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); }
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 )); }