IWETHEY v. 0.3.0 | TODO
1,095 registered users | 0 active users | 1 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New Mininum Convex Polygon around Points?
Anybody know of a good algorithm to find the smallest polygon that bounds a set of points?

The application I'm working on has a set of points being drawn (via PHP GD functions) onto a jpeg. They have an algorithm that tries to find the points that make up the bounding polygon, but it doesn't work in some cases and it's slow.

The current system takes the points and builds every possible triangle. Each triangle is then drawn, filled in black, onto a temporary graphic. They then loop through the points and check each point to see if it is on an edge of the blacked out area. To see if a pixel is on an edge it has to check every pixel next to the one it is considering to see if it is white or black. This is essentially a rounding error, and the algorithm fails if an interior point is too close to the bounding line.

Jay
New Are they always convex?
Been a while since I did any serious graphics work, but how about:

1. Calculate (not draw) lines between all points.
2. Drop any lines which cross (at some point other than original vertices). That is, if two lines cross, drop both of them.
3. Calc points from remaining lines.

If there's a concave point, however, that won't work. One possibility for *that* problem would be to calc your triangles and drop any vertices which are contained within a triangle.

These are just ideas off the top of my head.
New Convex Hull
What I want is to find the smallest convex polygon that will fit around an essentially random set of points.

I figured was a well known problem, but it took me a while to find the proper geometric name for the problem, which is Convex Hull. Googling on that gives a lot of pages that address the problem.

Now I just have to pick an algorithm and implement it in PHP.

Not that it's going to be real easy. It's been so long since I have done anything like this I can't remember basic crud like checking if a point intersects a line.

Jay
New Glad you said you found it
I thought about it, came up with one of the n log(n) algorithms, but now don't feel obliged to type it up. :-)

Cheers,
Ben
About the use of language: it is impossible to sharpen a pencil with a blunt axe. It is equally vain to try to do it with ten blunt axes instead. -- Edsger W. Dijkstra
New You need an algorithms book.
Like [link|http://www.amazon.com/exec/obidos/ASIN/0201314525/qid=1097033373/sr=2-1/ref=pd_ka_2_1/102-1952750-3300121|this one].

Wade.


Is it enough to love
Is it enough to breathe
Somebody rip my heart out
And leave me here to bleed
 
Is it enough to die
Somebody save my life
I'd rather be Anything but Ordinary
Please

-- "Anything but Ordinary" by Avril Lavigne.

New NIST DADS
The [link|http://www.nist.gov/dads/|NIST] page lists the [link|http://www.nist.gov/dads/HTML/optimalPolygonTriangProb.html|optimal polygon triangulation problem] but it unfortunately has no current definition.
New I have that one
Buried somewhere under the pile of stuff from moving. But I've read it more then once, and I don't think it address this specific question anyway.

Jay
New Wierd
There is a chapter on Convex Hulls in my copy of the C++ version: [link|http://www.amazon.com/exec/obidos/tg/detail/-/0201510596/qid=1097038850/sr=1-6/ref=sr_1_6/102-2463306-3277769?v=glance&s=books|http://www.amazon.co...?v=glance&s=books] but it looks like he's expanded the book into 5 volumes for later editions and left some older content out.
--
Chris Altmann
New I have the C++ one, too.
And I remember the chapter on Convex Hulls. That's why I recommended it.

Wade.

Is it enough to love
Is it enough to breathe
Somebody rip my heart out
And leave me here to bleed
 
Is it enough to die
Somebody save my life
I'd rather be Anything but Ordinary
Please

-- "Anything but Ordinary" by Avril Lavigne.

New Start with center of mass
The find the points that are the farthest from the center and connect these points. You don't mention how many max vertices in your polygon, so that would be a tuning issue.
===

Implicitly condoning stupidity since 2001.
New Re: Mininum Convex Polygon around Points?
Do you just need to know if a point is inside or outside? Contour integration.

Let me try to restate your problem - given any N points, find the smallest polygon (as in least area) such that all the points are on or inside it. Is that right? (What they are doing is obviously wrong without further checking.)
-drl
New Yep, that would be a formal statement
Right now, I'm aiming for the Gift Wrap / Jarvis' March algorithm. It's O(N^2), but it's simple and the current algorithm is something like O(N!) so it will still be an improvement.

Sadly, I'm having more trouble computing the angle of intersection then anything else. Too much high school geometry forgotten.

Jay
New Re: Yep, that would be a formal statement
Slope of line 1 = (y12 - y11)/(x12 - x11) = tan A1

Slope of line 2 = (y22 - y21)/(x22 - x21) = tan A2

Here (x1i, y1i) and (x2i,y2i), i=1,2 are any two points on lines 1 and 2.

Need A2 - A1.

tan (A2 - A1) = (tan A2 - tan A1) / ( 1 + tan A2 tan A1)

So the answer is

A2 - A1 = arctan (tan A2 - tan A1) / (1 + tan A2 tan A1)

Actually it is much simpler to work with the "homogeneous coordinates" of projective geometry. Then the angle can be calculated as a logarithm of the "cross ratio" of four lines - the two lines you are given and two imaginary "ideal" lines that connect the intersection point of the given lines with the two "circular points at infinity". The angle is then

A = i log XR(L1, L2, I1, I2)

The tangents etc. that appear above are the reduction of this formula for a specific coordinate system.

It really pays to learn projective ideas if you're going to do computational geometry.
-drl
New If he doesn't remember highschool math...
do you think that he'll figure out how to apply what you said?

Curious,
Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
New He's Jay - he'll figure it out
-drl
New You don't need to compute angles
You just need to be able to compare angles. That is easier because you just need to compute the sin and cos of the angles and compare those. Let me walk you through that calculation and then comparison.

Suppose that p0, p1, and p2 are points, represented by ordered pairs of coordinates, (p0x, p0y), (p1x, p1y), and (p2x, p2y). Suppose that you're interested in the angle at p0 between the lines from p0->p1 and p0->p2. That is the angle between the vectors
\n  v1  = p1 - p0\n     = (p1x, p1y) - (p0x, p0y)\n     = (p1x-p0x, p1y-p0y)\n     = (v1x, v1y)\n
and
\n  v2  = p2 - p0\n     = (p2x, p2y) - (p0x, p0y)\n     = (p2x-p0x, p2y-p0y)\n     = (v2x, v2y)\n

Now let me introduce the dot product. Suppose that v and w are two vectors. Then the definition of the dot product is
\n  v dot w = (vx, vy) dot (wx, wy)\n          = vx*wx + vy*wy\n

Seems simple, why do you care? Well because of the following geometric fact (good in any number of dimensions): The dot product of two vectors is the product of their lengths and the angle between them! In other words if we define:
\n  |v| = length of v\n      = sqrt(vx*vx + vy*vy)\n

then
\ncos(angle from v to w)\n      = (v dot w)/ ( |v| * |w| )\n

all of which we know how to calculate. In your problem you can just calculate v1 and v2, then drop them in as v and w. (In fact the same calculation works in any number of dimensions.)

So we can compute the cos of the angle. What about the sin? Well that needs a 2-dim piece of trivia. Suppose that v1' is v1 rotated 90 degrees counter-clockwise. Then the sin of the angle from v1 to v2 is the cos of the angle from v1' to v2. So what is v1'? Well it turns out to be (v1y, -v1x). So to calculate the sin, drop v1' and v2 in as v and w in the formula above.

Now that we have sin and cos, you can figure out how to calculate angles with appropriate invocations to the inverse functions. But you don't need to do that! Just remember this fact. Going from 0 degrees to 180 degrees, sin(angle) >= 0 and cos(angle) decreases from 1 to -1. Between 180 and 360 degrees, sin(angle) < 0 and cos(angle) increases from -1 back to 1. You can therefore compare angles to see which is greater without actually calculating them.

If you don't want to do pairs of comparisons, though, you don't have to. Instead you can write a cheesy function like this (untested but it compiles) one in Perl to get something that increases from 0 to 4 as the angle goes from 0 to 360 degrees (though not evenly):
\n# Given 3 points p0, p1, and p2, this returns a\n# number from 0 to 4 that increases monotonically as\n# the angle p1->p0->p2 goes from 0 to 360 degrees.\n#\n# This therefore isn't the angle, but can be used to\n# compare the angles.\nsub angle_proxy {\n  my ($p0, $p1, $p2) = @_;\n\n  my $v1 = subtract_vectors($p1, $p0);\n  my $v2 = subtract_vectors($p2, $p0);\n\n  if (vector_cos(rotate_90($v1), $v2) >= 0) {\n    return 1 - vector_cos($v1, $v2);\n  }\n  else {\n    return 3 + vector_cos($v1, $v2);\n  }\n}\n\n# Returns the cos of the angle between 2 vectors.\nsub vector_cos {\n  my ($v, $w) = @_;\n  return dot($v, $w) / sqrt(dot($v, $v)) / sqrt(dot($w, $w));\n}\n\n# From here on down functions rely on the internal\n# representation that I have chosen, an array\n# reference in Perl.  If the functions or notations\n# do not make sense, refer to the math explanation\n# above.\n#\n# You should be able to guess most of the notation\n# except $#$foo.  $#array is the last index of an\n# array.  If $foo is a reference to an array, then\n# 0..$#$foo is the set of possible indexes.  I'm\n# using that just to show what can be generalized\n# easily to more than 2 dimensions.\n#\n# I've left out various sanity checks that one might\n# want to insert.\n\n# Subtracts the second from the first.\nsub subtract_vectors {\n  my ($v, $w) = @_;\n  my $difference = [];\n  for my $i (0..$#$v) {\n    $difference->[$i] = $v->[$i] - $w->[$i];\n  }\n  return $difference;\n}\n\n# Returns the dot product of two vectors.\nsub dot {\n  my ($v, $w) = @_;\n  my $answer = 0;\n  for my $i (0..$#$v) {\n    $answer += $v->[$i] * $w->[$i];\n  }\n  return $answer;\n}\n\n# Rotates a vector 90 degrees counter-clockwise.\n# Only works for 2-D vectors.\nsub rotate_90 {\n  my $v = shift;\n  return [$v->[1], -$v->[0]];\n}\n


Cheers,
Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
New Actually ended up using vector math
What I wrote did end up computing the angle using the dot product. But the optimization of quiting before I had the actual angle and just comparing a relative value didn't occure to me.

Jay
     Mininum Convex Polygon around Points? - (JayMehaffey) - (16)
         Are they always convex? - (FuManChu) - (7)
             Convex Hull - (JayMehaffey) - (6)
                 Glad you said you found it - (ben_tilly)
                 You need an algorithms book. - (static) - (4)
                     NIST DADS - (ChrisR)
                     I have that one - (JayMehaffey) - (2)
                         Wierd - (altmann) - (1)
                             I have the C++ one, too. - (static)
         Start with center of mass - (drewk)
         Re: Mininum Convex Polygon around Points? - (deSitter) - (6)
             Yep, that would be a formal statement - (JayMehaffey) - (5)
                 Re: Yep, that would be a formal statement - (deSitter) - (2)
                     If he doesn't remember highschool math... - (ben_tilly) - (1)
                         He's Jay - he'll figure it out -NT - (deSitter)
                 You don't need to compute angles - (ben_tilly) - (1)
                     Actually ended up using vector math - (JayMehaffey)

Able to chew and walk gum at the same time.
132 ms