public override IFigure HitTest(Point point) { var width = LogicalWidth(); var r = Math.Distance(Center, point); var angleToPoint = Math.GetAngle(Center, point); // Find the point relative to the ellipse in canonical form(unrotated). var canonicalPoint = Math.RotatePoint(Center, r, angleToPoint - Inclination).Minus(Center); var equationLeft = canonicalPoint.X.Sqr() / SemiMajor.Sqr() + canonicalPoint.Y.Sqr() / SemiMinor.Sqr(); // HitTest for the edge if ((equationLeft - 1).Abs() < CursorTolerance + width / 2) { return(this); } // HitTest for the fill. Use this instead of base.HitTest() because it is not working properly with ellipses. var shapeStyle = Style as ShapeStyle; if (shapeStyle != null) { if (shapeStyle.IsFilled && equationLeft < 1) { return(this); } } return(null); }
public override IFigure HitTest(Point point) { // HitTest for the fill. ShapeStyle shapeStyle = Style as ShapeStyle; if (shapeStyle != null) { if (shapeStyle.IsFilled) { var fillResult = HitTestShape(point); if (fillResult != null) { return(fillResult); } } } // HitTest for the edge var width = LogicalWidth(); var r = Math.Distance(Center, point); var angleToPoint = Math.GetAngle(Center, point); bool between = Math.IsAngleBetweenAngles(angleToPoint, StartAngle, EndAngle, Clockwise); if (between) { // Find the point relative to the ellipse in canonical form(unrotated). var canonicalPoint = Math.RotatePoint(Center, r, angleToPoint - Inclination).Minus(Center); var equationLeft = canonicalPoint.X.Sqr() / SemiMajor.Sqr() + canonicalPoint.Y.Sqr() / SemiMinor.Sqr(); // A cheap way to deal with small arcs. var tolerance = CursorTolerance + width / 2; if (SemiMajor < 1 || SemiMinor < 1) { tolerance += .25; } if ((equationLeft - 1).Abs() < tolerance) { return(this); } } // HitTest for the chord (if necessary). if (this is EllipseSegment || this is CircleSegment) { var epsilon = ToLogical(this.Shape.StrokeThickness) / 2 + CursorTolerance; if (Math.IsPointOnSegment(new PointPair(BeginLocation, EndLocation), point, epsilon)) { return(this); } } // HitTest for the radii (if necessary). if (this is EllipseSector || this is CircleSector) { var epsilon = ToLogical(this.Shape.StrokeThickness) / 2 + CursorTolerance; if (Math.IsPointOnSegment(new PointPair(Center, BeginLocation), point, epsilon) || Math.IsPointOnSegment(new PointPair(Center, EndLocation), point, epsilon)) { return(this); } } return(null); }