Easy math question - find point on circumference of a circle.

Of course, by easy question I mean easy for anyone who knows maths :slight_smile:

Imagine I have an asteroids style game where the ship can rotate and thrust about.  I have a smoke trail that is created when the ship thrusts but its point of origin is the XY coords of the ship so when the ship is turning and thrusting at the same time it looks like the smoke is coming out of the side of the ship.

What I’m trying to do is work out the co-ords so that the smoke is generated at the back of the ship regardless of the ships angle.

I really must try to learn basic trig :slight_smile:

Thanks in advance

Hi,

I had a similar issue when working on Radiance and had to brush up on math skills as well.

Not the stuff one uses every day is it.

It’s been a while so let me just paste the snippet and perhaps it can be of some help.

The code is of course about rotating an emitter with tail but the consept should be similar.

Could be the code overcomplicate it but I’m no math genius :slight_smile:

animRotateValue=math.deg(math.atan((1062-278-animFocus.x)/math.abs((482-318-animFocus.y)))) if animFocus.y\<482-318 and animFocus.x\>1062-278 then animRotateValue=180+math.deg(math.atan((math.abs(1062-278-animFocus.x))/math.abs((482-318-animFocus.y)))) end if animFocus.y\<482-318 and animFocus.x\<1062-278 then animRotateValue=90+(90-math.deg(math.atan((math.abs(1062-278-animFocus.x))/math.abs((482-318-animFocus.y))))) end transition.to(emitter[1],{time=300,rotation=animRotateValue})

You could also just add the emitter as a child object to your ship, offset it to the position you want your smoke to appear and use it’s current position whenever you create a smoke particle.

Cheers for the responses guys.

It’s not actually an emitter that I’m using (though it may get changed as development progresses).

What I’ve ended up doing is creating a tiny invisible object at the point that I want the smoke to appear and then attaching that to the players ship with a weld joint.  The smoke is then created at the XY of that object and it works like a charm.

Do you mean something like that?

v6V0vmZ.gif

If so check ldurniat/Asteroids on github.

Note: To improve your math skills check Math for Game Developers (YouTube chanel) :slight_smile:

Have a nice day Appletreeman:)

ldurniat

Here is a quick sample of a following object orbiting a parent object using math.rad(), math.sin() and math.cos():

local distance = 100 local parentObj = display.newRect(display.contentWidth \* 0.5, display.contentHeight \* 0.5, 50, 50) local followingObj = display.newRect(0, 0, 25, 25) local function update() parentObj.rotation = parentObj.rotation + 1 if parentObj.rotation \> 360 then parentObj.rotation = 0 elseif parentObj.rotation \< 0 then parentObj.rotation = 360 end local radians = math.rad(parentObj.rotation) followingObj.x, followingObj.y = parentObj.x + (math.sin(radians) \* distance), parentObj.y - (math.cos(radians) \* distance) end Runtime:addEventListener( "enterFrame", update )&nbsp;

The important part is the last 2 lines of the update function,where it gets the current angle of the parent object, converts that to radians and then sets the position of the following object relative to the parentObj’s position based on that angle:

local radians = math.rad(parentObj.rotation) followingObj.x, followingObj.y = parentObj.x + (math.sin(radians) \* distance), parentObj.y - (math.cos(radians) \* distance)&nbsp;

The distance is hardcoded to 100 in my example, but presumably you would want to use distance = ship.height * 0.5 or something like that so that it always appears at the bottom of the ship. 

And obviously you’ll need to change it to set the initial position of new smoke trail objects, rather than updating an existing object’s position.

Why don’t you use equations below?

x=cos( alpha ) y=sin( alpha )

where alpha is angle of parent object.

Equations come from wikipedia - Polar coordinate system.

Have I not done that…?

math.cos() and math.sin() take an angle in radians as their argument ( I don’t know of any cos() and sin() function in Corona that uses an angle in degrees), and on the line above the one you quoted I have converted the angle of the parent into radians:

local radians = math.rad(parentObj.rotation)

I’ve then multiplied the sin/cos values by a distance, because Appletreeman may not want the object to appear in the middle of the parent object.

Lastly I’ve added the resulting values onto the current xy position of the parent object, because the position of the child object is relative to the parent of the parent object. 

I would use sinus and cosinus functions in slightly different way than you:

followingObj.x, followingObj.y = parentObj.x + math.cos(radians)&nbsp;\* distance, parentObj.y +&nbsp;math.sin(radians) \* distance

That is all:)

Ah I see. Generally when the angle is 0 I think of it as being overhead, whereas with your calculation it would appear to the right of the object.

The wiki post you linked shows angle = 0 as being to the right, whereas in Corona’s docs they say “this rotation is based in the clockwise direction where 0 is directly upward”.

those docs are essentially nonsense - rotation as used there has no intrinsic “zero orientation” (ie, you can imagine zero as pointing to wherever you like, and it makes no difference, it still equals “no rotation” – rotation is a relative angle, not an absolute angle)

but compare it against some actual trig calculations and you’ll find the difference…

the “math convention” is that zero is along the positive x-axis, proceeding towards the positive y-axis.  (so normally it would proceed counter-clockwise, but in corona the y-axis is inverted so it appears to proceed clockwise)

thus, the “math convention” answer to OP’s question would look something like:

xprime = x + radius \* math.cos(theta) yprime = y + radius \* math.sin(theta)&nbsp;

swapping cos/sin for y/x causes a 90 degree rotation and reflection about the y axis (left for reader to prove to themselves) which recreates the “clock orientation” system described in the docs.  no problem, trig doesn’t care, still valid, but it looks “weird” to math people.  (just take care to use same convention throughout your code!)

Hi,

I had a similar issue when working on Radiance and had to brush up on math skills as well.

Not the stuff one uses every day is it.

It’s been a while so let me just paste the snippet and perhaps it can be of some help.

The code is of course about rotating an emitter with tail but the consept should be similar.

Could be the code overcomplicate it but I’m no math genius :slight_smile:

animRotateValue=math.deg(math.atan((1062-278-animFocus.x)/math.abs((482-318-animFocus.y)))) if animFocus.y\<482-318 and animFocus.x\>1062-278 then animRotateValue=180+math.deg(math.atan((math.abs(1062-278-animFocus.x))/math.abs((482-318-animFocus.y)))) end if animFocus.y\<482-318 and animFocus.x\<1062-278 then animRotateValue=90+(90-math.deg(math.atan((math.abs(1062-278-animFocus.x))/math.abs((482-318-animFocus.y))))) end transition.to(emitter[1],{time=300,rotation=animRotateValue})

You could also just add the emitter as a child object to your ship, offset it to the position you want your smoke to appear and use it’s current position whenever you create a smoke particle.

Cheers for the responses guys.

It’s not actually an emitter that I’m using (though it may get changed as development progresses).

What I’ve ended up doing is creating a tiny invisible object at the point that I want the smoke to appear and then attaching that to the players ship with a weld joint.  The smoke is then created at the XY of that object and it works like a charm.

Do you mean something like that?

v6V0vmZ.gif

If so check ldurniat/Asteroids on github.

Note: To improve your math skills check Math for Game Developers (YouTube chanel) :slight_smile:

Have a nice day Appletreeman:)

ldurniat

Here is a quick sample of a following object orbiting a parent object using math.rad(), math.sin() and math.cos():

local distance = 100 local parentObj = display.newRect(display.contentWidth \* 0.5, display.contentHeight \* 0.5, 50, 50) local followingObj = display.newRect(0, 0, 25, 25) local function update() parentObj.rotation = parentObj.rotation + 1 if parentObj.rotation \> 360 then parentObj.rotation = 0 elseif parentObj.rotation \< 0 then parentObj.rotation = 360 end local radians = math.rad(parentObj.rotation) followingObj.x, followingObj.y = parentObj.x + (math.sin(radians) \* distance), parentObj.y - (math.cos(radians) \* distance) end Runtime:addEventListener( "enterFrame", update )&nbsp;

The important part is the last 2 lines of the update function,where it gets the current angle of the parent object, converts that to radians and then sets the position of the following object relative to the parentObj’s position based on that angle:

local radians = math.rad(parentObj.rotation) followingObj.x, followingObj.y = parentObj.x + (math.sin(radians) \* distance), parentObj.y - (math.cos(radians) \* distance)&nbsp;

The distance is hardcoded to 100 in my example, but presumably you would want to use distance = ship.height * 0.5 or something like that so that it always appears at the bottom of the ship. 

And obviously you’ll need to change it to set the initial position of new smoke trail objects, rather than updating an existing object’s position.

Why don’t you use equations below?

x=cos( alpha ) y=sin( alpha )

where alpha is angle of parent object.

Equations come from wikipedia - Polar coordinate system.

Have I not done that…?

math.cos() and math.sin() take an angle in radians as their argument ( I don’t know of any cos() and sin() function in Corona that uses an angle in degrees), and on the line above the one you quoted I have converted the angle of the parent into radians:

local radians = math.rad(parentObj.rotation)

I’ve then multiplied the sin/cos values by a distance, because Appletreeman may not want the object to appear in the middle of the parent object.

Lastly I’ve added the resulting values onto the current xy position of the parent object, because the position of the child object is relative to the parent of the parent object. 

I would use sinus and cosinus functions in slightly different way than you:

followingObj.x, followingObj.y = parentObj.x + math.cos(radians)&nbsp;\* distance, parentObj.y +&nbsp;math.sin(radians) \* distance

That is all:)

Ah I see. Generally when the angle is 0 I think of it as being overhead, whereas with your calculation it would appear to the right of the object.

The wiki post you linked shows angle = 0 as being to the right, whereas in Corona’s docs they say “this rotation is based in the clockwise direction where 0 is directly upward”.