HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Math problem

08-31-2007, 01:04 AM#1
NightBreeze
EDIT: I solved the problem. The factor is q = (1 + 1/a * tan(b)) / (1 - a * tan(b)). This is the fastest it gets, with only 1 tangent functioncall.





I hope that it's possible to avoid going into the context of the problem, so I will state it as abstractly as possible. I hope you can all follow, since it's pretty much a geometric problem which is hard to describe with words. I will try my best to do so though.

Given are 2 points in 2D space, for example (1, 0.5) and (1, 16). I draw lines from the origin through those 2 points. Those lines will have the equations y = 0.5x and y = 16x respectively. Both of those lines make a certain angle with the x-axis. Well there are really 4 angles per line at the origin, but I'm only interested in the smallest angle between the positive part of the line and the x-axis. You can find this angle easily by realizing that the slope of the line (dy/dx or 0.5/1 for example) is the tangent of the angle with the x-axis. If you take tan^-1 of the slope of the line, you get the angle it makes with the x-axis. Agreed?

Now for the problem:

There is an angle difference between the first line and the second line. I want to divide that angle difference in x pieces, let's say 4 for this example. Now I want to find the 3 lines 'in between' the 2 I already have, each 1/4 of the angle difference apart from each other. This would mean that the slopes of those lines is tan^-1 (tan(0.5) + 1/4*angledifference * x). Big formula, but what it means is I increment the angle the line makes with the x-axis by 1/4th of the total angle difference between the 2 lines and then take the inverse tangent to get the actual slope of the line.

This all works nicely, but as you can see it's not a real elegant way of going about it. I take the tangent of a slope, increase it by an angle and then take the inverse tangent again. That basically means that I transform the slope into an angle, work on it, and transform it back again. What I would want is to find some sort of factor q by which I can multiply the slope of the first line (which has slope 0.5) to get to the next line, so that I don't have to use the angles. Now I know that some way or another, the angles come into play, but maybe someone can find a better way to do this?

I have 2 other options.. I will list them here if you want to read them, but maybe you can try finding it by yourself ^^

1. Angle addition formulas

The formulas state that:
sin(a+b) = sin(a) * cos(b) + sin(b) * cos(a) and
cos(a+b) = cos(a) * cos(b) - sin(a) * sin(b)

Two things are important to note here. a is the angle the first line makes with the x-axis and b is the increment in angle (you know, the difference/4 etc..). Because tan(a) = sin(a)/cos(a): sin(a+b)/cos(a+b) gives the tangent of the angle of the line with the x-axis. This tangent is equal to the slope of that line. So dividing those 2 gives us the slope.
The next important thing is to realize that sin(a) = y of the first point (which made the first line) and cos(a) = x of the first point.

This gives us:
sin(a+b) = y * cos(b) + x * sin(b)
cos(a+b) = x * cos(b) - y * sin(b)

Now what I want to solve is this:

sin(a+b) / cos(a+b) = sin(a) / cos(a) * q

sin(a) was equal to y and cos(a) was equal to x... so

sin(a+b) / cos(a+b) = y / x * q

The left part of the equation is the new slope, the right part is the old slope * q.

If I write it out, I get:

(y * cos(b) + x * sin(b)) / (x * cos(b) - y * sin(b)) = y / x * q

I now divide by y / x or multiply by its inverse to solve q.

(x * y * cos(b) + x² * sin(b)) / (x * y * cos(b) - y² * sin(b)) = q

So now I have found q... But how the hell do I simplify this crap? Could this be faster than taking the inverse tangent of a tangent? I don't know about the speed of those operations. One may notice that both the numerator and the denominator contain x * y * cos(b), maybe this can be used? I have no idea. I could use some help :)



The second approach circumvents the angles completely and doesn't give the lines I wanted, but does always give 3 lines inbetween the 2 lines. The angle between them depends on the slope of the previous angle though. It is done pretty easily by taking the factor of the 2 lines (16/0.5 = 32) and then multiply the initial slope by 32^(x/4) where x goes from 1 to 4. That way the factor difference is taken in 4 steps, pretty easy. This approach sucks ass, of course, cause roots take a lot of time and it doesn't even produce the required lines.


So there you have it. A long story and I hope you could make something of it. I hope it somehow sparked your interest to make you want to invest some time into it ^^ or maybe someone with a mathematical background can give me the answer right away. If not, feel free to ask questions.

Thanks



EDIT: The problem can be summarized to this: With what factor must the slope of a line be multiplied to get an absolute increase in angle with the x-axis?
08-31-2007, 05:16 PM#2
PipeDream
The problem with making a problem completely abstract is that we can't zoom out. In this case we can guess that you are looking at space so that you took a wrong turn earlier using a 1 dimensional parameterization instead of the 2 dimensions of the warcraft plane.
08-31-2007, 06:00 PM#3
NightBreeze
I do not understand what you mean. My methods were correct, but I couldn't get to fit it into an efficient formula. I am working in the warcraft x,y place. The third dimension has nothing to do with it.
08-31-2007, 06:26 PM#4
PipeDream
y(x) vs. <x(t),y(t)>
The second is more general than the first in a way that you require. For example y(x) makes no sense for vertical lines. Any formulas you derive by routing through y(x) will have singularities and round off issues, just like the one you found.
08-31-2007, 07:21 PM#5
NightBreeze
You're right. That is better. I worked around the vertical line issue in another way. I find it easier to work with y(x) because it's a lot simpeler and enough for what I require it to do. What kind of singularities/round off issues do you mean?
09-01-2007, 02:28 AM#6
PipeDream
E.g. in your formula, 1 - a * tan(b) = 0 has a whole line's worth of solutions. Any of these will cause problems. Trying to go across the singularity to get a line with negative slope starting from one with positive should also fail.

The lack of equality of order of trig function on the angles (a vs tan b) suggests to me that there was an error in deriving it, but that's moot.

If you want a single multiplicative factor which you can repeatedly apply to rotate, use a linear map on the plane:
x -> x Cos(p) - y Sin(p)
y -> x Sin(p) + y Cos(p)
Which you nearly derived, although you made it nonlinear by forcing it into one dimension.
09-01-2007, 10:23 AM#7
NightBreeze
It's possible to circumvent the problem you described by defining the domains for both functions.

tan(a+b) = (tan(a) + tan(b)) / (1 - tan(a) * tan(b))
If you divide by tan(a), you get the factor I had as my solution.

Thanks for looking into it though :) You're right that parametrization would have made this problem easier.