# Math for the Algebraically Challenged (Read 11931 times)

Started by Bronko, November 20, 2005, 04:19:10 PM

#### Bronko

##### Math for the Algebraically Challenged
#1  November 20, 2005, 04:19:10 PM
• Just a butcher on a mission.
Okay I'm starting this thread as a "demonstration" of math operations to help total newbs manipulate variables in mugen.  In this case, time is the only variable.  I will post some of the basics and everyone else can add on to it. (I have supplied pictures for this tutorial, if you do not provide one I can make it for you.)

To start, here we have a set of Axes.  The origin is at the left-center, 0,0.

For all extents and purposes, we will assume the X axis represents Time.  Throughout this demonstration we will be manipulating time, which is why the graph does not include negative numbers in the X direction.
First we have constants. Constants are just unchanging numbers, like 10 and 20.  Here we have Y= 0, Y=10, and Y = 20

Notice they do not change due to time.  This is because time is not included in the expression.  However if we plotted Y = Time

You can see that Time is equal to itself, for obvious reasons.  We can shift this plot in many ways such as the four basic operations, addition,subtraction,multiplication, and division.

Using addition, you can set where the graph starts from, useful for possibly an attack that increases in damage the longer you charge it (Charging it for 0 time will still produce some damage)
Using multiplication or division, you can make that same attack charge faster or slower without having to change the laws of physics and cause time to go faster or slower.
Now we get more complicated.  Suppose the attack mentioned earlier was charging too slowly for you, but time*1000 is way too broken.  You can use an exponent for this.

Time^2 is just another notation for Time*Time. The bigger the exponent, the faster the graph curves upward.  And just as the inverse of multiplication is division, the inverse of an exponent is a logarithm.

I think you get the idea.
However by far the most useful operation is the modulus.  Modulus is like division, but instead returns the remainder of the operation, not the quotient.

I have also graphed y=10 to show that the graph never goes to ten, because the remainder of any multiple of ten divided by ten is always zero.  This is great for times when you want to do something every X ticks.  Lastly, we have trigonometric functions.  For now I will only demonstrate the sine curve.

This is a bit complicated, so I'll go into detail about the expression first.
20*sin((pi/12)*time)
Normally a sin function goes from 1 to -1, so I multiplied it by 20 to make the range 20 to -20.  Then on the inside, I multiplied time by PI and then divided by twelve.  The period (or how long it takes for the sine curve to repeat) is usually 2*PI, which is around 6.28, not a very clean number if you ask me.  The period of my equation is 24, so it repeats whenever time is a multiple of 24.  Why?  Because 2*PI/(PI/12) = 24 If I multiplied time by PI/6 instead, my period would be 2*PI/(PI/6) = 12  You can use the sin curve for all kinds of things, but it's main usage comes from palette effects, such getting hit by fire.  The player should gradually go from normal to red and back again.

If any of this is too confusing/could be explained better let me know.
One last note: In mugen, it doesn't hurt to add .0 to every number to make sure mugen doesn't truncate anything (cut off the decimals).
Last Edit: November 25, 2009, 03:38:20 PM by Insanius

#### Renzo F

##### Re: Math for the Algebraically Challenged
#2  November 21, 2005, 01:10:45 AM
...and it doesn't hurt to truncate an expression with ceil() or floor() to avoid that nice debug warning messages...

Nice tutorial. Basic stuff that any creator should know (and should learnt at school).

#### 外音リザ

##### Re: Math for the Algebraically Challenged
#3  November 21, 2005, 08:11:12 AM
• 君の事、マスターにしてあげる! 御願い、信じてマスター！♥
To save on SFF space and added flexibility, any explod that revolves or moves around the character should be programmed with algebraic expressions instead of absolute positioning from sprites.
Orochi Herman: MUGEN Creator, Producer and Web Programmer

#### Foxphoenix

##### Re: Math for the Algebraically Challenged
#4  November 21, 2005, 02:19:37 PM
• I love this pic XD
Quote
(and should learnt at school).

This was too advanced for a puertorican school at my age so I could never learn most of this stuff.

#### ????

##### Re: Math for the Algebraically Challenged
#5  November 22, 2005, 01:22:52 AM
FEh.. too easy...

sup Mugen coding class 101
Goodbye V V

#### Foxphoenix

##### Re: Math for the Algebraically Challenged
#6  November 22, 2005, 11:57:58 AM
• I love this pic XD
FEh.. too easy...

sup Mugen coding class 101

Well. It's stated in the topic title. "Math for the Algebraically Challenged" Not everyone could learn this stuff or is good enough for it. And I apply for both things

@Jazzy. If you have more stuff to add here. I'm all ears ...errr eyes!
Last Edit: November 22, 2005, 11:59:38 AM by Foxphoenix

#### Parker

##### Re: Math for the Algebraically Challenged
#7  November 22, 2005, 06:56:42 PM
• What?
It was good if somebody translate the tutorial to spanish...

#### Chosen_01

##### Re: Math for the Algebraically Challenged
#8  November 25, 2005, 10:19:44 PM
• Now your gonna feel my hooks! OH YEAH!!
Meh. You lost me at "20*sin((pi/12)*time)" Was never a math wiz. If I could learn this it would be a friggin miricle.

#### Mário Fong

##### Re: Math for the Algebraically Challenged
#9  November 25, 2005, 11:00:34 PM
• Vans Worshipper
• Ø
it means "20 multiplified by sin[that cool and useless thing that you learn in the 8th grade]((pi divided by 12)* teh time)" what's so hard???
Last Edit: November 25, 2005, 11:05:39 PM by Knuckle Sandwiches

#### Cybaster

##### Re: Math for the Algebraically Challenged
#10  November 29, 2005, 03:21:59 PM
• Limited time to use Infinite power !
What's so hard is that not everybody is good at maths or had the chance to be able to learn this at school.

And, understanding the formula as you did isn't the most complicated part. The complicated part is to understand what it's meant for, and what effect or purpose it will finally give.

#### ????

##### Re: Math for the Algebraically Challenged
#11  December 14, 2005, 08:52:28 AM
ARe these for how the way the character moves in mugen?

I would like to know..
Goodbye V V

#### Byakko

##### Re: Math for the Algebraically Challenged
#12  December 14, 2005, 12:46:59 PM
That's for anything mathematical. If you want to give a mathematical move to your char (a sinusoidal projectile for example), you have that.
If I struggled to the end of my determination, to the end of my way of life with my followers, if the result is ruin, then this ruin is inevitable. Grieve. Shed tears. But you cannot regret.

#### Mr. Sand

##### Re: Math for the Algebraically Challenged
#13  September 22, 2007, 06:50:00 AM

#### Renzo F

##### Re: Math for the Algebraically Challenged
#14  September 22, 2007, 06:56:11 AM
Take Strider Hiryu's Uroboros as an example.
In that move, two projectiles move around Hiryu. Instead of adding a lot of sprites with the projectiles positioned in different angles, you can just use some math and one sprite.

The first Hiryu I downloaded was programmed not using math, and the Uroboros looked and played like crap

#### #Shaun

##### Re: Math for the Algebraically Challenged
#15  September 22, 2007, 04:30:34 PM
• corner push pusher
#Shaun never took trig.
#Shaun never took calculus
#Shaun barely passed Algebra.

After finding this topic, #Shaun will now have a better understanding of what type = projectile, trigger = time % 60, offset = 10 + ( floor(time/60) * 20 ), 0 means. Thanks!

#### conicteam

##### Re: Math for the Algebraically Challenged
#16  October 17, 2007, 11:42:23 PM
I did not learn this stuff yet

#### ultimatedude

##### Re: Math for the Algebraically Challenged
#17  October 29, 2007, 05:50:47 PM

No Borders, No Nations

#### Ryanide

##### Re: Math for the Algebraically Challenged
#18  November 09, 2007, 08:54:00 AM
• It's not furry you goons, it's anthro! ANTHRO!
I'm still having trouble understanding this. I'm a visual learner, so could you maybe give some examples of these in actual Mugen code? I'm interested in learning this so I can make my characters main projectiles (floating fire) move at angles and sines without having to rely on sprite positioning.
A magical force-field surrounding a brick in an iron vault...even if the security is breached, the thieves are bound to be disappointed.

#### DMK

##### Re: Math for the Algebraically Challenged
#19  November 09, 2007, 10:01:35 AM
• 141⅔% chance of winning
Lol, I remember reading this and wondering what in the flying fuck you were going on about.

Now that I know what the axis and all that stands for it's like looking at a small tutorial.

#### Bronko

##### Re: Math for the Algebraically Challenged
#20  November 09, 2007, 03:44:36 PM
• Just a butcher on a mission.
Given the amount of interest, I will be expanding this further in the near future.

I'm a visual learner, so could you maybe give some examples of these in actual Mugen code?

#### FrozenDelight

##### Re: Math for the Algebraically Challenged
#21  November 22, 2009, 05:54:50 PM
• Why can't I upload a Profile Pic?!

#### Bronko

##### Re: Math for the Algebraically Challenged
#22  November 25, 2009, 03:29:47 PM
• Just a butcher on a mission.
For now I'm going to see if I can find the images again and re-upload.

#### Seravy

##### Re: Math for the Algebraically Challenged
#23  October 21, 2011, 01:17:24 AM
There is a mistake around here :
Quote
Time^2 is just another notation for Time*Time. The bigger the exponent, the faster the graph curves upward.  And just as the inverse of multiplication is division, the inverse of an exponent is a logarithm.
Logarithm base 2 would be the inverse of 2^Time, not Time^2.
Time^2 is the square of Time, and the inverse of that is Square Root, so the graph below is Sqrt(time) and not log(2,time).

For comparison,
log(2,64)=6 (because 2^6=2*2*2*2*2*2=64)
log(2,1024)=10  (because 2^10=2*2*2*2*2*2*2*2*2*2=1024)
log(2,65536)=16 (because 2^16=65536)
sqrt(64)=8 (because 8^2=8*8=64)
sqrt(1024)=32. (because 32^2=32*32=1024)
sqrt(65536)=256. (because 256^2=256*256=65536)

As you can see, logarithm grows a lot slower than square root does.
Other than that, nice guide, math is indeed often useful when coding things in Mugen, and there are way too many people not using it.

#### Bronko

##### Re: Math for the Algebraically Challenged
#24  March 08, 2012, 09:27:32 PM
• Just a butcher on a mission.
I've neglected this thread for far too long and it could really use a bit of a rewrite.  Thanks for catching that Seravy I don't know what I was thinking when I wrote that section.
Anyways I've written up a fairly detailed explanation of common trigonometric functions, hopefully there's one person who won't tl;dr it.

If you want to understand how sine, cosine, and tangent work you need to understand a few fundamental things about circles and triangles.

Consider a whole circle.  The circumference is PI * 2 * radius.  For the sake of this explanation we will use what is a called a unit circle, which is a circle with radius 1
Which means our circumference is simply PI * 2.  We also have a unit of angle measurements called radians, which are simply relating angles to the length of an arc on our unit circle.  That is to say 360 degrees (a full circle) is equal to 2*PI radians.
In mugen, sin, cos, and tan use radians as parameters, not degrees.  Therefore, before you do any calculation you must remember to use the correct conversion.

What are sin, cos, and tan?
These are ratios of the sides of a right triangle.  As long as we know the angles of a triangle, and one angle on that triangle is 90 degrees (PI/2 radians) we can know for certain the ratios of the lengths of all three sides of the triangle.
For example, if we have a triangle with two angles of 45 degrees and one angle of 90 degrees (your Geometry teacher will call this a 45/45/90 triangle) then the two sides near the right angle will be X and the hypotenuse will be of length X * square root of 2.  It doesn't matter how big the triangle is, those ratios will be constant as long as the angles don't change.
So how are these ratios defined?

Most people in school will learn SOHCAHTOA
Say it repeatedly until you remember it.

SOH = Sine,  Opposite over Hypotenuse
CAH = Cosine, Adjacent over Hypotenuse
TOA = Tangent, Opposite over Adjacent

Naturally in a right triangle, the hypotenuse refers to the side directly opposite of the right angle.  So in our 45/45/90 example, we can take the sine of one of the 45 degree angles, and that'll give us 1/sqrt(2)
Plug in sin(45) in a calculator and you'll get that answer.

If you know the lengths of a right triangle, but you don't know the other two angles, you can use inverse trigonometry and input your ratio in order to get the angle, asin, acos, and atan.

I still don't get it.
If you want to imagine sin and cos graphically, imagine the unit circle in your head.  You know, the circle with radius 1.  Now imagine that circle is on a graph, with the center at 0,0.  That means that 0 degrees on the circle (furthest right) is at point 1,0
If you want to know the position of any point in the circle, the X coordinate is cos and the Y coordinate is sin.  So sin(0) is 0 and cos(0) is 1.  At the top of the circle, 90 degrees, the circle is at 0,1.  So sin(90) = 1 and cos(90) = 0.  Looking at it this way, you can observe a few interesting things about sin and cos

- Because the unit circle only has a radius of 1, sin and cos will only go from -1 to 1
- sin and cos repeat themselves after going a full 360 degrees (2*PI) this is also called the period of the function.
- cosine is just a sine that's been shifted by 90 degrees (PI / 2)

`[State 3150, Fulcrum] ; Spawn the center of our "circle"type = Helpertrigger1 = anim = 3150trigger1 = animelemno(0) = 2name = "Fulcrum"ID = 3150pos = 250, -400stateno = 3151ownpal = 1persistent = 0[State 3150, Arm] ; The arm is a seperate object from the bodytype = Helpertrigger1 = anim = 3150trigger1 = animelemno(0) = 2name = "Arm"ID = 3151pos = 0,-120stateno = 3152ownpal = 0persistent = 0[State 3150, Wire] ; The string that shoots out is also its own objecttype = Helpertrigger1 = anim = 3150trigger1 = animelemno(0) = 2name = "Wire"ID = 3152pos = 0,-120stateno = 3153ownpal = 0persistent = 0[State 3150, Clone] ; The body we see is actually a helper, the real character will be invisibletype = Helpertrigger1 = anim = 3151trigger1 = animelemno(0) = 2name = "Clone"ID = 3154pos = 0,0stateno = 3155ownpal = 0persistent = 0[State 3150, Blade] ; The part that attacks just spins around on its own.type = Helpertrigger1 = anim = 3151trigger1 = animelemno(0) = 2name = "Blade"ID = 3153pos = 0,-120stateno = 3154ownpal = 0persistent = 0[State 3150, Distance Calculate] ; Here we use the pythagorean theorem to find the initial distance between the character and the fulcrumtype = varsettrigger1 = anim = 3151trigger1 = animelemno(0) = 2fvar(0) = (((helper(3150), Pos Y)-(Pos Y-120))**2 + ((helper(3150), Pos X)-(Pos X))**2)**.5persistent = 0[State 3150, Angle Calculate] ; Calculate the angle of the character relative to the fulcrum.  Remember it slows down near the ends.type = varsettrigger1 = anim = 3151fvar(1) = -1* sin((time+12)*pi/70.0)[State 3150, Position Set] ; Here's where we actually figure out where the character needs to betype = possettrigger1 = anim = 3151trigger1 = animelemno(0) >= 2x = (helper(3150), Pos X) + facing*fvar(0)*cos(fvar(1)*pi/2 - pi/2)y = (helper(3150), Pos Y) - fvar(0)*sin(fvar(1)*pi/2 - pi/2) + 120[State 3150, Invisible]type = assertspecialtrigger1 = anim = 3151trigger1 = animelemno(0) >= 2flag = invisible[State 3150, Screenbound]type = Screenboundtrigger1 = anim = 3151trigger1 = animelemno(0) >= 2value = 0movecamera = 0,1[State 3150, End]type = ChangeStatetrigger1 = time = 90+140*var(5)trigger2 = anim = 3151trigger2 = animelemno(0) >= 2trigger2 = command = "a"value = 50ctrl = 1;Arm[Statedef 3152]type = Aphysics = Nmovetype = Ictrl = 0anim = 3152[State 3152, Screenbound]type = Screenboundtrigger1 = 1value = 0movecamera = 0,0[State 3152, Bind] ; Attach the arm to the bodytype = BindToParenttrigger1 = 1time = 1pos = 0,-120[State 3152, AngleSet] ; Remember where we attached the arm, set the angle based on that.type = AngleSettrigger1 = ((helper(3150), Pos X)-Pos X) != 0value = -1* facing * 180.0*atan(((helper(3150), Pos Y)-Pos Y)/((helper(3150), Pos X)-Pos X))/pi[State 3152, Flip] ; We have to make a correction here depending on if we're on the left or right side of the swing.type = AngleAddtrigger1 = ((helper(3150), Pos X)-Pos X) < 0value = 180[State 3152, Flip Again] ; We have to make a correction here if we're facing left or right.type = AngleAddtrigger1 = facing < 0value = 180[State 3152, AngleSet]type = AngleSettrigger1 = ((helper(3150), Pos X)-Pos X) = 0value = 90[State 3152, AngleDraw]type = AngleDrawtrigger1 = 1[State 3152, Destroy]type = destroyselftriggerall = IsHelpertrigger1 = Root, Stateno != 3150;Wire[Statedef 3153]type = Aphysics = Nmovetype = Ictrl = 0anim = 3154[State 3153, Screenbound]type = Screenboundtrigger1 = 1value = 0movecamera = 0,0[State 3153, Extend]type = varsettrigger1 = time < 7fvar(0) = time/6.0[State 3153, Bind]type = BindToParenttrigger1 = 1time = 1pos = 0,-120[State 3153, AngleSet] ; This code is the same as the armtype = AngleSettrigger1 = ((helper(3150), Pos X)-Pos X) != 0value = -1 * facing * 180.0*atan(1.0*((helper(3150), Pos Y)-Pos Y)/((helper(3150), Pos X)-Pos X))/pi[State 3153, Flip]type = AngleAddtrigger1 = ((helper(3150), Pos X)-Pos X) < 0value = 180[State 3153, Flip Again]type = AngleAddtrigger1 = facing < 0value = 180[State 3153, AngleSet]type = AngleSettrigger1 = ((helper(3150), Pos X)-Pos X) = 0value = 90[State 3153, AngleDraw]type = AngleDrawtrigger1 = 1scale = 4.2*fvar(0),1[State 3153, Destroy]type = destroyselftriggerall = IsHelpertrigger1 = Root, Stateno != 3150;Blade[Statedef 3154]type = Aphysics = Nmovetype = Ictrl = 0anim = 3155sprpriority = 3[State 3154, Screenbound]type = Screenboundtrigger1 = 1value = 0movecamera = 0,0[State 3154, Bind]type = BindToParenttrigger1 = 1time = 1pos = 0,-120[State 3154, AngleSet] ; This blade just spins on its own, but it has a precise timing to it.  It spins once completely every 32 frames.type = AngleSettrigger1 = 1value = -time*45.0/4.0[State 3154, AngleDraw]type = AngleDrawtrigger1 = 1[State 3154, Destroy]type = destroyselftriggerall = IsHelpertrigger1 = Root, Stateno != 3150;Clone[Statedef 3155] ; This is the body we see.  on the back swing it just hangs upright, but at the front it starts angling backwards.type = Aphysics = Nmovetype = Ictrl = 0anim = 3156sprpriority = 2[State 3155, Screenbound]type = Screenboundtrigger1 = 1value = 0movecamera = 0,0[State 3155, Bind]type = BindToParenttrigger1 = 1time = 1pos = 0,0[State 3155, Angle Calculate] ; Find the angle, same code as the main bodytype = varsettrigger1 = 1fvar(1) = -1* sin((time+52)*pi/70.0)[State 3155, AngleSet] ; Find the angle, slightly different code because the axis is off by 120type = varsettrigger1 = 1fvar(2) = -1 * facing * 180.0*atan(((helper(3150), Pos Y)-(Pos Y-120))/((helper(3150), Pos X)-Pos X))/pi + 90[State 3155, Offset] ; Make a position correction based on the angle, since the axis is wrong this is actually complicated.type = offsettrigger1 = cos(fvar(1)*pi/2 - pi/2) > .01x = facing*120*cos(fvar(2)*pi/180.0-pi/2.0)y = -120*sin(fvar(2)*pi/180.0) + 48*sin(fvar(2)*pi/90.0)[State 3155, Angle] ; Set the angle, but only at the front of our swing.type = AngleSettrigger1 = cos(fvar(1)*pi/2 - pi/2) > .01value = fvar(2)[State 3155, Angle]type = AngleDrawtrigger1 = cos(fvar(1)*pi/2 - pi/2) > .01[State 3155, Destroy]type = destroyselftriggerall = IsHelpertrigger1 = Root, Stateno != 3150`