@@ -32,6 +32,10 @@ namespace WorldBuilder
3232{
3333 namespace Objects
3434 {
35+ /*
36+ Takes a vector of points and interpolates a spline using a cubic Bezier curve, for more information see this wikipedia
37+ page https://en.wikipedia.org/wiki/B%C3%A9zier_curve
38+ */
3539 BezierCurve::BezierCurve (const std::vector<Point<2 > > &p, const std::vector<double > &angle_constraints_input)
3640 {
3741 points = p;
@@ -55,17 +59,22 @@ namespace WorldBuilder
5559 angles[0 ] = angle_constraints[0 ];
5660 }
5761
62+ // If there are more than 2 points provided, calculate the average angle between a given point and the previous point,
63+ // and the following point. If only 2 points are provided, this for loop is skipped.
5864 for (size_t p_i = 1 ; p_i < n_points-1 ; ++p_i)
5965 {
6066 // first determine the angle
6167 if (std::isnan (angle_constraints[p_i]))
6268 {
63- // get the average angle
69+ // Calculate the line between the current point and the previous point
6470 const Point<2 > P1P2 = points[p_i-1 ]-points[p_i];
71+ // Calculate the line between the current point and the following point
6572 const Point<2 > P3P2 = points[p_i+1 ]-points[p_i];
6673
74+ // Calculate the angles of the two lines determined above
6775 const double angle_p1p2 = atan2 (P1P2[1 ],P1P2[0 ]);
6876 const double angle_p3p1 = atan2 (P3P2[1 ],P3P2[0 ]);
77+ // Calculate the average angle
6978 const double average_angle = (angle_p1p2 + angle_p3p1)*0.5 ;
7079 angles[p_i] = average_angle;
7180 angles[p_i] -= Consts::PI*0.5 ;
@@ -87,12 +96,15 @@ namespace WorldBuilder
8796 angles[n_points-1 ] = angle_constraints[n_points-1 ];
8897 }
8998
99+ // If there are more than 2 points provided, loop through the points and determine the control points
90100 if (points.size () > 2 )
91101 {
92102 // next determine the location of the control points
93- // the location of the control point is 1 /10th p1p2 distance in the direction of the angle.
103+ // the location of the control point is 2 /10th p1p2 distance in the direction of the angle.
94104 // make sure the angle is pointing away from the next point, e.g.
95105 // the check point is on the other side of the of the line p1p2 compared to p3.
106+ // This first block determines the control points for the special case of the first
107+ // 3 points.
96108 const double fraction_of_length = 0.2 ;
97109 {
98110 const Point<2 > &p1 = points[0 ];
@@ -104,6 +116,7 @@ namespace WorldBuilder
104116 control_points[0 ][1 ][0 ] = cos (angles[1 ])*length*fraction_of_length+p2[0 ];
105117 control_points[0 ][1 ][1 ] = sin (angles[1 ])*length*fraction_of_length+p2[1 ];
106118 {
119+ // Determine which side of the line the control points lie on
107120 const bool side_of_line_1 = (p1[0 ] - p2[0 ]) * (control_points[0 ][1 ][1 ] - p1[1 ])
108121 - (p1[1 ] - p2[1 ]) * (control_points[0 ][1 ][0 ] - p1[0 ])
109122 < 0 ;
@@ -119,7 +132,7 @@ namespace WorldBuilder
119132 }
120133 }
121134
122- for (size_t p_i = 1 ; p_i < n_points-1 ; ++p_i)
135+ for (size_t p_i = 0 ; p_i < n_points-1 ; ++p_i)
123136 {
124137 const Point<2 > &p1 = points[p_i];
125138 const Point<2 > &p2 = points[p_i+1 ];
@@ -128,6 +141,7 @@ namespace WorldBuilder
128141 control_points[p_i][0 ][1 ] = sin (angles[p_i])*length*fraction_of_length+p1[1 ];
129142
130143 {
144+ // Determine which side of the line the control points lie on
131145 const bool side_of_line_1 = (p1[0 ] - p2[0 ]) * (control_points[p_i-1 ][1 ][1 ] - p1[1 ])
132146 - (p1[1 ] - p2[1 ]) * (control_points[p_i-1 ][1 ][0 ] - p1[0 ])
133147 < 0 ;
0 commit comments