FlightGear next
VectorMath.cxx
Go to the documentation of this file.
1// VectorMath - class for vector calculations
2// Written by Keith Paterson
3//
4// This program is free software; you can redistribute it and/or
5// modify it under the terms of the GNU General Public License as
6// published by the Free Software Foundation; either version 2 of the
7// License, or (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17
18#include <simgear/debug/logstream.hxx>
19#include <simgear/math/SGGeod.hxx>
20
21#include "VectorMath.hxx"
22
23std::array<double, 2> VectorMath::innerTangentsAngle( SGGeod m1, SGGeod m2, double r1, double r2) {
24 std::array<double, 2> ret;
25 double hypothenuse = SGGeodesy::distanceM(m1, m2);
26 if (hypothenuse <= r1 + r2) {
27 SG_LOG(SG_AI, SG_WARN, "innerTangentsAngle turn circles too near");
28 }
29 double opposite = r1 + r2;
30 double angle = asin(opposite/hypothenuse) * SG_RADIANS_TO_DEGREES;
31 double crs;
32 if (r1>r2) {
33 crs = SGGeodesy::courseDeg(m2, m1);
34 } else {
35 crs = SGGeodesy::courseDeg(m1, m2);
36 }
37 ret[0] = SGMiscd::normalizePeriodic(0, 360, crs - angle);
38 ret[1] = SGMiscd::normalizePeriodic(0, 360, crs + angle);
39 return ret;
40}
41
42double VectorMath::innerTangentsLength( SGGeod m1, SGGeod m2, double r1, double r2) {
43 double hypothenuse = SGGeodesy::distanceM(m1, m2);
44 if (hypothenuse <= r1 + r2) {
45 SG_LOG(SG_AI, SG_WARN, "innerTangentsLength turn circles too near");
46 }
47
48 double opposite = r1 + r2;
49 double angle = asin(opposite/hypothenuse) * SG_RADIANS_TO_DEGREES;
50 double crs;
51 if (r1>r2) {
52 crs = SGGeodesy::courseDeg(m2, m1);
53 } else {
54 crs = SGGeodesy::courseDeg(m1, m2);
55 }
56 double angle1 = SGMiscd::normalizePeriodic(0, 360, crs - angle + 90);
57 double angle2 = SGMiscd::normalizePeriodic(0, 360, crs - angle - 90);
58 SGGeod p1 = SGGeodesy::direct(m1, angle1, r1);
59 SGGeod p2 = SGGeodesy::direct(m2, angle2, r2);
60
61 return SGGeodesy::distanceM(p1, p2);
62}
63
64std::array<double, 2> VectorMath::outerTangentsAngle( SGGeod m1, SGGeod m2, double r1, double r2) {
65 std::array<double, 2> ret;
66 double hypothenuse = SGGeodesy::distanceM(m1, m2);
67 double radiusDiff = abs(r1 - r2);
68 double beta = atan2( radiusDiff, hypothenuse ) * SG_RADIANS_TO_DEGREES;
69 double gamma = SGGeodesy::courseDeg(m1, m2);
70 ret[0] = SGMiscd::normalizePeriodic(0, 360, gamma - beta);
71 ret[1] = SGMiscd::normalizePeriodic(0, 360, gamma + beta);
72 return ret;
73}
74
75double VectorMath::outerTangentsLength( SGGeod m1, SGGeod m2, double r1, double r2) {
76 double hypothenuse = SGGeodesy::distanceM(m1, m2);
77 double radiusDiff = abs(r1 - r2);
78 double dist = sqrt(pow(hypothenuse,2)-pow(radiusDiff,2));
79 return dist;
80}
#define p2(x, y)
static double outerTangentsLength(SGGeod m1, SGGeod m2, double r1, double r2)
Length of outer tangent between two circles.
static std::array< double, 2 > innerTangentsAngle(SGGeod m1, SGGeod m2, double r1, double r2)
Angles of inner tangent between two circles.
static double innerTangentsLength(SGGeod m1, SGGeod m2, double r1, double r2)
Length of inner tangent between two circles.
static std::array< double, 2 > outerTangentsAngle(SGGeod m1, SGGeod m2, double r1, double r2)
Angles of outer tangent between two circles normalized to 0-360.