private bool IsOver(double x, double y) { double xp = m_xs1 + (m_xs2 - m_xs1) * m_value; double yp = (m_ys1 + m_ys2) / 2.0; return(PictorMath.CalculateDistance(x, y, xp, yp) <= m_Bounds.Top - m_Bounds.Bottom); }
public bool IsEqual(VertexDistance val) { bool ret = (dist = PictorMath.CalculateDistance(x, y, val.x, val.y)) > PictorMath.vertex_dist_epsilon; if (!ret) { dist = 1.0 / PictorMath.vertex_dist_epsilon; } return(ret); }
public void join_path(PathStorage vs, uint path_id) { double x, y; vs.Rewind(path_id); uint PathAndFlags = vs.Vertex(out x, out y); if (!Path.IsStop(PathAndFlags)) { if (Path.IsVertex(PathAndFlags)) { double x0, y0; uint PathAndFlags0 = last_vertex(out x0, out y0); if (Path.IsVertex(PathAndFlags0)) { if (PictorMath.CalculateDistance(x, y, x0, y0) > PictorMath.vertex_dist_epsilon) { if (Path.IsMoveTo(PathAndFlags)) { PathAndFlags = (uint)Path.EPathCommands.LineTo; } m_vertices.add_vertex(x, y, PathAndFlags); } } else { if (Path.IsStop(PathAndFlags0)) { PathAndFlags = (uint)Path.EPathCommands.MoveTo; } else { if (Path.IsMoveTo(PathAndFlags)) { PathAndFlags = (uint)Path.EPathCommands.LineTo; } } m_vertices.add_vertex(x, y, PathAndFlags); } } while (!Path.IsStop(PathAndFlags = vs.Vertex(out x, out y))) { m_vertices.add_vertex(x, y, Path.IsMoveTo(PathAndFlags) ? (uint)Path.EPathCommands.LineTo : PathAndFlags); } } }
//-------------------------------------------------------------------- public void Prepare() { unsafe { coord_type[] coord = new coord_type[3]; base.arrange_vertices(coord); m_y2 = (int)(coord[1].y); m_swap = PictorMath.CrossProduct(coord[0].x, coord[0].y, coord[2].x, coord[2].y, coord[1].x, coord[1].y) < 0.0; m_rgba1.Init(coord[0], coord[2]); m_rgba2.Init(coord[0], coord[1]); m_rgba3.Init(coord[1], coord[2]); } }
//-------------------------------------------------------------------- // Sets the triangle and dilates it if needed. // The trick here is to Calculate beveled joins in the vertices of the // triangle and render it as a 6-Vertex polygon. // It's necessary to achieve numerical stability. // However, the Coordinates to interpolate Colors are calculated // as miter joins (CalculateIntersection). public void triangle(double x1, double y1, double x2, double y2, double x3, double y3, double d) { m_coord[0].x = m_x[0] = x1; m_coord[0].y = m_y[0] = y1; m_coord[1].x = m_x[1] = x2; m_coord[1].y = m_y[1] = y2; m_coord[2].x = m_x[2] = x3; m_coord[2].y = m_y[2] = y3; m_cmd[0] = (uint)Path.EPathCommands.MoveTo; m_cmd[1] = (uint)Path.EPathCommands.LineTo; m_cmd[2] = (uint)Path.EPathCommands.LineTo; m_cmd[3] = (uint)Path.EPathCommands.Stop; if (d != 0.0) { PictorMath.DilateTriangle(m_coord[0].x, m_coord[0].y, m_coord[1].x, m_coord[1].y, m_coord[2].x, m_coord[2].y, m_x, m_y, d); PictorMath.CalculateIntersection(m_x[4], m_y[4], m_x[5], m_y[5], m_x[0], m_y[0], m_x[1], m_y[1], out m_coord[0].x, out m_coord[0].y); PictorMath.CalculateIntersection(m_x[0], m_y[0], m_x[1], m_y[1], m_x[2], m_y[2], m_x[3], m_y[3], out m_coord[1].x, out m_coord[1].y); PictorMath.CalculateIntersection(m_x[2], m_y[2], m_x[3], m_y[3], m_x[4], m_y[4], m_x[5], m_y[5], out m_coord[2].x, out m_coord[2].y); m_cmd[3] = (uint)Path.EPathCommands.LineTo; m_cmd[4] = (uint)Path.EPathCommands.LineTo; m_cmd[5] = (uint)Path.EPathCommands.LineTo; m_cmd[6] = (uint)Path.EPathCommands.Stop; } }
public int Calculate(int x, int y, int d) { //return (int)System.Math.Sqrt((uint)(System.Math.Abs(x) * System.Math.Abs(y))); return((int)PictorMath.FastSqrt((uint)(System.Math.Abs(x) * System.Math.Abs(y)))); }
public int Calculate(int x, int y, int d) { //return (int)(System.Math.Sqrt((uint)(x * x + y * y))); return((int)(PictorMath.FastSqrt((uint)(x * x + y * y)))); }
// Actually the same as radial. Just for compatibility public int Calculate(int x, int y, int d) { return((int)(PictorMath.FastSqrt((uint)(x * x + y * y)))); }
private void recursive_bezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, uint level) { if (level > (uint)Curves.curve_recursion_limit_e.curve_recursion_limit) { return; } // Calculate all the mid-points of the Line segments //---------------------- double x12 = (x1 + x2) / 2; double y12 = (y1 + y2) / 2; double x23 = (x2 + x3) / 2; double y23 = (y2 + y3) / 2; double x34 = (x3 + x4) / 2; double y34 = (y3 + y4) / 2; double x123 = (x12 + x23) / 2; double y123 = (y12 + y23) / 2; double x234 = (x23 + x34) / 2; double y234 = (y23 + y34) / 2; double x1234 = (x123 + x234) / 2; double y1234 = (y123 + y234) / 2; // Try to approximate the full cubic curve by a single straight Line //------------------ double dx = x4 - x1; double dy = y4 - y1; double d2 = Math.Abs(((x2 - x4) * dy - (y2 - y4) * dx)); double d3 = Math.Abs(((x3 - x4) * dy - (y3 - y4) * dx)); double da1, da2, k; int SwitchCase = 0; if (d2 > Curves.curve_collinearity_epsilon) { SwitchCase = 2; } if (d3 > Curves.curve_collinearity_epsilon) { SwitchCase++; } switch (SwitchCase) { case 0: // All collinear OR p1==p4 //---------------------- k = dx * dx + dy * dy; if (k == 0) { d2 = PictorMath.CalculateSquaredDistance(x1, y1, x2, y2); d3 = PictorMath.CalculateSquaredDistance(x4, y4, x3, y3); } else { k = 1 / k; da1 = x2 - x1; da2 = y2 - y1; d2 = k * (da1 * dx + da2 * dy); da1 = x3 - x1; da2 = y3 - y1; d3 = k * (da1 * dx + da2 * dy); if (d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1) { // Simple collinear case, 1---2---3---4 // We can leave just two endpoints return; } if (d2 <= 0) { d2 = PictorMath.CalculateSquaredDistance(x2, y2, x1, y1); } else if (d2 >= 1) { d2 = PictorMath.CalculateSquaredDistance(x2, y2, x4, y4); } else { d2 = PictorMath.CalculateSquaredDistance(x2, y2, x1 + d2 * dx, y1 + d2 * dy); } if (d3 <= 0) { d3 = PictorMath.CalculateSquaredDistance(x3, y3, x1, y1); } else if (d3 >= 1) { d3 = PictorMath.CalculateSquaredDistance(x3, y3, x4, y4); } else { d3 = PictorMath.CalculateSquaredDistance(x3, y3, x1 + d3 * dx, y1 + d3 * dy); } } if (d2 > d3) { if (d2 < m_distance_tolerance_square) { m_points.Add(new PointD(x2, y2)); return; } } else { if (d3 < m_distance_tolerance_square) { m_points.Add(new PointD(x3, y3)); return; } } break; case 1: // p1,p2,p4 are collinear, p3 is significant //---------------------- if (d3 * d3 <= m_distance_tolerance_square * (dx * dx + dy * dy)) { if (m_angle_tolerance < Curves.curve_angle_tolerance_epsilon) { m_points.Add(new PointD(x23, y23)); return; } // Angle Condition //---------------------- da1 = Math.Abs(Math.Atan2(y4 - y3, x4 - x3) - Math.Atan2(y3 - y2, x3 - x2)); if (da1 >= Math.PI) { da1 = 2 * Math.PI - da1; } if (da1 < m_angle_tolerance) { m_points.Add(new PointD(x2, y2)); m_points.Add(new PointD(x3, y3)); return; } if (m_cusp_limit != 0.0) { if (da1 > m_cusp_limit) { m_points.Add(new PointD(x3, y3)); return; } } } break; case 2: // p1,p3,p4 are collinear, p2 is significant //---------------------- if (d2 * d2 <= m_distance_tolerance_square * (dx * dx + dy * dy)) { if (m_angle_tolerance < Curves.curve_angle_tolerance_epsilon) { m_points.Add(new PointD(x23, y23)); return; } // Angle Condition //---------------------- da1 = Math.Abs(Math.Atan2(y3 - y2, x3 - x2) - Math.Atan2(y2 - y1, x2 - x1)); if (da1 >= Math.PI) { da1 = 2 * Math.PI - da1; } if (da1 < m_angle_tolerance) { m_points.Add(new PointD(x2, y2)); m_points.Add(new PointD(x3, y3)); return; } if (m_cusp_limit != 0.0) { if (da1 > m_cusp_limit) { m_points.Add(new PointD(x2, y2)); return; } } } break; case 3: // Regular case //----------------- if ((d2 + d3) * (d2 + d3) <= m_distance_tolerance_square * (dx * dx + dy * dy)) { // If the curvature doesn't exceed the distance_tolerance Value // we tend to finish subdivisions. //---------------------- if (m_angle_tolerance < Curves.curve_angle_tolerance_epsilon) { m_points.Add(new PointD(x23, y23)); return; } // Angle & Cusp Condition //---------------------- k = Math.Atan2(y3 - y2, x3 - x2); da1 = Math.Abs(k - Math.Atan2(y2 - y1, x2 - x1)); da2 = Math.Abs(Math.Atan2(y4 - y3, x4 - x3) - k); if (da1 >= Math.PI) { da1 = 2 * Math.PI - da1; } if (da2 >= Math.PI) { da2 = 2 * Math.PI - da2; } if (da1 + da2 < m_angle_tolerance) { // Finally we can stop the recursion //---------------------- m_points.Add(new PointD(x23, y23)); return; } if (m_cusp_limit != 0.0) { if (da1 > m_cusp_limit) { m_points.Add(new PointD(x2, y2)); return; } if (da2 > m_cusp_limit) { m_points.Add(new PointD(x3, y3)); return; } } } break; } // Continue subdivision //---------------------- recursive_bezier(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1); recursive_bezier(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1); }
private void recursive_bezier(double x1, double y1, double x2, double y2, double x3, double y3, uint level) { if (level > (uint)Curves.curve_recursion_limit_e.curve_recursion_limit) { return; } // Calculate all the mid-points of the Line segments //---------------------- double x12 = (x1 + x2) / 2; double y12 = (y1 + y2) / 2; double x23 = (x2 + x3) / 2; double y23 = (y2 + y3) / 2; double x123 = (x12 + x23) / 2; double y123 = (y12 + y23) / 2; double dx = x3 - x1; double dy = y3 - y1; double d = Math.Abs(((x2 - x3) * dy - (y2 - y3) * dx)); double da; if (d > Curves.curve_collinearity_epsilon) { // Regular case //----------------- if (d * d <= m_distance_tolerance_square * (dx * dx + dy * dy)) { // If the curvature doesn't exceed the distance_tolerance Value // we tend to finish subdivisions. //---------------------- if (m_angle_tolerance < Curves.curve_angle_tolerance_epsilon) { m_points.Add(new PointD(x123, y123)); return; } // Angle & Cusp Condition //---------------------- da = Math.Abs(Math.Atan2(y3 - y2, x3 - x2) - Math.Atan2(y2 - y1, x2 - x1)); if (da >= Math.PI) { da = 2 * Math.PI - da; } if (da < m_angle_tolerance) { // Finally we can stop the recursion //---------------------- m_points.Add(new PointD(x123, y123)); return; } } } else { // Collinear case //------------------ da = dx * dx + dy * dy; if (da == 0) { d = PictorMath.CalculateSquaredDistance(x1, y1, x2, y2); } else { d = ((x2 - x1) * dx + (y2 - y1) * dy) / da; if (d > 0 && d < 1) { // Simple collinear case, 1---2---3 // We can leave just two endpoints return; } if (d <= 0) { d = PictorMath.CalculateSquaredDistance(x2, y2, x1, y1); } else if (d >= 1) { d = PictorMath.CalculateSquaredDistance(x2, y2, x3, y3); } else { d = PictorMath.CalculateSquaredDistance(x2, y2, x1 + d * dx, y1 + d * dy); } } if (d < m_distance_tolerance_square) { m_points.Add(new PointD(x2, y2)); return; } } // Continue subdivision //---------------------- recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1); recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1); }