Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I'm mostly throwing this out there because this question caught my interest, it was something I have no expertise in, and I'd like to generate discussion.</p> <p>I took the <a href="http://www.engr.colostate.edu/~dga/dga/papers/point_in_polygon.pdf" rel="nofollow">Point in Polygon pseudo-code</a> and tried to make it fit your situation. It seemed you are only interested in determining if something is winding clockwise or counter-clockwise. Here is a simple test and a very simple (rough around the edges) C# implementation.</p> <pre><code>[Test] public void Test_DetermineWindingDirection() { GraphicsPath path = new GraphicsPath(); // Set up points collection PointF[] pts = new[] {new PointF(10, 60), new PointF(50, 110), new PointF(90, 60)}; path.AddLines(pts); foreach(var point in path.PathPoints) { Console.WriteLine("X: {0}, Y: {1}",point.X, point.Y); } WindingDirection windingVal = DetermineWindingDirection(path.PathPoints); Console.WriteLine("Winding value: {0}", windingVal); Assert.AreEqual(WindingDirection.Clockwise, windingVal); path.Reverse(); foreach(var point in path.PathPoints) { Console.WriteLine("X: {0}, Y: {1}",point.X, point.Y); } windingVal = DetermineWindingDirection(path.PathPoints); Console.WriteLine("Winding value: {0}", windingVal); Assert.AreEqual(WindingDirection.CounterClockWise, windingVal); } public enum WindingDirection { Clockwise, CounterClockWise } public static WindingDirection DetermineWindingDirection(PointF[] polygon) { // find a point in the middle float middleX = polygon.Average(p =&gt; p.X); float middleY = polygon.Average(p =&gt; p.Y); var pointInPolygon = new PointF(middleX, middleY); Console.WriteLine("MiddlePoint = {0}", pointInPolygon); double w = 0; var points = polygon.Select(point =&gt; { var newPoint = new PointF(point.X - pointInPolygon.X, point.Y - pointInPolygon.Y); Console.WriteLine("New Point: {0}", newPoint); return newPoint; }).ToList(); for (int i = 0; i &lt; points.Count; i++) { var secondPoint = i + 1 == points.Count ? 0 : i + 1; double X = points[i].X; double Xp1 = points[secondPoint].X; double Y = points[i].Y; double Yp1 = points[secondPoint].Y; if (Y * Yp1 &lt; 0) { double r = X + ((Y * (Xp1 - X)) / (Y - Yp1)); if (r &gt; 0) if (Y &lt; 0) w = w + 1; else w = w - 1; } else if ((Y == 0) &amp;&amp; (X &gt; 0)) { if (Yp1 &gt; 0) w = w + .5; else w = w - .5; } else if ((Yp1 == 0) &amp;&amp; (Xp1 &gt; 0)) { if (Y &lt; 0) w = w + .5; else w = w - .5; } } return w &gt; 0 ? WindingDirection.ClockWise : WindingDirection.CounterClockwise; } </code></pre> <p>The difference that I've put in that makes this a bit specific to your problem is that I've calculated the average values of X and Y from all points and use that as the "point in polygon" value. So, passing in just an array of points, it will find something in the middle of them.</p> <p>I've also made the assumption that the V i+1 should wrap around when it gets to the bounds of the points array so that</p> <pre><code>if (i + 1 == points.Count) // use points[0] instead </code></pre> <p>This hasn't been optimized, it's just something to potentially answers your question. And perhaps you've already come up with this yourself.</p> <p>Here's hoping for constructive criticism. :)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload