示例#1
0
文件: Seg2F.cs 项目: blue3k/ATFClone
        /// <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);
        }
示例#2
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);
        }
示例#3
0
        /// <summary>
        /// Constructs the circle containing 3 points</summary>
        /// <param name="p1">Point 1</param>
        /// <param name="p2">Point 2</param>
        /// <param name="p3">Point 3</param>
        public CircleF(Vec2F p1, Vec2F p2, Vec2F p3)
        {
            Vec2F  o1 = Vec2F.Add(p1, p2); o1 *= 0.5f;
            Vec2F  o2 = Vec2F.Add(p3, p2); o2 *= 0.5f;
            Vec2F  d1 = Vec2F.Sub(p2, p1); d1 = d1.Perp;
            Vec2F  d2 = Vec2F.Sub(p3, p2); d2 = d2.Perp;
            double t1 = 0;
            double t2 = 0;

            if (Ray2F.Intersect(new Ray2F(o1, d1), new Ray2F(o2, d2), ref t1, ref t2))
            {
                Center = o1 + d1 * (float)t1;
                Radius = Vec2F.Distance(Center, p1);
            }
            else
            {
                Center = new Vec2F(float.PositiveInfinity, float.PositiveInfinity);
                Radius = float.PositiveInfinity;
            }
        }