예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
파일: PathStorage.cs 프로젝트: djlw78/Mosa
        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);
                }
            }
        }
예제 #4
0
        //--------------------------------------------------------------------
        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]);
            }
        }
예제 #5
0
파일: GouraudSpan.cs 프로젝트: djlw78/Mosa
        //--------------------------------------------------------------------
        // 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;
            }
        }
예제 #6
0
파일: SpanGradient.cs 프로젝트: djlw78/Mosa
 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))));
 }
예제 #7
0
파일: SpanGradient.cs 프로젝트: djlw78/Mosa
 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))));
 }
예제 #8
0
파일: SpanGradient.cs 프로젝트: djlw78/Mosa
 // 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))));
 }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }