Figure of eight movement

Sorry this is a fairly basic question, but my maths skills are somewhat lacking.
I’d like to move an object in a figure of eight movement around a central point.  I know that it can be done using sin/cos, but so far I can only get it moving in circles/elipses.

Hope someone with a better knowledge of maths can help me :slight_smile:

Cheers

Chris

Okay. Try this:

local image = display.newRect(100,100,100,100) local frameLoop = function(event) image.x = 600+math.sin(event.time/400)\*200 image.y = 200+math.sin(event.time/200)\*60 end -- frameLoop Runtime:addEventListener("enterFrame", frameLoop)

The key is to divide the value that you give the math.sin in half for the vertical motion.

Totally awesome!  That is exactly what I was after.  
@thomas6 - you are a legend!

Hehe - my girlfriend would disagree with that, but thanks for the compliment! :wink:

Sine and cosine are incredibly powerful tools. Check out this test video: both the bird motion and the hero walk cycle are all done using only sine waves.

https://www.youtube.com/watch?v=aixyWdqiAUU

Nice.  Is that something that you’ve created?

Yep! That’s the game I’m working on at the moment. Loads of work to do, but it’s shaping up to look real nice!

The “divide the value in half” is key. If that ratio changes a little you get all sorts of craziness: Lissajous figures

@StarCrunch - That looks amazing, but any idea how to implement it?  Like I said before my maths skills are pretty non-existent :slight_smile:

Those “a” and “b”, in the link, are the ratios you want to choose.

In thomas6’s example, he gives you event.time/400 and event.time/200, for x and y respectively, which are in the 1 : 2 ratio, since event.time / 200 = 2 * (event.time / 400). As you see on that page, that’s a figure 8!

So to get any of those others, just adjust those two numbers so they correspond to a given a and b. That gets you the curve. Then just tune the scale factors to taste.

@StarCrunch : That’s brilliant thank you.  Nice easy to understand explaination.

One other question though ( sorry about this )…

I’ve got the curve working nicely, but what I’d like is a line of object following each other along the curve.  I’ve tried but they all sit on top of each other so it looks like there’s only one.  Any idea how best to go about this?

Use (event.time + 50) instead of event.time for the second image, (event.time+100) for the next and so on!

As soon as I read your reply I just face palmed myself.  Looking at it it’s obvious.  Thank you so much :slight_smile:

OK, I have one more question related to this.  How would I go about making the objects rotate to face the direction of travel?  I’ve tried various things but none of them work :frowning:

Hmmm. Trigonometry is your friend! Unfortunately I don’t have the time to help a lot today.

Basically, if you know what the sine and the cosine of a given angle are, then you can derive the angle. IIRC using the math.atan2 function.

What is your code for the x and y movement? Can you post it here? This part I mean:

image.x = 600+math.sin(event.time/400)\*200 image.y = 200+math.sin(event.time/200)\*60
local e for e=1, #tabEnemies do tabEnemies[e].x = \_x+math.sin((event.time+tabEnemies[e].timeOffset)/750)\*\_x tabEnemies[e].y = \_y+math.sin((event.time+tabEnemies[e].timeOffset)/3000)\*\_y end

_x and _y are just local variables that I use as shorthand for the centre of the display area.
The timeOffset is set when the enemies are created to ensure they follow each other in a line (as mentioned above).

There really is no rush on this as I still have loads of other stuff to be getting on with as well :).

Appletreeman, 

Check out Brent’s tutorial on objects following a curve. If you download the examples at the end, they include the ‘follow’ module. The module includes allowing for an object to rotate to the direction its travelling. Load up the examples and you’ll see it, then you should be able to pick the code apart and figure out how to implement.

http://coronalabs.com/blog/2014/09/09/tutorial-working-with-curved-paths/

Appletreeman’s suggestion is a very good “catch-all” orient-to-path approach:

local deltaX = newX - oldX local deltaY = newY - oldY local angleRadians = math.atan2(deltaY, deltaX) local angleDegrees = math.deg(angleRadians) image.rotation = angleDegrees

If you store the old x and y coordinates and combine them with the new x and y coordinates, you can calculate the angle like this. However, for your specific case, since it’s such an elegant trigonometrical curve, I’m sure there is a better way to do this.

Brilliant.  I love this place :slight_smile:

As you say Thomas6, there may be a more elegant way of doing it but it works and looks good (for now).
Many thanks to everyone for the help and suggestions.

Beats me if it’d look any better, but the tangent vector falls right out of the math.

Since we have equations in the form

Xpos = X + cos(A * t + B ) * XScale

Ypos = Y + sin(C * t + D) * YScale

(where everything but time is a constant, and B and D may even be 0), some basic calculus gives us

Xtan = -sin(A * t + B ) * XScale * A

Ytan = cos(C * t + D) * YScale * C

The tangent would be going “along” the curve. This may be fine, or maybe we’d want something facing “out”, 90 degrees away. That’s just a matter of switching the components and negating one of them, so either (-Ytan, Xtan) or (Ytan, -Xtan), then just doing the same atan2 () / deg () treatment on whichever was chosen.

Whoops, they both start as sin (), so they both end up as cos (). Otherwise, as is.  :slight_smile: