## Trig and Maptools

Discuss macro implementations, ask for macro help (to share your creations, see User Creations, probably either Campaign Frameworks or Drop-in Resources).

Moderators: dorpond, trevor, Azhrei, giliath, jay, Mr.Ice

KaylaKaze
Cave Troll
Posts: 57
Joined: Mon Jun 18, 2007 1:08 pm
Contact:

### Re: Trig and Maptools

Code: Select all

``KaylaKaze:« math.sin(math.toRadians(45)) = math.sin(math.toRadians(45)) = 0.665148772988813401014167238056219011 »KaylaKaze:« math.cos(math.toRadians(45)) = math.cos(math.toRadians(45)) = 0.758912420807571160280436671609310105 »``

Those should be equal (or reasonably close).

prestidigitator
Dragon
Posts: 317
Joined: Fri Apr 23, 2010 8:17 pm

### Re: Trig and Maptools

For angles close to pi/2, you might want to use the identities:

cos x = sin (pi/2-x)
sin x = cos (pi/2-x)

For angles close to pi/4 (farthest from 0 and pi/2), you might want to use the half-angle identities:

sin(2x) = 2 sin(x) cos(x)
cos(2x) = cos^2(x)-sin^2(x)

Those (particularly the first ones, but the half-angle identities might give you an extra decimal point or so too) might help you to decrease the numeric errors when you creep away from x=0 in the Taylor Series expansions.

See http://en.wikipedia.org/wiki/List_of_tr ... identities
"He knows not how to know who knows not also how to un-know." --Sir Richard Burton

Deity
Posts: 8603
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

### Re: Trig and Maptools

KaylaKaze wrote:Something's off in your calculations:

Code: Select all

``KaylaKaze:« math.sin(math.toRadians(45)) = math.sin(math.toRadians(45)) = 0.665148772988813401014167238056219011 »KaylaKaze:« math.cos(math.toRadians(45)) = math.cos(math.toRadians(45)) = 0.758912420807571160280436671609310105 »``

Those should be equal (or reasonably close).

I only ran a couple of tests on each and see if they matched my calculator, but I'll double check this. At first glance, neither of those answers are correct:

toRadians = pi/180 * 45 = 0.78539816339744830961566084581988
cos(0.78539816339744830961566084581988) = 0.70710678118654752440084436210485
sin(0.78539816339744830961566084581988) = 0.70710678118654752440084436210485

on my calculator.

in MT:
cos(0.78539816339744830961499999999999990) = 0.758912420807571160280436671609310105
cos(0.78539816339744830961566084581988) = 0.758912420807571160280436671609310105
sin(0.78539816339744830961499999999999990) = 0.665148772988813401014167238056219011
sin(0.78539816339744830961566084581988) = 0.665148772988813401014167238056219011

So it seems the cos and sin function are off... I left those alone from the original file, but I'll see if adding some more significance helps, but when I tested the values before it was correct within 20 places... but that was with integers and that may be the difference.

That is a pretty big diff... I'll try increasing the significance. I left the

Deity
Posts: 8603
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

### Re: Trig and Maptools

I updated math.cos and get
MT: 0.70710678118654753120014772423229804685834 vs
Cal: 0.70710678118654752440084436210485

Here's the code for a temp fix for cos:

Code: Select all

``[H: radians = arg(0)][H: cosine = 1][H: product = 1][H, for(i,2,21,2), code: {   [H: product = product * -1 * i * (i-1)]   [H: cosine = cosine + power(radians,i) / product]}][H: macro.return = cosine ]  ``

Raising the iteration doesn't help beyond 21 probably because of the power function.. but 16 digits are significant.

edit:

Code: Select all

``[H: radians = arg(0)][H: sine = radians][H: product = 1][H, for(i,3,24,2), code: {   [H: product = product * -1 * i * (i-1)]   [H: sine = sine + power(radians,i) / product]}][H: macro.return = sine]  ``
Attachments
MathLib 2.1.rptok
MT version 1.3b70

ziltmilt
Dragon
Posts: 331
Joined: Sun Apr 29, 2007 9:28 pm
Contact:

### Re: Trig and Maptools

This is really cool, but I'm not sure how to use these functions. Let me describe what I'm trying to accomplish:

Many RPGs have flying characters. Flying on an incline means that they're flying their move distance and trying to achieve some amount of height, which the player specifies. So, that's 2 sides known of a right triangle.

So, using a2 + b2 = c2, I need to solve for a2:

a2 = c2 - b2

... and now the value of 'a' will tell me the horizontal distance traveled by a flying character. But, if the angle of ascent is greater then 45 degrees, the character has to make a skill check. So, I think I need the arcosine function to determine this angle. But, I can't figure out how to use these functions. Can you give me some pointers?

Deity
Posts: 8603
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

### Re: Trig and Maptools

Well, I can think of a couple ways of doing this, but if all you're interested in is greater than 45 degrees, then if the distance traveled on the horizontal plane is less the distance on the vertical plane, then it's greater than 45 degrees. So, if rise >= run then do skill check.

I should just toss in a distance formula for 2 points in space: distance(pointObjectA,pointObjectB); pointObject = json.set("{}","x",x,"y",y,"z",z) where z is optional. It's useful enough that I could end up using it. I know on another related thread I posted some distance getting formulas. I'll look it up later and post here. Or maybe I'll just add it to v2.2. But not tonight.

ziltmilt
Dragon
Posts: 331
Joined: Sun Apr 29, 2007 9:28 pm
Contact:

### Re: Trig and Maptools

Well, I'm really interested in getting the value of that angle, which I think I can do via an arcosine calculation. Is it difficult to do this?

Deity
Posts: 8603
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

### Re: Trig and Maptools

I have slope to angle formula and that should return angle given the height / distance as a single value for the parameter. I'll have to look up what the actual formula is, but I think it's arctangent.

ziltmilt
Dragon
Posts: 331
Joined: Sun Apr 29, 2007 9:28 pm
Contact:

### Re: Trig and Maptools

Going back to what you said earlier re: if rise >= run, then it's always 45 degrees or more ... I don't get this.

If I'm talking about a triangle with a 90 degree angle, won't the hypotenuse always be of greater length that the horizontal length? For a flying character, you'll always use such a triangle when flying, with the hypotenuse being the leg traveled, and the other two legs representing the vertical and horizontal distances. I can't imagine that the hypo. (or Side C) would ever be shorter than side A or side B.

Does this make sense?

: Actually, I think I do get what you're saying. If the height, or Side B, is >= Side A, the horizontal leg, then the angle of ascent is at least 45 degrees. Have I got that right?

Deity
Posts: 8603
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

### Re: Trig and Maptools

Right, if the 2 sides are equal then it is 45 degrees. If the height traveled is greater than the horizontal distance traveled then it is greater than 45 degrees to the horizontal plane. The hypotenuse is the actual distance traveled.

So, you travel from point A (aX,aY) to point B (bX,bY) on the MT map. To get that distance is as follows:

distance = sqrt( sqr(aX - bX) + sqr(aY - bY) )

distance is the horizontal distance traveled. The vertical distance is the change in elevation. To calculate the actual distance traveled would be as follows:

distanceTraveled = sqrt( sqr( distance ) + sqr( changeInElevation ) )
Attachments
example.jpg (9.45 KiB) Viewed 2466 times

Polymachine
Kobold
Posts: 1
Joined: Sat Aug 03, 2013 10:05 am

### Re: Trig and Maptools

Hi there, i've modified the arcTan function so that values >1 will be more accurately resolved:

Extensions include:
if the value is +/-1, return +/- 45°. (it'll never reach 45 deg unless the number of iterations goes through the roof). Also 45° is rather common on a square grid.

If the value is >1, use the inverse, since cot(x)=tan(90°-x).

Iterates 50 times .. i don't like the way it gets fuzzy towards the edges.

Code: Select all

``[H: radians = arg(0)][h, if(abs(radians)>=1), code:{   [h, if(abs(radians)==1), code:   {      [H: arcTangent = radians*math.pi()/4]   };   {      [h:alt=1/radians]      [h:inverse=math.arcTan(alt)]      [h: arcTangent = math.pi()/2 - inverse]   }]};{   [h: arcTangent = radians]   [h: sign = 1]      [h, for(i,3,50,2), code:   {      [H: sign = if(sign == -1,1,-1)]      [H: arcTangent = arcTangent + (sign * power(radians,i) / i)]   }]}][H: macro.return = arcTangent]``