0

Let's say I have a contour shape defined by two functions x(p) and y(p), where p is the distance traveled along the perimeter of the shape, normalized between 0 and 1. For example, a unit circle about the origin would be defined as x(p) = sin(2 * pi * p) and y(p) = cos(2 * pi * p).

A simple test to determine if a point is within that circle would be to calculate the point's distance from the origin, and then detect if that distance is less than or equal to 1.

But what if my shape has multiple crossings, and is much more complicated than a circle?

There exists a point in polygon test for a discrete shape defined by a set of points. That algorithm is pretty easy to find, since it's used in a lot of places. But if I don't want to use a discrete definition of my shape, what algorithm can I use to determine the winding number, with the assumption that the shape is defined at compile time?

NmdMystery
  • 2,778
  • 3
  • 32
  • 60
  • Does Wikipedia help? https://en.wikipedia.org/wiki/Winding_number – Mark Ransom Oct 20 '15 at 22:01
  • @MarkRansom I saw that, I was hoping it could be explained in CS terms rather than applied math terms. There's definitions of the discrete algorithm, but as far as differential geometry goes you're kind of on your own in implementing it. – NmdMystery Oct 20 '15 at 22:12
  • The only code I've seen is for discrete segments, yours is kind of a specialized case. – Mark Ransom Oct 20 '15 at 22:28

3 Answers3

1

If you know a point that is inside (or outside) the shape and the shape is smooth and non-intersecting, then you can connect the known point to any other point and count the number of times it crosses the boundary. An even number of times means the unknown point is similarly inside (or outside). An odd number means the opposite.

This is based on the Jordan Curve Theorem. As I recall, winding number is needed for the proof of the theorem, but the application is quite easy.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
  • What if the shape intersects, and has regions with winding numbers greater than 1? – NmdMystery Oct 20 '15 at 22:36
  • @NmdMystery . . . The Jordan Curve Theorem applies to smooth (actually, I think continuous) non-intersecting curves. If they intersect, then you need to divide the shape into separate shapes. – Gordon Linoff Oct 22 '15 at 01:31
1

How about computing the total curvature of the closed curve (assuming it is everywhere differentiable), then dividing it by 2PI? See Wiki's Total Curvature page here.

fang
  • 3,473
  • 1
  • 13
  • 19
1

Generalizing the point in polygon test, you can find all solutions of y(p)=0 such that x(p)>0 and use the parity of their numbers.

In the case of the circle, cos(2πp)=0 for p=(k+1/2)π, and only one value of p in range [0,1) makes sin(2πp)>0.

So far so good if you can solve the y equation analytically. Otherwise you will need a reliable numerical solver, able to spot all roots. An alternative is to flatten the curve (draw it as a polyline, ensuring a maximum deviation tolerance), and apply the polygon algorithm.

enter image description here


For the sake of a second example, let us consider Pascal's limaçon with equation r = 0.5 + cos Θ, and some test point along X.

enter image description here

y = (0.5 + cos Θ) sin Θ = 0

for Θ=0, 2π/3, π, 4π/3. The corresponding abscissas are 1.5, 0, 0.5 and 0.

You can conclude that the interior points on the X axis are between 0.5 and 1.5 (also at 0, in a degenerate way).

  • The first suggestion is what I tried to do and I ended up with a square, lol. I also figured "rendering" the curve as a set of points would work, as per your second suggestion. I'm going to try the first approach again and see where it gets me. – NmdMystery Oct 22 '15 at 17:14
  • @NmdMystery: let me add that if the equation y=0 cannot be solved analytically, you may still find a curve F(x, y)=0 through the origin (x(0=0, y(0)= 0, F(0, 0)=0) and extending far enough, for which you can express the roots. –  Oct 22 '15 at 19:48