Some extra math functions

About advanced scenes, and the Thyme scripting language used in Algodoo.

Some extra math functions

Postby link0007 » Thu Sep 10, 2009 8:35 am

Edit: (by tatt61880 on 2011.11.19 11:01)
Kilinich suggested below for KISS principle:
Code: Select all
scene.my.sign = (x) => {x < 0 ? -1 : 1};
scene.my.abs = (x) => {x > 0 ? x : -x};
(his post is in Optimization IS important)

Using simple function will optimize your thyme scripting.
I also suggest to use the definition above.

-Tatt
----


A collection from the math functions that were posted on phunland:

Code: Select all
scene.my.sign = (number) =>
{
    sign := 0;
    (number<0)?{sign=(-1)}:false;
    (number>0)?{sign=1}:false;
    sign;
};
scene.my.abs = (number) =>
{
    number*scene.my.sign(number);
};
scene.my.floor = (number) =>
{
    number >= 0 ? number - math.mod(number, 1) : (math.mod(number, 1) == 0 ? number : number - math.mod(number, 1) - 1);
};
scene.my.ceil = (number) =>
{
    fpart:=math.mod(number,1);
    ipart:=number-fpart;
    (number>0)?{ipart=(scene.my.abs(fpart)>0)?(ipart+1):ipart}:{ipart=(scene.my.abs(fpart)>0)?(ipart-1):ipart};     
    ipart;
};
scene.my.round = (number,precision) =>
{
    fpart:=math.mod(number,1);
    ipart:=number-fpart;
    roundfloat:=fpart*math.pow(10,precision);
    roundfloat = (scene.my.abs(math.mod(roundfloat,1))>=0.5)?{scene.my.ceil(roundfloat)}:{scene.my.floor(roundfloat)};
    roundfloat = roundfloat/math.pow(10,precision);
    answer:=ipart+roundfloat;
    answer;
};
scene.my.dist = (P1, P2) =>
{
     math.pow(math.pow(P2(0) - P1(0), 2) + math.pow(P2(1) - P1(1), 2), 0.5);
};
scene.my.max = (A, B) =>
{
     A >= B ? A : B;
};
scene.my.min = (A, B) =>
{
     A <= B ? A : B;
};
scene.my.PolarProjection = (Source, Distance, Angle) =>
{
    [Source(0) + Distance * Math.Cos(Angle), Source(1) + Distance * Math.Sin(Angle)];
};
scene.my.Deg2Rad = (Deg) =>
{
     Deg * Math.Pi / 180
};
scene.my.IsPointInCircle = (point, circleCenter, circleRadius) =>
{
     XX = point(0) - circleCenter(0);
     YY = Point(1) - circleCenter(1);
     XX * XX + YY * YY <= circleRadius* circleRadius;
};
scene.my.IsPointInTriangle = (trianglePoint1, trianglePoint2, trianglePoint3, point) => {
    A = (point(1) - trianglePoint1(1)) * (trianglePoint2(0) - trianglePoint1(0)) - (point(0) - trianglePoint1(0)) * (trianglePoint2(1) - trianglePoint1(1));
    B = (point(1) - trianglePoint3(1)) * (trianglePoint1(0) - trianglePoint3(0)) - (point(0) - trianglePoint3(0)) * (trianglePoint1(1) - trianglePoint2(1));
    C = (point(1) - trianglePoint2(1)) * (trianglePoint3(0) - trianglePoint2(0)) - (point(0) - trianglePoint2(0)) * (trianglePoint3(1) - trianglePoint3(1));
    (A * B > 0) && (B * C > 0);
};
Link: "Surely somebody hates Walter Cronkite.."
Sonic: "Probably.. But somebody hates everyone."
:D
User avatar
link0007
 
Posts: 408
Joined: Thu Jun 11, 2009 2:45 pm

Re: Some extra math functions

Postby Torpedo » Thu Sep 10, 2009 10:23 am

That scene.my.dist could come vastly in handy, I've tried a few times to make distance calculations in phun/algodoo but i swear using index powers doesn't work properly. (Pythagoras)

AHHHH I see what its doing now, so index powers are math.pow(number,index)

Right well i've been using ^ as thats what someone else told me your meant to do, and it doesn't work lol.
Image
User avatar
Torpedo
 
Posts: 120
Joined: Mon Aug 31, 2009 8:51 pm

Re: Some extra math functions

Postby gradyfitz » Thu Sep 10, 2009 11:17 am

Torpedo wrote:That scene.my.dist could come vastly in handy, I've tried a few times to make distance calculations in phun/algodoo but i swear using index powers doesn't work properly. (Pythagoras)

AHHHH I see what its doing now, so index powers are math.pow(number,index)

Right well i've been using ^ as thats what someone else told me your meant to do, and it doesn't work lol.

_^_ is an infixed operation of math.pow :D. How doesn't it work?

(a^2 + b^2)^0.5 should work, doesn't it? (It works for me).
Mechanisms: 18 Mechanisms.
Thyme: Tutorial - Variables/Commands List.
Thymechanic
gradyfitz
 
Posts: 174
Joined: Tue Sep 01, 2009 8:33 am
Location: Victoria, Australia

Re: Some extra math functions

Postby KarateBrot » Fri Sep 11, 2009 4:18 am

Of course ^ works. I use it without exception. But I wonder why it doesn't work for you sometimes... Are you sure the brackets always are in the right order?
Image
User avatar
KarateBrot
 
Posts: 825
Joined: Mon Aug 31, 2009 7:32 pm
Location: Germany

Re: Some extra math functions

Postby Torpedo » Fri Sep 11, 2009 2:52 pm

I find using ^ doesn't seem to give the right values. like if you use some integer value that has integer roots it doesn't make an integer number, or something miles too large i found. I have no idea why i was having trouble though. I'll make a scene soon using either function and try and work out what was happening.
Image
User avatar
Torpedo
 
Posts: 120
Joined: Mon Aug 31, 2009 8:51 pm

Re: Some extra math functions

Postby KarateBrot » Fri Sep 11, 2009 5:16 pm

Torpedo wrote:I find using ^ doesn't seem to give the right values. like if you use some integer value that has integer roots it doesn't make an integer number, or something miles too large i found. I have no idea why i was having trouble though. I'll make a scene soon using either function and try and work out what was happening.


okay. i'm very interested in what's wrong with it.
Image
User avatar
KarateBrot
 
Posts: 825
Joined: Mon Aug 31, 2009 7:32 pm
Location: Germany

Re: Some extra math functions

Postby Conundrumer » Thu Oct 01, 2009 5:42 pm

is there a function for logarithms?
User avatar
Conundrumer
 
Posts: 344
Joined: Mon Aug 31, 2009 5:55 pm
Location: NYC

Re: Some extra math functions

Postby KarateBrot » Thu Oct 01, 2009 5:46 pm

Conundrumer wrote:is there a function for logarithms?


if there isn't already a function i can make one.
Image
User avatar
KarateBrot
 
Posts: 825
Joined: Mon Aug 31, 2009 7:32 pm
Location: Germany

Re: Some extra math functions

Postby Conundrumer » Thu Oct 01, 2009 11:54 pm

KarateBrot wrote:
Conundrumer wrote:is there a function for logarithms?


if there isn't already a function i can make one.

I certainly can't find a log function
How would you make it?
User avatar
Conundrumer
 
Posts: 344
Joined: Mon Aug 31, 2009 5:55 pm
Location: NYC

Re: Some extra math functions

Postby KarateBrot » Tue Oct 06, 2009 2:39 pm

Conundrumer wrote:How would you make it?

i use a formula for ln(x) and with ln(x) algodoo can calculate every logarithm you want. I'm on it. i have a few problems with the thyme code but that should be no problem.
Image
User avatar
KarateBrot
 
Posts: 825
Joined: Mon Aug 31, 2009 7:32 pm
Location: Germany

Re: Some extra math functions

Postby Conundrumer » Tue Oct 06, 2009 5:40 pm

KarateBrot wrote:
Conundrumer wrote:How would you make it?

i use a formula for ln(x) and with ln(x) algodoo can calculate every logarithm you want. I'm on it. i have a few problems with the thyme code but that should be no problem.

Oh yea I forgot about the natural logarithm! Although it's a bit annoying to type in a quotient, it's still very useful. I guess a general log function would be even better.
User avatar
Conundrumer
 
Posts: 344
Joined: Mon Aug 31, 2009 5:55 pm
Location: NYC

Re: Some extra math functions

Postby KarateBrot » Tue Oct 06, 2009 6:31 pm

yes i make a general log function for every logarithm you want. it looks like "scene.my.log(a,b)" and a is the basis

[Edit]
How can I delete this post? I thought there was an option for it :|
Last edited by KarateBrot on Fri Oct 09, 2009 8:13 pm, edited 1 time in total.
Image
User avatar
KarateBrot
 
Posts: 825
Joined: Mon Aug 31, 2009 7:32 pm
Location: Germany

Re: Some extra math functions

Postby KarateBrot » Fri Oct 09, 2009 8:12 pm

Ok now I did it. A function for ln and a function for the general log which is based on ln. But because you can't calculate limits with thyme it's not exactly ln but nevertheless it's relatively precise.

Natural logarithm (ln)
Code: Select all
scene.my.ln = (x) => { (x^0.001 - 1) / 0.001 }

Example: e^x = 5
scene.my.ln(5) = 1.6107558

- - - - -

General logarithm (log)
Code: Select all
scene.my.log = (a,b) => { (b^0.001 - 1) / (a^0.001 - 1) }

Example: 3^x = 18
scene.my.log(3,18) = 2.6332285

- - - - -

Deviation from real ln
I calculated the deviation from the real ln and it's not much. Only a deviation of 0% (x = 1) to 0.11% (x = 10) and even for big x values (for example x = 1000) it's only about 0.4%.

Image
I really would like to make an even more precise function but it doesn't seem to be possible until now with thyme. But maybe I get ideas to make it a bit more precise.



- - - - -


Improved code
I made an algorithm for ln(x) that decomposes x if its value is smaller than 1 or bigger than 10 and with some basic logarithm rules the logarithm can be calculated with much(!!!) more precision.
For example if I want to calculate ln(12000), 12000 will be decomposed to 1.2*10^4 and 4*ln(10) + ln(1.2) will be calculated instead, which is the same as ln(12000) but it's much more precise.

Additional note
The new algorithm is slow compared to the old simple algorithm which is already very precise. If you want to calculate multiple logarithms at every simulation step rather choose the old algorithm. If you only want to calculate logarithms at specific points in time you can choose the new one.
You have to choose between incredibly precise calculations and fast calculations.


Natural logarithm (ln)
Code: Select all
scene.my.ln = (x) => {y := x; n := 0; y < 1 ? { for(10,(i)=>{ y < 1 ? {y = 10*y; n = n-1} : {} }) } : { y > 10 ? { for(10,(i)=>{ y > 10 ? {y = 0.1*y; n = n+1} : {} }) } : {} }; n*2.302585092994 + (y^0.0001 - 1) / 0.0001 }

Example: e^x = 5
scene.my.ln(5) = 1.6093254

- - - - -

General logarithm (log)
Code: Select all
scene.my.ln = (x) => {y := x; n := 0; y < 1 ? { for(10,(i)=>{ y < 1 ? {y = 10*y; n = n-1} : {} }) } : { y > 10 ? { for(10,(i)=>{ y > 10 ? {y = 0.1*y; n = n+1} : {} }) } : {} }; n*2.302585092994 + (y^0.0001 - 1) / 0.0001 };

scene.my.log = (a,b) => { scene.my.ln(b) / scene.my.ln(a) }

Example: 3^x = 18
scene.my.log(3,18) = 2.629662
Last edited by KarateBrot on Sat Apr 24, 2010 12:15 pm, edited 2 times in total.
Image
User avatar
KarateBrot
 
Posts: 825
Joined: Mon Aug 31, 2009 7:32 pm
Location: Germany

Re: Some extra math functions

Postby standardtoaster » Mon Oct 12, 2009 7:38 pm

Here's a functional atan2.

Code: Select all
Scene.my.atan2=(P)=>{2 * math.atan(P(1) / (((P(0) ^ 2 + P(1) ^ 2) ^ 0.5) + P(0)))}

atan2 returns the angle in radians between the point [0, 0] and the point that you feed it.

Here's a functional rad2deg function. Returns any angle between 0° and 359.9° from radians.

Code: Select all
Scene.my.rad2deg=(n)=>{n < 0 ? {(((math.toFloat(n) * math.toFloat(180)) / math.pi) + 360)} : {((math.toFloat(n) * math.toFloat(180)) / math.pi)}}


Give it the radian value and it will convert it to degrees.

You can use atan2 and rad2deg to create simple mouse control. :thumbup:

Either using motors:
Rating: rated 5.6
Filesize: 78.59 kB
Comments: 4
Ratings: 2
download

Using a motor as the form of movement is a bit slower than using springs.

Or you can use springs:
Rating: rated 5.1
Filesize: 77.08 kB
Comments: 1
Ratings: 3
download
User avatar
standardtoaster
 
Posts: 606
Joined: Mon Aug 31, 2009 7:57 pm

Re: Some extra math functions

Postby KarateBrot » Mon Oct 12, 2009 9:46 pm

The rad2deg function is not completely correct. It's not a general rad2deg function because with it you only get 50% of every possible solution. Because you could also for example have -Pi/2 rad and it must be -90° as a result. That's equal to 3*Pi/2 and 270° and with your function with -Pi/2 you get 270° but for every value there are two solutions depending on which direction you choose (if you go clockwise or counter clockwise) so the function is more simple:

Code: Select all
scene.my.rad2deg = (n) => { n * 180/math.pi }

(As far as I know math.toFloat is not necessary here because math.pi is already float)

Because of atan2 you have to extend this function to the one you posted above if you go counter clockwise, that's right.

For angles I like acos better than atan2 because at Pi rad it's not changing its value from Pi to -Pi but that's not too important. Just my opinion :D
Image
User avatar
KarateBrot
 
Posts: 825
Joined: Mon Aug 31, 2009 7:32 pm
Location: Germany

Re: Some extra math functions

Postby standardtoaster » Mon Oct 12, 2009 10:23 pm

How would you calculate the angle with acos?
User avatar
standardtoaster
 
Posts: 606
Joined: Mon Aug 31, 2009 7:57 pm

Re: Some extra math functions

Postby KarateBrot » Mon Oct 12, 2009 11:32 pm

acos( x / √(x² + y²) )

In Thyme it would be
Code: Select all
scene.my.acos = (P1,P2) => { math.acos( (P2(0) - P1(0)) / ((P2(0) - P1(0))^2 + (P2(1) - P1(1))^2)^0.5 ) }


It will return angles from 0 to Pi and then back to 0 (0, Pi/2 Pi, Pi/2, 0). That's not what we want because you can't differ values from 0 to Pi and values from Pi to 2*Pi so we extend it a bit.
We want the values on the lower half of the unit circle go up and not go down so we need the condition if y < 0 then the acos will be subtracted from 2*Pi. If y >= 0 nothing should happen.
Code: Select all
scene.my.angle = (P1,P2) => { (P2(1) - P1(1)) < 0 ? { 2*math.pi - scene.my.acos(P1,P2) } : { scene.my.acos(P1,P2) } }


Now you get values from 0 to 2*Pi (0, Pi/2, Pi, 3*Pi/2, 2*Pi). Now for a pointer you could still go a step further so theres no gap between 2*Pi and 0 (because if you are at 2*Pi it will jump back to 0 and the pointer will turn full 360° into the other direction). If you want I can show the next step to prevent the pointer from turning 360°.
Image
User avatar
KarateBrot
 
Posts: 825
Joined: Mon Aug 31, 2009 7:32 pm
Location: Germany

Re: Some extra math functions

Postby standardtoaster » Tue Oct 13, 2009 2:42 am

Updated the atan2! You can now feed it two points and it will calculate the angle in radians between those points.

Code: Select all
Scene.my.atan2=(P1, P2)=>{2 * math.atan((P2(1)-P1(1)) / (((((P2(0)-P1(0))^2) + (P2(1)-P1(1))^2) ^ 0.5) + (P2(0)-P1(0))))}


I have also updated the scenes!

Motor:
Rating: rated 5.6
Filesize: 78.59 kB
Comments: 4
Ratings: 2
download


Spring(still can't go full 360° but it has the capability to!):
Rating: rated 5.1
Filesize: 77.08 kB
Comments: 1
Ratings: 3
download
User avatar
standardtoaster
 
Posts: 606
Joined: Mon Aug 31, 2009 7:57 pm

Re: Some extra math functions

Postby standardtoaster » Mon Oct 19, 2009 5:07 am

Made a new function! It may not be very useful but it can slim down some code.

Code: Select all
Scene.my.IsMouseInBox=(P1, P2, CIT, CIF) =>{App.mousePos(0) >= P1(0) && App.mousePos(1) <= P1(1) && App.mousePos(0) <= P2(0) && App.mousePos(1) >= P2(1) ? {CIT} : {CIF}}


This script will be able to tell if the mouse is in a box and adjust the color of it accordingly.

P1 stands for the first point you give it.
P2 stands for the second point you give it.
CIT stands for Color If True
CIF stands for Color If False

Ex. scene.my.IsMouseInBox([-1,1], [1,-1], [1,1,1,1], [0,0,0,1]) Put that into a box that is at [0,0] and has a size of 2x2. This will make it change to white if the mouse is in the box and make it change to black if the mouse is not in the box.
User avatar
standardtoaster
 
Posts: 606
Joined: Mon Aug 31, 2009 7:57 pm

Re: Some extra math functions

Postby KarateBrot » Sun Oct 25, 2009 8:54 am

Color spectrum function

I made a function to change the color of an object depending on one variable. The variable can be between 0 and 300. It's comfortable if you want to smoothly change a color from one to another, going through the color spectrum.

Image

Code: Select all
scene.my.color = (c) => { x := math.tofloat(c); math.or(x > 300, x < 0) ? {print ("c = " + x + "   ~~>   Invalid value! Choose a value between 0 and 300")} : {x >= 250 ? {[1, 0, -(x - 250) / 50 + 1, 1]} : {x >= 200 ? {[(x - 200) / 50, 0, 1, 1]} : {x >= 150 ? {[0, -(x - 150) / 50 + 1, 1, 1]} : {x >= 100 ? {[0, 1, (x - 100) / 50, 1]} : {x >= 50 ? {[-(x - 50) / 50 + 1, 1, 0, 1]} : {x >= 0 ? {[1, x / 50, 0, 1]} : {}}}}}}} }
Image
User avatar
KarateBrot
 
Posts: 825
Joined: Mon Aug 31, 2009 7:32 pm
Location: Germany

Re: Some extra math functions

Postby immibis » Sun Oct 25, 2009 11:53 pm

This isn't exactly math-related but I have a better for-loop that can loop more than 40 times (but it's slow for large numbers)
Code: Select all
Scene.my.for2_internal = (n, min, max, what) => {
   (min == max) ? {
      (min < n) ? {
         what(min)
      } : {}
   } : {
      Scene.my.for2_internal(n, min, min + (max - min + 1) / 2 - 1, what);
      Scene.my.for2_internal(n, min + (max - min + 1) / 2, max, what)
   }
};
Scene.my.for2 = (n, what) => {
   num := Math.toFloat(Math.toInt(n));
   max := 2^(Math.toInt(((num^0.001 - 1) / (2^0.001 - 1)) + 1));
   (num <= 0) ? {} : {
      (num == 1) ? {
         what(0)
      } : {
         Scene.my.for2_internal(num, 0, (max/2)-1, what);
         Scene.my.for2_internal(num, (max/2), max-1, what)
      }
   };
};
Thymechanic
immibis
 
Posts: 87
Joined: Wed Sep 30, 2009 12:24 am

Re: Some extra math functions

Postby standardtoaster » Sat Oct 31, 2009 3:50 am

Phun users can now use math.toBool, math.toFloat, math.toSting, and math.toInt(to an extent)!

Code: Select all
scene.my.toBool=(N)=>{N == 0 ? false : true}
//returns true or false

Code: Select all
scene.my.toFloat=(N)=>{N + 0.0}
//returns the given number as a float

Code: Select all
scene.my.toString=(N)=>{N + ""}
//returns the given value, N, as a string

Code: Select all
Scene.my.toInt=(N)=>{N - math.mod(N, 1)}
//returns the given number as an integer
//i.e. 10.6(float) scene.my.toInt(10.6) = 10(Integer)
//!! Does not return an integer if given a boolean. Using the built in math.toInt in Algodoo it will.
User avatar
standardtoaster
 
Posts: 606
Joined: Mon Aug 31, 2009 7:57 pm

Re: Some extra math functions

Postby KarateBrot » Sat Oct 31, 2009 7:11 pm

Iteration (Newton–Raphson method)

Code: Select all
scene.my.NewRap = (f, df, x) =>
{
   z := math.tofloat(x);
   for(45,(i)=>{ z = z - f(z) / df(z)  })
}



Scene.my.NewRap(f, df, x)
f: Function
df: Derivation of the function
x: initial value


Example:

1)
We want to calculate the root of the function f(x) = cos(x) - x which can't be solved with basic methods.
The derivation of this function is f'(x) = -sin(x) - 1
We also need a proper initial value for our calculation, for example 2

2)
In the console we type:
scene.my.NewRap( (x)=>{math.cos(x)-x}, (x)=>{-math.sin(x)-1}, 2 )

3)
The solution will be 0.73908514 which is our root


- - - - -


Improved code
Now there's no more need of the derivation to calculate the root.

Code: Select all
Scene.my.derive = (f, x) => { ( f(x+0.001) - f(x) ) / 0.001 };

scene.my.NewRap = (f, x) =>
{
   z := math.tofloat(x);
   for(45,(i)=>{ z = z - f(z) / scene.my.derive(f, z)  })
}


Scene.my.NewRap(f, x)
f: Function
x: initial value


Example:

1)
Again, we want to calculate the root of the function f(x) = cos(x) - x . We just need a proper initial value for our calculation, for example 2. No need to derive the function.

2)
In the console we type:
scene.my.NewRap( (x)=>{math.cos(x)-x}, 2 )

3)
Like above the solution for the root will be 0.73908514 but it's way more simple and dynamic.
Last edited by KarateBrot on Wed Dec 02, 2009 8:59 pm, edited 3 times in total.
Image
User avatar
KarateBrot
 
Posts: 825
Joined: Mon Aug 31, 2009 7:32 pm
Location: Germany

Re: Some extra math functions

Postby KarateBrot » Thu Nov 05, 2009 11:13 pm

Gradient of a function

Code: Select all
Scene.my.derive = (f, x) => { ( f(x+0.001) - f(x) ) / 0.001 }


Example: You want to know the gradient of f(x) = x² +3x -1 for x = 2
Scene.my.derive( (x)=>{x^2+3*x-1}, 2 ) = 6.999969

The correct solution would be 7. It's very precise.
Last edited by KarateBrot on Wed Dec 02, 2009 9:01 pm, edited 1 time in total.
Image
User avatar
KarateBrot
 
Posts: 825
Joined: Mon Aug 31, 2009 7:32 pm
Location: Germany

Re: Some extra math functions

Postby Ivanlul » Sat Nov 07, 2009 5:14 am

I need help doing inverse trig fuctions(arcsin, arccos, arctan)
Registered: 2008-10-16
Image
User avatar
Ivanlul
 
Posts: 763
Joined: Mon Aug 31, 2009 11:19 pm
Location: US

Next

Return to Thyme scripting

Who is online

Users browsing this forum: No registered users and 1 guest

cron