API Documentation
Loading...
Searching...
No Matches
BulgeConverter.h
Go to the documentation of this file.
1#pragma once
4namespace NDEVR
5{
6 /* Line Intersection
7 * intersectX and intersectY are set to the CenterPoint */
8 Vertex<3, fltp08> getLineIntersection(double lineAx1, double lineAy1,
9 double lineAx2, double lineAy2,
10 double lineBx1, double lineBy1,
11 double lineBx2, double lineBy2)
12 {
13 double A1 = lineAy2 - lineAy1;
14 double B1 = lineAx1 - lineAx2;
15 double C1 = A1 * lineAx1 + B1 * lineAy1;
16
17 double A2 = lineBy2 - lineBy1;
18 double B2 = lineBx1 - lineBx2;
19 double C2 = A2 * lineBx1 + B2 * lineBy1;
20
21 double det = A1 * B2 - A2 * B1;
22 Vertex<3, fltp08> center;
23 if (det == 0)
24 {
25 printf("Intersecting lines cannot be parallel.\n");
26 }
27 else
28 {
29 center[X] = (B2 * C1 - B1 * C2) / det;
30 center[Y] = (A1 * C2 - A2 * C1) / det;
31 }
32 return center;
33 }
34 /* Calculus based approach at determining whether a polygon is clockwise or counterclockwise.
35 * Returns true if arc is clockwise. */
36 bool isArcClockwise(double startx, double starty, double midx, double midy, double endx, double endy)
37 {
38 double edge1 = (midx - startx) * (midy + starty);
39 double edge2 = (endx - midx) * (endy + midy);
40 double edge3 = (startx - endx) * (starty + endy);
41 return (edge1 + edge2 + edge3 >= 0.0);
42 }
43
44 /* Calculates the CenterPoint of the Arc */
45 Vertex<3, fltp08> getArcCenter(double arcStartX, double arcStartY,
46 double arcMidX, double arcMidY,
47 double arcEndX, double arcEndY)
48 {
49 double ax = arcMidX - arcStartX;
50 double ay = arcMidY - arcStartY;
51 Angle<fltp08> aAngleInRadians = Angle<fltp08>::atan2(ay, ax);
52 double aMidX = (arcMidX + arcStartX) / 2.0;
53 double aMidY = (arcMidY + arcStartY) / 2.0;
54
55 Angle<fltp08> paAngleInRadians = aAngleInRadians + Angle<fltp08>(DEGREES, 90.0);
56 double pax = cos(paAngleInRadians);
57 double pay = sin(paAngleInRadians);
58 double aPerpX = aMidX + pax;
59 double aPerpY = aMidY + pay;
60
61 double bx = arcEndX - arcMidX;
62 double by = arcEndY - arcMidY;
63 Angle<fltp08> bAngleInRadians = Angle<fltp08>::atan2(by, bx);
64 double bMidX = (arcEndX + arcMidX) / 2.0;
65 double bMidY = (arcEndY + arcMidY) / 2.0;
66
67 Angle<fltp08> pbAngleInRadians = bAngleInRadians + Angle<fltp08>(DEGREES, 90.0);
68 double pbx = cos(pbAngleInRadians);
69 double pby = sin(pbAngleInRadians);
70 double bPerpX = bMidX + pbx;
71 double bPerpY = bMidY + pby;
72
73 return getLineIntersection(aMidX, aMidY, aPerpX, aPerpY, bMidX, bMidY, bPerpX, bPerpY);
74 }
75
76 /* Calculates Arc Geometry from Bulge Data.
77 * Returns false if there was an error calculating the data. */
79 /* returned data */
80 Vertex<3, fltp08>& arc_mid,
81 Vertex<3, fltp08>& arc_center,
82 fltp08& radius,
83 double* chord,
84 double* chordMidX, double* chordMidY,
85 double* sagitta, double* apothem,
86 Angle<fltp08>& span)
87 {
88 Angle<fltp08> chordAngleInRadians;
89 Angle<fltp08> sagittaAngleInRadians;
90
91 double w, h, fx, fy, dx, dy;
92 bool clockwise = bulge < 0.0;
93
94 /* Calculate the Included Angle in Radians */
95 span = Angle<fltp08>::atan(bulge) * 4.0;
96
97 /* Calculate the Chord */
98 w = fabs(p1[X] - p2[X]);
99 h = fabs(p1[Y] - p2[Y]);
100 *chord = sqrt(w * w + h * h);
101
102 /* Calculate the Radius */
103 radius = fabs(*chord / (2.0 * sin(span / 2.0)));
104
105
106 /* Calculate the Sagitta */
107 *sagitta = fabs((*chord / 2.0) * bulge);
108
109 /* Calculate the Apothem */
110 *apothem = fabs(radius - *sagitta);
111
112 /* Calculate the Chord MidPoint */
113 *chordMidX = (p1[X] + p2[X]) / 2.0;
114 *chordMidY = (p1[Y] + p2[Y]) / 2.0;
115
116 /* Calculate the Chord Angle (from arcStart to arcEnd) */
117 dx = p1[X] - p1[X];
118 dy = p2[Y] - p1[Y];
119 chordAngleInRadians = Angle<fltp08>::atan2(dy, dx);
120
121 /* Calculate the Sagitta Angle (from chordMid to arcMid) */
122 if (clockwise) sagittaAngleInRadians = chordAngleInRadians + Angle<fltp08>(DEGREES, 90.0);
123 else sagittaAngleInRadians = chordAngleInRadians - Angle<fltp08>(DEGREES, 90.0);
124
125 /* Calculate the Arc MidPoint */
126 fx = *sagitta * cos(sagittaAngleInRadians);
127 fy = *sagitta * sin(sagittaAngleInRadians);
128 arc_mid[X] = *chordMidX + fx;
129 arc_mid[Y] = *chordMidY + fy;
130
131 /* Calculate the Arc CenterPoint */
132 arc_center = getArcCenter(p1[X], p1[Y], arc_mid[X], arc_mid[Y], p2[X], p2[Y]);
133
134
135 /* Confirm the direction of the Arc, it should match the Bulge */
136 if (clockwise != isArcClockwise(p1[X], p1[Y], arc_mid[X], arc_mid[Y], p2[X], p2[Y]))
137 {
138 lib_assert(false, "Arc and Bulge direction do not match.");
139
140 }
141 if (!clockwise)
142 span = -span;
143 }
144}
#define lib_assert(expression, message)
Asserts some logic in the code. Disabled in non debug mode by default. Can be re-enabled in release u...
Definition LibAssert.h:70
Stores an angle in an optimized format.
Definition StringStream.h:408
static Angle atan(fltp04 value)
Definition Angle.h:465
static Angle atan2(fltp04 value_a, fltp04 value_b)
Definition Angle.h:477
A vertex or point. A specific type of Vector used primarily for spacial location information.
Definition Vertex.hpp:48
Definition ACIColor.h:37
void ArcDataFromBulge(fltp08 bulge, const Vertex< 3, fltp08 > &p1, const Vertex< 3, fltp08 > &p2, Vertex< 3, fltp08 > &arc_mid, Vertex< 3, fltp08 > &arc_center, fltp08 &radius, double *chord, double *chordMidX, double *chordMidY, double *sagitta, double *apothem, Angle< fltp08 > &span)
Definition BulgeConverter.h:78
@ DEGREES
Definition Angle.h:62
std::enable_if<!ObjectInfo< t_type >::Float, fltp08 >::type cos(const Angle< t_type > &angle)
Definition AngleFunctions.h:149
bool isArcClockwise(double startx, double starty, double midx, double midy, double endx, double endy)
Definition BulgeConverter.h:36
Vertex< 3, fltp08 > getLineIntersection(double lineAx1, double lineAy1, double lineAx2, double lineAy2, double lineBx1, double lineBy1, double lineBx2, double lineBy2)
Definition BulgeConverter.h:8
Vertex< 3, fltp08 > getArcCenter(double arcStartX, double arcStartY, double arcMidX, double arcMidY, double arcEndX, double arcEndY)
Definition BulgeConverter.h:45
t_type sqrt(const t_type &value)
Definition VectorFunctions.hpp:1305
std::enable_if<!ObjectInfo< t_type >::Float, fltp08 >::type sin(const Angle< t_type > &angle)
Definition AngleFunctions.h:108
@ Y
Definition BaseValues.hpp:197
@ X
Definition BaseValues.hpp:195
double fltp08
Defines an alias representing an 8 byte floating-point number.
Definition BaseValues.hpp:176