public double calc_max_error(curve4 curve, double scale, out double max_angle_error) { curve.approximation_scale(m_approximation_scale.value() * scale); curve.init(m_curve1.x1(), m_curve1.y1(), m_curve1.x2(), m_curve1.y2(), m_curve1.x3(), m_curve1.y3(), m_curve1.x4(), m_curve1.y4()); pod_vector <vertex_dist> curve_points = new pod_vector <vertex_dist>(); uint cmd; double x, y; curve.rewind(0); while (!Path.is_stop(cmd = curve.vertex(out x, out y))) { if (Path.is_vertex(cmd)) { curve_points.add(new vertex_dist(x, y)); } } uint i; double curve_dist = 0; for (i = 1; i < curve_points.size(); i++) { curve_points.Array[i - 1].dist = curve_dist; curve_dist += agg_math.calc_distance(curve_points[i - 1].x, curve_points[i - 1].y, curve_points[i].x, curve_points[i].y); } curve_points.Array[curve_points.size() - 1].dist = curve_dist; pod_vector <curve_point> reference_points = new pod_vector <curve_point>(); for (i = 0; i < 4096; i++) { double mu = i / 4095.0; bezier4_point(m_curve1.x1(), m_curve1.y1(), m_curve1.x2(), m_curve1.y2(), m_curve1.x3(), m_curve1.y3(), m_curve1.x4(), m_curve1.y4(), mu, out x, out y); reference_points.add(new curve_point(x, y, mu)); } double reference_dist = 0; for (i = 1; i < reference_points.size(); i++) { reference_points.Array[i - 1].dist = reference_dist; reference_dist += agg_math.calc_distance(reference_points[i - 1].x, reference_points[i - 1].y, reference_points[i].x, reference_points[i].y); } reference_points.Array[reference_points.size() - 1].dist = reference_dist; uint idx1 = 0; uint idx2 = 1; double max_error = 0; for (i = 0; i < reference_points.size(); i++) { if (find_point(curve_points, reference_points[i].dist, out idx1, out idx2)) { double err = Math.Abs(agg_math.calc_line_point_distance(curve_points[idx1].x, curve_points[idx1].y, curve_points[idx2].x, curve_points[idx2].y, reference_points[i].x, reference_points[i].y)); if (err > max_error) { max_error = err; } } } double aerr = 0; for (i = 2; i < curve_points.size(); i++) { double a1 = Math.Atan2(curve_points[i - 1].y - curve_points[i - 2].y, curve_points[i - 1].x - curve_points[i - 2].x); double a2 = Math.Atan2(curve_points[i].y - curve_points[i - 1].y, curve_points[i].x - curve_points[i - 1].x); double da = Math.Abs(a1 - a2); if (da >= Math.PI) { da = 2 * Math.PI - da; } if (da > aerr) { aerr = da; } } max_angle_error = aerr * 180.0 / Math.PI; return(max_error * scale); }
public double calc_max_error(curve4 curve, double scale, out double max_angle_error) { curve.approximation_scale(m_approximation_scale.value() * scale); curve.init(m_curve1.x1(), m_curve1.y1(), m_curve1.x2(), m_curve1.y2(), m_curve1.x3(), m_curve1.y3(), m_curve1.x4(), m_curve1.y4()); pod_vector<vertex_dist> curve_points = new pod_vector<vertex_dist>(); uint cmd; double x, y; curve.rewind(0); while(!Path.is_stop(cmd = curve.vertex(out x, out y))) { if(Path.is_vertex(cmd)) { curve_points.add(new vertex_dist(x, y)); } } uint i; double curve_dist = 0; for(i = 1; i < curve_points.size(); i++) { curve_points.Array[i - 1].dist = curve_dist; curve_dist += agg_math.calc_distance(curve_points[i-1].x, curve_points[i-1].y, curve_points[i].x, curve_points[i].y); } curve_points.Array[curve_points.size() - 1].dist = curve_dist; pod_vector<curve_point> reference_points = new pod_vector<curve_point>(); for(i = 0; i < 4096; i++) { double mu = i / 4095.0; bezier4_point(m_curve1.x1(), m_curve1.y1(), m_curve1.x2(), m_curve1.y2(), m_curve1.x3(), m_curve1.y3(), m_curve1.x4(), m_curve1.y4(), mu, out x, out y); reference_points.add(new curve_point(x, y, mu)); } double reference_dist = 0; for(i = 1; i < reference_points.size(); i++) { reference_points.Array[i - 1].dist = reference_dist; reference_dist += agg_math.calc_distance(reference_points[i-1].x, reference_points[i-1].y, reference_points[i].x, reference_points[i].y); } reference_points.Array[reference_points.size() - 1].dist = reference_dist; uint idx1 = 0; uint idx2 = 1; double max_error = 0; for(i = 0; i < reference_points.size(); i++) { if(find_point(curve_points, reference_points[i].dist, out idx1, out idx2)) { double err = Math.Abs(agg_math.calc_line_point_distance(curve_points[idx1].x, curve_points[idx1].y, curve_points[idx2].x, curve_points[idx2].y, reference_points[i].x, reference_points[i].y)); if(err > max_error) max_error = err; } } double aerr = 0; for(i = 2; i < curve_points.size(); i++) { double a1 = Math.Atan2(curve_points[i-1].y - curve_points[i-2].y, curve_points[i-1].x - curve_points[i-2].x); double a2 = Math.Atan2(curve_points[i].y - curve_points[i - 1].y, curve_points[i].x - curve_points[i-1].x); double da = Math.Abs(a1 - a2); if (da >= Math.PI) da = 2 * Math.PI - da; if(da > aerr) aerr = da; } max_angle_error = aerr * 180.0 / Math.PI; return max_error * scale; }