Beispiel #1
0
        /// <override></override>
        public override RelativePosition CalculateRelativePosition(int x, int y)
        {
            // The RelativePosition of a PolyLine is defined as
            // A = ControlPointId of the first vertex of the nearest line segment (FirstVertex -> LastVertex)
            // B = Angle between the line segment (A / next vertex of A) and the point
            // C = Distance of the point from A in percentage of the line segment's length
            RelativePosition result = RelativePosition.Empty;
            Point            p      = Point.Empty;

            p.Offset(x, y);

            // Find the nearest line segment
            int   pointIdx          = -1;
            float angleFromA        = float.NaN;
            float distanceFromA     = float.NaN;
            float lowestAbsDistance = float.MaxValue;
            float lineWidth         = LineStyle.LineWidth / 2f + 2;
            int   cnt = vertices.Count - 1;

            for (int i = 0; i < cnt; ++i)
            {
                float dist = Geometry.DistancePointLine(p, vertices[i], vertices[i + 1], true);
                if (dist < lowestAbsDistance)
                {
                    lowestAbsDistance = dist;
                    pointIdx          = i;
                    if (dist > lineWidth)
                    {
                        angleFromA = ((360 + Geometry.RadiansToDegrees(Geometry.Angle(vertices[i], vertices[i + 1], p))) % 360);
                    }
                    else
                    {
                        angleFromA = 0;
                    }
                    distanceFromA = Geometry.DistancePointPoint(vertices[i], p);
                }
            }

            if (pointIdx >= 0)
            {
                result.A = GetControlPointId(pointIdx);
                result.B = Geometry.DegreesToTenthsOfDegree(angleFromA);
                float segmentLength = Geometry.DistancePointPoint(vertices[pointIdx], vertices[pointIdx + 1]);
                if (segmentLength == 0)
                {
                    result.C = 0;
                }
                else
                {
                    result.C = (int)Math.Round((distanceFromA / (segmentLength / 100)) * 10);
                }
                Debug.Assert(result.B >= 0 && result.B <= 3600, "Calculated angle is out of range.");
            }
            if (result == RelativePosition.Empty)
            {
                result.A = result.B = result.C = 0;
            }
            return(result);
        }
Beispiel #2
0
        /// <override></override>
        public override Point CalculateAbsolutePosition(RelativePosition relativePosition)
        {
            // The RelativePosition of a PolyLine is defined as
            // A = ControlPointId of the first vertex of the nearest line segment (FirstVertex -> LastVertex)
            // B = Angle between the line segment (A / next vertex of A) and the point
            // C = Distance of the point from A in percentage of the line segment's length
            Point result   = Point.Empty;
            int   idx      = GetControlPointIndex(relativePosition.A);
            float angle    = Geometry.TenthsOfDegreeToDegrees(relativePosition.B);
            float distance = relativePosition.C / 1000f;

            if (distance != 0)
            {
                float segmentLength = Geometry.DistancePointPoint(vertices[idx], vertices[idx + 1]);
                Point p             = Geometry.VectorLinearInterpolation(vertices[idx], vertices[idx + 1], (distance));
                result = Geometry.RotatePoint(vertices[idx], angle, p);
                Debug.Assert(Geometry.IsValid(result));
            }
            else
            {
                result = vertices[idx];
            }
            return(result);
        }
Beispiel #3
0
 /// <summary>
 /// Calculates the absolute position of a RelativePosition.
 /// </summary>
 public abstract Point CalculateAbsolutePosition(RelativePosition relativePosition);