(Point64 pt, OutPt op)
| 2644 | |
| 2645 | |
| 2646 | private static PointInPolygonResult PointInOpPolygon(Point64 pt, OutPt op) |
| 2647 | { |
| 2648 | if (op == op.next || op.prev == op.next) |
| 2649 | return PointInPolygonResult.IsOutside; |
| 2650 | |
| 2651 | OutPt op2 = op; |
| 2652 | do |
| 2653 | { |
| 2654 | if (op.pt.Y != pt.Y) break; |
| 2655 | op = op.next!; |
| 2656 | } while (op != op2); |
| 2657 | if (op.pt.Y == pt.Y) // not a proper polygon |
| 2658 | return PointInPolygonResult.IsOutside; |
| 2659 | |
| 2660 | // must be above or below to get here |
| 2661 | bool isAbove = op.pt.Y < pt.Y, startingAbove = isAbove; |
| 2662 | int val = 0; |
| 2663 | |
| 2664 | op2 = op.next!; |
| 2665 | while (op2 != op) |
| 2666 | { |
| 2667 | if (isAbove) |
| 2668 | while (op2 != op && op2.pt.Y < pt.Y) op2 = op2.next!; |
| 2669 | else |
| 2670 | while (op2 != op && op2.pt.Y > pt.Y) op2 = op2.next!; |
| 2671 | if (op2 == op) break; |
| 2672 | |
| 2673 | // must have touched or crossed the pt.Y horizontal |
| 2674 | // and this must happen an even number of times |
| 2675 | |
| 2676 | if (op2.pt.Y == pt.Y) // touching the horizontal |
| 2677 | { |
| 2678 | if (op2.pt.X == pt.X || (op2.pt.Y == op2.prev.pt.Y && |
| 2679 | (pt.X < op2.prev.pt.X) != (pt.X < op2.pt.X))) |
| 2680 | return PointInPolygonResult.IsOn; |
| 2681 | op2 = op2.next!; |
| 2682 | if (op2 == op) break; |
| 2683 | continue; |
| 2684 | } |
| 2685 | |
| 2686 | if (op2.pt.X <= pt.X || op2.prev.pt.X <= pt.X) |
| 2687 | { |
| 2688 | if ((op2.prev.pt.X < pt.X && op2.pt.X < pt.X)) |
| 2689 | val = 1 - val; // toggle val |
| 2690 | else |
| 2691 | { |
| 2692 | int d = InternalClipper.CrossProductSign(op2.prev.pt, op2.pt, pt); |
| 2693 | if (d == 0) return PointInPolygonResult.IsOn; |
| 2694 | if ((d < 0) == isAbove) val = 1 - val; |
| 2695 | } |
| 2696 | } |
| 2697 | isAbove = !isAbove; |
| 2698 | op2 = op2.next!; |
| 2699 | } |
| 2700 | |
| 2701 | if (isAbove == startingAbove) return val == 0 ? PointInPolygonResult.IsOutside : PointInPolygonResult.IsInside; |
| 2702 | { |
| 2703 | int d = InternalClipper.CrossProductSign(op2.prev.pt, op2.pt, pt); |
nothing calls this directly
no test coverage detected