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

Welcome to IWETHEY!

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)

Specifically, why is he still allowed to make them?
54 ms