private static float max_error_location(Arc arc, float begin_point_angle, float end_point_angle) { OctahedronUVCoordinates begin_point = new NormalizedCartesianCoordinates(arc.position(begin_point_angle)); OctahedronUVCoordinates end_point = new NormalizedCartesianCoordinates(arc.position(end_point_angle)); float begin = begin_point_angle; float end = end_point_angle; // 2) use binary / bisection search to find the point of maximal error while (end - begin > Precision.delta) { float midpoint = (begin + end) / 2; OctahedronUVCoordinates left_midpoint = new NormalizedCartesianCoordinates(arc.position(midpoint - Precision.delta)); OctahedronUVCoordinates right_midpoint = new NormalizedCartesianCoordinates(arc.position(midpoint + Precision.delta)); float error_left = PlanetariaMath.point_line_distance(begin_point.data, end_point.data, left_midpoint.data); float error_right = PlanetariaMath.point_line_distance(begin_point.data, end_point.data, right_midpoint.data); if (error_left < error_right) //error begin should be replaced since it has less error { begin = midpoint; } else //error end should be replaced since it has less error { end = midpoint; } } return((begin + end) / 2); // return location of max error }
private static void subdivide(Arc arc, float begin_point_angle, float end_point_angle) { float middle_point_angle = max_error_location(arc, begin_point_angle, end_point_angle); Vector3 begin = arc.position(begin_point_angle); Vector3 middle = arc.position(middle_point_angle); Vector3 end = arc.position(end_point_angle); OctahedronUVCoordinates begin_point = new NormalizedCartesianCoordinates(begin); OctahedronUVCoordinates middle_point = new NormalizedCartesianCoordinates(middle); OctahedronUVCoordinates end_point = new NormalizedCartesianCoordinates(end); if (PlanetariaMath.point_line_distance(begin_point.data, end_point.data, middle_point.data) > Precision.threshold) // if the max error is greater than a threshold, recursively add the left and right halves into the list of lines { subdivide(arc, begin_point_angle, middle_point_angle); subdivide(arc, middle_point_angle, end_point_angle); } else { QuadraticBezierCurve curve = new QuadraticBezierCurve(begin_point.data, middle_point.data, end_point.data); VectorGraphicsWriter.set_edge(curve); } }