public override KeyValuePair <double, Handle> GetSelectionDistance(SysPoint point) { double distance; if (!ShouldRender) { distance = double.NaN; } else { BoardPoint boardPoint = Board.GetBoardPoint(point); BoardPoint observerPosition = GetEffectiveObserverPosition(); Line2 bearingLine = new Line2(observerPosition, new Vector2(0, 1).Rotate(-Bearing)); distance = Math.Abs(bearingLine.DistanceTo(boardPoint)) * Board.ZoomFactor; // the distance measurement considers the entire infinite line, but we only want to consider the ray starting from the observer, so // we'll ignore the portion of the line on the other side of the observer point if (distance > 4 || bearingLine.ClosestPointOnSegment(boardPoint) == bearingLine.Start && boardPoint.DistanceTo(bearingLine.Start) * Board.ZoomFactor > 4) { distance = double.NaN; } } return(new KeyValuePair <double, Handle>(distance, null)); }
public override void Render(Graphics graphics) { if (ShouldRender) { BoardPoint observerPosition = GetEffectiveObserverPosition(); observerPosition = new BoardPoint(observerPosition.X * Board.ZoomFactor, -observerPosition.Y * Board.ZoomFactor); Vector2 screenVector = new Vector2(0, -1).Rotate(Bearing); Line2 bearingLine = new Line2(observerPosition, screenVector); // since the bearing line is infinitely long, we'll test the intersection of the line against all four sides of the clipping // rectangle, and draw the line to the furthest intersection BoardRect clipRect = new BoardRect(graphics.VisibleClipBounds); BoardPoint endPoint = BoardPoint.Invalid; double maxDistance = 0; for (int i = 0; i < 4; i++) { Line2 edge = clipRect.GetEdge(i); LineIntersection intersection = bearingLine.GetIntersectionInfo(edge); if (intersection.OnSecond) { double distance = observerPosition.DistanceTo(intersection.Point); // find the closest point on the segment to ensure that we're only considering intersections in the forward direction of the // vector if (distance > maxDistance && bearingLine.ClosestPointOnSegment(intersection.Point) != bearingLine.Start) { endPoint = intersection.Point; maxDistance = distance; } } } if (endPoint.IsValid) { graphics.DrawLine(Pen, observerPosition.ToPointF(), endPoint.ToPointF()); graphics.DrawCircle(Pen, observerPosition.ToPointF(), 3); RenderTime(graphics, (observerPosition + (endPoint - observerPosition) * 0.5).ToPointF()); } } }