zig zag boom (clone) math question

Hi,

I’m trying to understand the following pieces of code:

x = centerX + (length/2) / sqrt2 y = centerY + (length/2) / sqrt2 function math2do.angle2VectorFast( angle ) local screenAngle = mRad(-(angle + 90)) local x = mCos(screenAngle) local y = mSin(screenAngle) return -x,y end

What does that (length/2) / sqrt2 do? and why do we have to add 90 degree to the angle?

I’m really stuck with the math, could you please help to explain?

Thanks,

Lin

It’s a math trick for calculating half the width of an isosceles triangle base (with angles of 45-degrees).

Look at the triangle here: http://mathworld.wolfram.com/IsoscelesTriangle.html

The two sides of the triangle ‘b’ are the same length (in our game we treat the sides of our hall like one side of a triangle).  

If you know b (which we do in the game [length]), we can calculate half the length of ‘a’, by doing this:

a = (b/2) / math.sqrt(2)

We need to do this in the game, because our walls are at 45 degree angles and flip on each turn.  This trick lets us easily calculate the width of the hall (or how far to move the sides from a center point.

Hi Ed,

Thanks for you explanation. I still don’t understand it and can’t find the formula in the link. You said “we treat the sides of our hall like one side of a triangle,” is it after or before the rotation? and where the base should be? It would be helpful if you could draw the said triangle in the game then I’ll try to figure out more on my own.

Thanks,

Lin

Hi Ed,

Does that /math.sqrt(2) apply to all angles? It seems to me that it only work(do the trick) with 45 degree angle.

I still don’t understand the math you use so I write the following. By treating the wall segment as radius and knowing the angle, I can find the x and y for the next wall segment. Still need to tweak a lot more.

local fullw = display.contentWidth local fullh = display.contentHeight local centerX = display.contentCenterX local centerY = display.contentCenterY local angle = 45 local lastAngle local tailX local tailY local x local y local firstLength = 100 local lastLength local pathWidth = 200 local length = 300 local hallwayLength = { 300, 200, 100} local function drawWall(length, firstCall) if length then tailX = centerX + 100 tailY = centerY + 300 else if angle == 45 then tailX = x + (lastLength \* math.cos(math.rad(angle))) tailY = y - (lastLength \* math.sin(math.rad(angle))) else tailX = x - (lastLength \* math.cos(math.rad(angle))) tailY = y + (lastLength \* math.sin(math.rad(angle))) end length = hallwayLength[math.random(1,#hallwayLength)] end if angle == 45 then angle = -45 else angle = 45 end x = tailX y = tailY local leftWall = display.newRect(x , y, 5 , length + 2.5) local rightWall = display.newRect(x + pathWidth, y, 5 , length + 2.5) leftWall.anchorY = 1.0 leftWall:rotate(angle) rightWall.anchorY = 1 rightWall:rotate(angle) lastLength = length if firstCall == true then pathBack = display.newRect( x + 4, y, math.sin(math.rad(90-angle))\*pathWidth - 5, length ) firstCall = false pathBack:rotate(angle) else if angle == -45 then pathBack = display.newRect( x + 4, y , math.sin(math.rad(90-angle))\*pathWidth - 5 , length ) pathBack:rotate(angle) else pathBack = display.newRect( x + 4, y , math.sin(math.rad(90-angle))\*pathWidth -8, length + math.sin(math.rad(45))\*pathWidth) pathBack:rotate(angle) end end pathBack.anchorX = 0.0 pathBack.anchorY = 1.0 pathBack:setFillColor(0,0,1) end drawWall(length, true) drawWall() drawWall()

Regards,

Lin

That trick only works for 45-degree angles (which I think I said in the hangout, at least I hope I did).

Let’s back up a bit though.

If the code works, why are you changing it?  Are you trying to make halls that run at other angles besides 45-degrees?

If you’re trying to learn simply to learn, that is awesome.  In which case, I’d focus on understanding how you calculate half-triangle bases.  Why half?  Well, we’re moving each of the two walls such that they are one base distance apart.  So, we can simply move them each by half that distance.

The key to this whole thing is becoming familiar with the Pythagoras Theorem: “a^2 = b^2 + c^2” and  how it is used to solve relationships like this.

Finally, please be sure to watch the very first shows (130 and 131) where we started making this clone.  And look at the OLD code (‘app_old_versions’ folder) I kept aside.  I provided it expressly for the purpose of walking through how the halls are made.  First I drew just a line segment as the ‘hall’, then two, then moved them, then I added a little extra length to handle overlap at the edges, …

Additional notes:

  1. For angles other that 45-degrees, the math gets very messy, or a very good understanding of the math is required for an elegant solution.  That is why this game only uses 45 degree angles.  

  2. Introducing alternate angles also severely complicates hallway layout and generation.  This game-clone is not a good starting place for hallways that can turn back on themselves or move sideways.

One more small note:  I’m not a great source for math learning/teaching.  

I’m afraid much of what I know, I know from doing this for a long time, not from teaching, so I often know a thing/trick works, but don’t remember the why of it, which makes it hard for me to explain.  

it’s not an easy subject to teach in a forum.

suggest that op google for the trigonometry of right angles… (or, better yet, take trig in school, eventually)

it’s no coincidence that sin(pi/4) == sqrt(2)/2

just work Pythagorus “backwards” asking “what would ‘a’ and ‘b’ need to be if ‘c’ is to equal one?”

we know a==b in a 45-45-90, and we want c==1 because we’re in need of a unit vector (even though we maybe don’t yet recognize it by that name)

…so, even better yet, take linear algebra while still in school, and recognize the relationship between unit vectors and trig, then drop the trig altogether - because all you really need to construct this sort of geometry is a single unit vector representing the desired angle.

(in *code* you’d need another vector to work *with*, to preserve your original, but that’s just an implementation detail, conceptually it’s still just the single vector doing all the work)

for example, given the unit vector <cos(45),sin(45)>, you’d proceed like this:

define a starting location

scale your vector to desired wall length

translate your vector to starting location

the end of that vector is now the end of your line (and the start of the next)

rotate your vector perpendicular (+/- 90 degrees;  <vx,vy> = <-vy,vx> or <vy,-vx> )

repeat

(and the wall on the other side is just “translate-perpendicular-scaled-by-path-width”)

with such a construction method, it’d be entirely trivial to switch to 50/40 degrees, or 60/30, or 70/20, etc.

…or just draw the whole thing orthogonally and simply rotate the camera.  :D

Hi Ed,

I just want to learn and in case I want to customize I need to understand the code well enough. 

Thanks,

Lin

It’s a math trick for calculating half the width of an isosceles triangle base (with angles of 45-degrees).

Look at the triangle here: http://mathworld.wolfram.com/IsoscelesTriangle.html

The two sides of the triangle ‘b’ are the same length (in our game we treat the sides of our hall like one side of a triangle).  

If you know b (which we do in the game [length]), we can calculate half the length of ‘a’, by doing this:

a = (b/2) / math.sqrt(2)

We need to do this in the game, because our walls are at 45 degree angles and flip on each turn.  This trick lets us easily calculate the width of the hall (or how far to move the sides from a center point.

Hi Ed,

Thanks for you explanation. I still don’t understand it and can’t find the formula in the link. You said “we treat the sides of our hall like one side of a triangle,” is it after or before the rotation? and where the base should be? It would be helpful if you could draw the said triangle in the game then I’ll try to figure out more on my own.

Thanks,

Lin

Hi Ed,

Does that /math.sqrt(2) apply to all angles? It seems to me that it only work(do the trick) with 45 degree angle.

I still don’t understand the math you use so I write the following. By treating the wall segment as radius and knowing the angle, I can find the x and y for the next wall segment. Still need to tweak a lot more.

local fullw = display.contentWidth local fullh = display.contentHeight local centerX = display.contentCenterX local centerY = display.contentCenterY local angle = 45 local lastAngle local tailX local tailY local x local y local firstLength = 100 local lastLength local pathWidth = 200 local length = 300 local hallwayLength = { 300, 200, 100} local function drawWall(length, firstCall) if length then tailX = centerX + 100 tailY = centerY + 300 else if angle == 45 then tailX = x + (lastLength \* math.cos(math.rad(angle))) tailY = y - (lastLength \* math.sin(math.rad(angle))) else tailX = x - (lastLength \* math.cos(math.rad(angle))) tailY = y + (lastLength \* math.sin(math.rad(angle))) end length = hallwayLength[math.random(1,#hallwayLength)] end if angle == 45 then angle = -45 else angle = 45 end x = tailX y = tailY local leftWall = display.newRect(x , y, 5 , length + 2.5) local rightWall = display.newRect(x + pathWidth, y, 5 , length + 2.5) leftWall.anchorY = 1.0 leftWall:rotate(angle) rightWall.anchorY = 1 rightWall:rotate(angle) lastLength = length if firstCall == true then pathBack = display.newRect( x + 4, y, math.sin(math.rad(90-angle))\*pathWidth - 5, length ) firstCall = false pathBack:rotate(angle) else if angle == -45 then pathBack = display.newRect( x + 4, y , math.sin(math.rad(90-angle))\*pathWidth - 5 , length ) pathBack:rotate(angle) else pathBack = display.newRect( x + 4, y , math.sin(math.rad(90-angle))\*pathWidth -8, length + math.sin(math.rad(45))\*pathWidth) pathBack:rotate(angle) end end pathBack.anchorX = 0.0 pathBack.anchorY = 1.0 pathBack:setFillColor(0,0,1) end drawWall(length, true) drawWall() drawWall()

Regards,

Lin

That trick only works for 45-degree angles (which I think I said in the hangout, at least I hope I did).

Let’s back up a bit though.

If the code works, why are you changing it?  Are you trying to make halls that run at other angles besides 45-degrees?

If you’re trying to learn simply to learn, that is awesome.  In which case, I’d focus on understanding how you calculate half-triangle bases.  Why half?  Well, we’re moving each of the two walls such that they are one base distance apart.  So, we can simply move them each by half that distance.

The key to this whole thing is becoming familiar with the Pythagoras Theorem: “a^2 = b^2 + c^2” and  how it is used to solve relationships like this.

Finally, please be sure to watch the very first shows (130 and 131) where we started making this clone.  And look at the OLD code (‘app_old_versions’ folder) I kept aside.  I provided it expressly for the purpose of walking through how the halls are made.  First I drew just a line segment as the ‘hall’, then two, then moved them, then I added a little extra length to handle overlap at the edges, …

Additional notes:

  1. For angles other that 45-degrees, the math gets very messy, or a very good understanding of the math is required for an elegant solution.  That is why this game only uses 45 degree angles.  

  2. Introducing alternate angles also severely complicates hallway layout and generation.  This game-clone is not a good starting place for hallways that can turn back on themselves or move sideways.

One more small note:  I’m not a great source for math learning/teaching.  

I’m afraid much of what I know, I know from doing this for a long time, not from teaching, so I often know a thing/trick works, but don’t remember the why of it, which makes it hard for me to explain.  

it’s not an easy subject to teach in a forum.

suggest that op google for the trigonometry of right angles… (or, better yet, take trig in school, eventually)

it’s no coincidence that sin(pi/4) == sqrt(2)/2

just work Pythagorus “backwards” asking “what would ‘a’ and ‘b’ need to be if ‘c’ is to equal one?”

we know a==b in a 45-45-90, and we want c==1 because we’re in need of a unit vector (even though we maybe don’t yet recognize it by that name)

…so, even better yet, take linear algebra while still in school, and recognize the relationship between unit vectors and trig, then drop the trig altogether - because all you really need to construct this sort of geometry is a single unit vector representing the desired angle.

(in *code* you’d need another vector to work *with*, to preserve your original, but that’s just an implementation detail, conceptually it’s still just the single vector doing all the work)

for example, given the unit vector <cos(45),sin(45)>, you’d proceed like this:

define a starting location

scale your vector to desired wall length

translate your vector to starting location

the end of that vector is now the end of your line (and the start of the next)

rotate your vector perpendicular (+/- 90 degrees;  <vx,vy> = <-vy,vx> or <vy,-vx> )

repeat

(and the wall on the other side is just “translate-perpendicular-scaled-by-path-width”)

with such a construction method, it’d be entirely trivial to switch to 50/40 degrees, or 60/30, or 70/20, etc.

…or just draw the whole thing orthogonally and simply rotate the camera.  :D

Hi Ed,

I just want to learn and in case I want to customize I need to understand the code well enough. 

Thanks,

Lin