Ejemplo n.º 1
0
        private void TestToStringWithCulture(CultureInfo culture)
        {
            CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture = culture;
            try
            {
                string listSeparator = culture.TextInfo.ListSeparator;
                string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator;
                var o = new Seg2F(new Vec2F(1.1f, 2.2f), new Vec2F(3.3f, 4.4f));

                string s = o.ToString(null, null);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                string s2 = o.ToString();
                Assert.AreEqual(s, s2);

                s = o.ToString("G", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                s = o.ToString("R", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);
            }
            finally
            {
                Thread.CurrentThread.CurrentCulture = originalCulture;
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Projects a point onto a segment</summary>
 /// <param name="seg">Segment</param>
 /// <param name="p">Point to project</param>
 /// <returns>Point on the segment nearest to the point</returns>
 public static Vec2F Project(Seg2F seg, Vec2F p)
 {
     Vec2F result = new Vec2F();
     Vec2F dir = seg.P2 - seg.P1;
     Vec2F vec = p - seg.P1;
     float lengthSquared = Vec2F.Dot(dir, dir);
     if (lengthSquared < DegenerateLength * DegenerateLength)    // degenerate segment?
     {
         result = seg.P1;
     }
     else
     {
         float projection = Vec2F.Dot(dir, vec);
         if (projection < 0)
         {
             result = seg.P1;
         }
         else if (projection > lengthSquared)
         {
             result = seg.P2;
         }
         else
         {
             double scale = projection / lengthSquared;
             result.X = (float)(seg.P1.X + scale * dir.X);
             result.Y = (float)(seg.P1.Y + scale * dir.Y);
         }
     }
     return result;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the distance from a point p to its projection on a segment</summary>
        /// <param name="seg">Segment</param>
        /// <param name="p">Point to project</param>
        /// <returns>Distance from point p to its projection on segment</returns>
        public static float DistanceToSegment(Seg2F seg, Vec2F p)
        {
            Vec2F projection = Project(seg, p);
            float d          = Vec2F.Distance(p, projection);

            return(d);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Projects a point onto a segment</summary>
        /// <param name="seg">Segment</param>
        /// <param name="p">Point to project</param>
        /// <returns>Point on the segment nearest to the point</returns>
        public static Vec2F Project(Seg2F seg, Vec2F p)
        {
            Vec2F result        = new Vec2F();
            Vec2F dir           = seg.P2 - seg.P1;
            Vec2F vec           = p - seg.P1;
            float lengthSquared = Vec2F.Dot(dir, dir);

            if (lengthSquared < DegenerateLength * DegenerateLength)    // degenerate segment?
            {
                result = seg.P1;
            }
            else
            {
                float projection = Vec2F.Dot(dir, vec);
                if (projection < 0)
                {
                    result = seg.P1;
                }
                else if (projection > lengthSquared)
                {
                    result = seg.P2;
                }
                else
                {
                    double scale = projection / lengthSquared;
                    result.X = (float)(seg.P1.X + scale * dir.X);
                    result.Y = (float)(seg.P1.Y + scale * dir.Y);
                }
            }
            return(result);
        }
Ejemplo n.º 5
0
 private void TestToStringResults(Seg2F o, string s, string listSeparator, string decimalSeparator)
 {
     string[] results = s.Split(new[] { listSeparator }, StringSplitOptions.RemoveEmptyEntries);
     Assert.AreEqual(results.Length, 4);
     foreach (string oneFloatString in results)
         Assert.True(oneFloatString.Contains(decimalSeparator));
     Assert.AreEqual(float.Parse(results[0]), o.P1.X);
     Assert.AreEqual(float.Parse(results[1]), o.P1.Y);
     Assert.AreEqual(float.Parse(results[2]), o.P2.X);
     Assert.AreEqual(float.Parse(results[3]), o.P2.Y);
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Picks the specified curve</summary>
        /// <param name="curve">Curve</param>
        /// <param name="p">Picking point</param>
        /// <param name="tolerance">Pick tolerance</param>
        /// <param name="hitPoint">Hit point</param>
        /// <returns>True if curve found; false otherwise</returns>
        public static bool Pick(BezierCurve2F curve, Vec2F p, float tolerance, ref Vec2F hitPoint)
        {
            Queue <BezierCurve2F> curves = new Queue <BezierCurve2F>();

            curves.Enqueue(curve);

            float dMin         = float.MaxValue;
            Vec2F closestPoint = new Vec2F();

            while (curves.Count > 0)
            {
                BezierCurve2F current = curves.Dequeue();

                // project p onto segment connecting curve endpoints
                Seg2F seg        = new Seg2F(current.P1, current.P4);
                Vec2F projection = Seg2F.Project(seg, p);
                float d          = Vec2F.Distance(p, projection);

                // reject - point not near enough to segment, expanded by curve "thickness"
                float flatness = current.Flatness;
                if (d - flatness > tolerance)
                {
                    continue;
                }

                // accept - point within tolerance of curve
                if (flatness <= tolerance)
                {
                    if (d < dMin)
                    {
                        dMin         = d;
                        closestPoint = projection;
                    }
                }
                else
                {
                    BezierCurve2F left, right;
                    current.Subdivide(0.5f, out left, out right);
                    curves.Enqueue(left);
                    curves.Enqueue(right);
                }
            }

            if (dMin < tolerance)
            {
                hitPoint = closestPoint;
                return(true);
            }

            return(false);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Picks the specified curve</summary>
        /// <param name="curve">Curve</param>
        /// <param name="p">Picking point</param>
        /// <param name="tolerance">Pick tolerance</param>
        /// <param name="hitPoint">Hit point</param>
        /// <returns>True if curve found; false otherwise</returns>
        public static bool Pick(BezierCurve2F curve, Vec2F p, float tolerance, ref Vec2F hitPoint)
        {
            Queue<BezierCurve2F> curves = new Queue<BezierCurve2F>();
            curves.Enqueue(curve);

            float dMin = float.MaxValue;
            Vec2F closestPoint = new Vec2F();
            while (curves.Count > 0)
            {
                BezierCurve2F current = curves.Dequeue();

                // project p onto segment connecting curve endpoints
                Seg2F seg = new Seg2F(current.P1, current.P4);
                Vec2F projection = Seg2F.Project(seg, p);
                float d = Vec2F.Distance(p, projection);

                // reject - point not near enough to segment, expanded by curve "thickness"
                float flatness = current.Flatness;
                if (d - flatness > tolerance)
                    continue;

                // accept - point within tolerance of curve
                if (flatness <= tolerance)
                {
                    if (d < dMin)
                    {
                        dMin = d;
                        closestPoint = projection;
                    }
                }
                else
                {
                    BezierCurve2F left, right;
                    current.Subdivide(0.5f, out left, out right);
                    curves.Enqueue(left);
                    curves.Enqueue(right);
                }
            }

            if (dMin < tolerance)
            {
                hitPoint = closestPoint;
                return true;
            }

            return false;
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Gets the distance from a point p to its projection on a segment</summary>
 /// <param name="seg">Segment</param>
 /// <param name="p">Point to project</param>
 /// <returns>Distance from point p to its projection on segment</returns>
 public static float DistanceToSegment(Seg2F seg, Vec2F p)
 {
     Vec2F projection = Project(seg, p);
     float d = Vec2F.Distance(p, projection);
     return d;
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Picks one or more control points within given rectangle</summary>
        /// <param name="curves">Curves on which to pick points</param>
        /// <param name="pickRect">Rectangle bounding picked control points</param>
        /// <param name="points">Points picked</param>
        /// <param name="regions">PointSelectionRegions of picked points</param>
        public void PickPoints(ReadOnlyCollection<ICurve> curves, RectangleF pickRect,
            List<IControlPoint> points, List<PointSelectionRegions> regions)
        {
            points.Clear();
            regions.Clear();
            if (curves == null)
                return;

            foreach (ICurve curve in curves)
            {
                if (!curve.Visible)
                    continue;

                ReadOnlyCollection<IControlPoint> curvePoints = curve.ControlPoints;
                for (int i = 0; i < curvePoints.Count; i++)
                {
                    IControlPoint cpt = curvePoints[i];
                    Vec2F clientcpt = m_canvas.GraphToClient(cpt.X, cpt.Y);
                    if (pickRect.Contains(clientcpt))
                    {
                        points.Add(cpt);
                        regions.Add(PointSelectionRegions.Point);
                    }
                    else if (curve.CurveInterpolation != InterpolationTypes.Linear && cpt.EditorData.SelectedRegion != PointSelectionRegions.None)
                    {
                        bool pickTanOut = cpt.TangentOutType != CurveTangentTypes.Stepped && cpt.TangentOutType != CurveTangentTypes.SteppedNext;
                        if (pickTanOut)
                        {
                            Vec2F tangOut = Vec2F.Normalize(m_canvas.GraphToClientTangent(cpt.TangentOut));
                            Seg2F seg = new Seg2F(clientcpt, (clientcpt + tangOut * m_tangentLength));
                            if (GdiUtil.Intersects(seg, pickRect))
                            {
                                points.Add(cpt);
                                regions.Add(PointSelectionRegions.TangentOut);
                                continue;
                            }
                        }

                        bool pickTanIn = true;
                        if (i > 0)
                        {
                            IControlPoint prevCpt = curvePoints[i - 1];
                            pickTanIn = prevCpt.TangentOutType != CurveTangentTypes.Stepped
                            && prevCpt.TangentOutType != CurveTangentTypes.SteppedNext;
                        }

                        if (pickTanIn)
                        {
                            //  pick tangentIn.
                            Vec2F tangIn = Vec2F.Normalize(m_canvas.GraphToClientTangent(cpt.TangentIn));
                            tangIn.X = -tangIn.X;
                            tangIn.Y = -tangIn.Y;
                            Seg2F seg = new Seg2F(clientcpt, (clientcpt + tangIn * m_tangentLength));
                            if (GdiUtil.Intersects(seg, pickRect))
                            {
                                points.Add(cpt);
                                regions.Add(PointSelectionRegions.TangentIn);
                            }
                        }
                    }
                }

            } // foreach curve in curves
        }