Example #1
0
        public static IEnumerable <Point> IntersectionPoints(this PrimitiveLine line, IPrimitive other, bool withinBounds = true)
        {
            IEnumerable <Point> result;

            switch (other.Kind)
            {
            case PrimitiveKind.Line:
                var p = line.IntersectionPoint((PrimitiveLine)other, withinBounds);
                if (p.HasValue)
                {
                    result = new[] { p.Value }
                }
                ;
                else
                {
                    result = new Point[0];
                }
                break;

            case PrimitiveKind.Ellipse:
                result = line.IntersectionPoints((PrimitiveEllipse)other, withinBounds);
                break;

            case PrimitiveKind.Point:
                var point = (PrimitivePoint)other;
                if (line.IsPointOnPrimitive(point.Location, withinBounds))
                {
                    result = new Point[] { point.Location };
                }
                else
                {
                    result = new Point[0];
                }
                break;

            case PrimitiveKind.Text:
                result = Enumerable.Empty <Point>();
                break;

            default:
                Debug.Assert(false, "Unsupported primitive type");
                result = Enumerable.Empty <Point>();
                break;
            }

            return(result);
        }
Example #2
0
        public static IPrimitive Offset(Plane drawingPlane, IPrimitive primitive, Point offsetDirection, double offsetDistance)
        {
            if (!drawingPlane.Contains(offsetDirection))
            {
                return(null);
            }

            IPrimitive result;

            switch (primitive.Kind)
            {
            case PrimitiveKind.Ellipse:
                var el          = (PrimitiveEllipse)primitive;
                var projection  = el.FromUnitCircle.Inverse();
                var isInside    = projection.Transform((Vector)offsetDirection).LengthSquared <= 1.0;
                var majorLength = el.MajorAxis.Length;
                if (isInside && (offsetDistance > majorLength * el.MinorAxisRatio) ||
                    (offsetDistance >= majorLength))
                {
                    result = null;
                }
                else
                {
                    Vector newMajor;
                    if (isInside)
                    {
                        newMajor = el.MajorAxis.Normalize() * (majorLength - offsetDistance);
                    }
                    else
                    {
                        newMajor = el.MajorAxis.Normalize() * (majorLength + offsetDistance);
                    }
                    result = new PrimitiveEllipse(
                        center: el.Center,
                        majorAxis: newMajor,
                        normal: el.Normal,
                        minorAxisRatio: el.MinorAxisRatio,
                        startAngle: el.StartAngle,
                        endAngle: el.EndAngle,
                        color: el.Color);
                }
                break;

            case PrimitiveKind.Line:
                // find what side the offset occured on and move both end points
                var line = (PrimitiveLine)primitive;
                // normalize to XY plane
                var picked        = drawingPlane.ToXYPlane(offsetDirection);
                var p1            = drawingPlane.ToXYPlane(line.P1);
                var p2            = drawingPlane.ToXYPlane(line.P2);
                var pline         = new PrimitiveLine(p1, p2);
                var perpendicular = new PrimitiveLine(picked, pline.PerpendicularSlope());
                var intersection  = pline.IntersectionPoint(perpendicular, false);
                if (intersection.HasValue && intersection.Value != picked)
                {
                    var offsetVector = (picked - intersection.Value).Normalize() * offsetDistance;
                    offsetVector = drawingPlane.FromXYPlane(offsetVector);
                    result       = new PrimitiveLine(
                        p1: line.P1 + offsetVector,
                        p2: line.P2 + offsetVector,
                        color: line.Color);
                }
                else
                {
                    // the selected point was directly on the line
                    result = null;
                }
                break;

            case PrimitiveKind.Point:
                var point             = (PrimitivePoint)primitive;
                var pointOffsetVector = (offsetDirection - point.Location).Normalize() * offsetDistance;
                result = new PrimitivePoint(point.Location + pointOffsetVector, point.Color);
                break;

            case PrimitiveKind.Text:
                result = null;
                break;

            default:
                throw new ArgumentException("primitive.Kind");
            }

            return(result);
        }
Example #3
0
        public static IPrimitive Offset(Plane drawingPlane, IPrimitive primitive, Point offsetDirection, double offsetDistance)
        {
            if (!drawingPlane.Contains(offsetDirection))
            {
                return(null);
            }

            return(primitive.MapPrimitive <IPrimitive>(
                       ellipse =>
            {
                var projection = ellipse.FromUnitCircle.Inverse();
                var isInside = projection.Transform((Vector)offsetDirection).LengthSquared <= 1.0;
                var majorLength = ellipse.MajorAxis.Length;
                if (isInside && (offsetDistance > majorLength * ellipse.MinorAxisRatio) ||
                    (offsetDistance >= majorLength))
                {
                    return null;
                }
                else
                {
                    Vector newMajor;
                    if (isInside)
                    {
                        newMajor = ellipse.MajorAxis.Normalize() * (majorLength - offsetDistance);
                    }
                    else
                    {
                        newMajor = ellipse.MajorAxis.Normalize() * (majorLength + offsetDistance);
                    }
                    return new PrimitiveEllipse(
                        center: ellipse.Center,
                        majorAxis: newMajor,
                        normal: ellipse.Normal,
                        minorAxisRatio: ellipse.MinorAxisRatio,
                        startAngle: ellipse.StartAngle,
                        endAngle: ellipse.EndAngle,
                        color: ellipse.Color);
                }
            },
                       line =>
            {
                // find what side the offset occured on and move both end points
                // normalize to XY plane
                var picked = drawingPlane.ToXYPlane(offsetDirection);
                var p1 = drawingPlane.ToXYPlane(line.P1);
                var p2 = drawingPlane.ToXYPlane(line.P2);
                var pline = new PrimitiveLine(p1, p2);
                var perpendicular = new PrimitiveLine(picked, pline.PerpendicularSlope());
                var intersection = pline.IntersectionPoint(perpendicular, false);
                if (intersection.HasValue && intersection.Value != picked)
                {
                    var offsetVector = (picked - intersection.Value).Normalize() * offsetDistance;
                    offsetVector = drawingPlane.FromXYPlane(offsetVector);
                    return new PrimitiveLine(
                        p1: line.P1 + offsetVector,
                        p2: line.P2 + offsetVector,
                        color: line.Color);
                }
                else
                {
                    // the selected point was directly on the line
                    return null;
                }
            },
                       point =>
            {
                var pointOffsetVector = (offsetDirection - point.Location).Normalize() * offsetDistance;
                return new PrimitivePoint(point.Location + pointOffsetVector, point.Color);
            },
                       text => null,
                       bezier => null,
                       image => null
                       ));
        }