Steering a Shape along a pathway

Hello all,

I want to steer a shape along a pathway. Let’s say a spaceship that first goes along x axis and when at a certain point stops and rotates slowly around its axis and then starts in another direction.

Like a framework with list of timers and different commands for the time periods. Ah, I must have done something like this…

But has anyone an example for this?

Thanks!

Chrisir

Do you want the shape to be locked to the path like a rail, and slide along it, or do you want it to be following a series of waypoints over time like a boid where it can be begin off the path and move onto it?

If you look at previous forum examples like LerpVectorsExample and LerpVectorsSimplified you will find some basic path-following objects.

Those are for objects x,y without orientation. If you wanted them to also turn, store x,y,r in the PVector, and draw the object with orientation r. Then place two nodes on the same path point like this:

0, 0, 0
100, 0, 0
100, 0, PI * 3/2.0
100, 100, PI * 3/2.0

Now the agent moves from point 0 to 1
Then turns in place to orientation 2
Then moves to point 3.

2 Likes

I am thinking you are referring to easing? This is an example.

I am thinking along the lines of a ship in the sea, it takes time to make a turn after you gave the command. Is this the concept you want to explore?

Kf

2 Likes

If it’s about easing, here’s another online example: :grinning:
Studio.ProcessingTogether.com/sp/pad/export/ro.9XkJm3bjTAxB2

2 Likes

Thanks everyone for the great help!

I digged a bit into this and my experience is this:

My goal was to animate a ship for a movie. So no interactivity involved.

when you have a slow animation of a ship, that’s going forward 3.2 seconds and then brakes for 0.7 seconds and turns 90 degrees: Don’t rely on millis()!

Because when you add complex decorations, like a couple of clouds or birds flying by or other ships, the amount of millis since the end of setup() doesn’t stay the same. In fact, running on windows, the time can even vary when you don’t change the code (e.g. when you have hard drive access because of storing the movie/images).

Better than millis() would be to use a x-position (or x,y,z): when the ship has reached this point, start to brake until speed is 0. Then start to turn until angle is 90. millis() ain’t your friend.

Chrisir

Hi there, I have a similar, perhaps simpler challenge–but being a newbie to Processing am a little stuck. How to move a spaceship GIF image from Earth along an elliptical orbit path past the outer planets and then back to Earth? Any assistance is mots appreciated. Cheers, Steve

In 2D or 3D please?

Chrisir

2D animation…The GIF image is to follow an elliptical path…I currently simply plot some x,y positions, store them in an array, and then display the image at each point, as shown below. But the processing happens so fast, that on can’t see the movement. Changing the frameRate doesn’t seem to have any effect.

void draw() 
{
for (int z=0; z<=28; z=z+1)
  {
  background(bkg);
  image (ship,x[z],y[z]);
  }
}
1 Like


float angle=0;

float radius = 160;

void setup() {
  size (770, 770);
}

void draw() {
  background (0);

  // get x and y 
  float x = width/2 + cos(radians(angle)) * radius;
  float y = height/2 + sin(radians(angle)) * radius * 2.9;

  ellipse(x, y, 17, 17);


  // ----------------
  // manage the angle 
  angle+=0.65;
  if (angle>360)
  { 
    angle=0;
  }
}


Thanks Chrisir…Much appreciated…Big improvement on what I was doing…Now I need to brush up on my trigonometry…Below is the slightly modified code…The path is elliptical in a vertical direction…How might I adjust it to a horizontal direction? Also, what determines the starting point? I would like the ship to start at planet Earth, which lies at position (250,250)?

float angle=0;
float radius = 100;
PImage bkg;
PImage ship;

void setup() {
  size (1000, 600);
  bkg = loadImage("solar_system.jpg");
  ship = loadImage("flying_saucer.gif");
}

void draw() {
  background (bkg);

  // get x and y 
  float x = width/2 + cos(radians(angle)) * radius;
  float y = height/2 + sin(radians(angle)) * radius * 2.9;
  image (ship, x,y);
//  ellipse(x, y, 17, 17);


  // ----------------
  // manage the angle 
  angle+=0.65;
  if (angle>360)
  { 
    angle=0;
  }
}

replace width/2 and height/2 by 250

move the * 2.9 one line up (it enlarges the radius in one direction)

Chrisir, Okey-dokey…Thanks mucho! I followed your directions and it now works fine. I readjusted the starting X,Y point to the center of the 1000,600 screen, so now the spaceship circles all of the planets. Which variable or equation determines the direction of the movement? Might you know of any online resources that can help to explain these trig. equations?

I don’t understand. Do you mean the direction the ellipse is pointing to,
like — or || or // ?

see https://www.processing.org/tutorials/trig/

Hi Chrisir,

Thanks for your quick response and thanks for the link to the Trigonometry Primer. This resource should be very helpful to me and my students.

Question 1: How can I change the direction from clockwise to counter-clockwise?
One more (last) question: My first idea (in my first post above) was to plot 28 points on the screen (elliptical circle) and have the image move from one point to another. The problem with this frame/path animation is that the computer displays them too quickly, so no real animation. Is there a way that I could pause between each ‘ship’ image display (say for 0.5 second), so that it would somewhat appear as movement? I tried using a ‘For loop’ (10,000 iterations), but everything still moved too fast.

for (int z=0; z<=28; z=z+1)
{
  for (int i=1; i<=10000; i=i+1) { }
  background(bkg);
  image (ship,x[z],y[z]);
}

(1) decrease the angle

(2) put the change of the angle in an if-clause

this represents a timer

if(millis()-timer>500) {
    Change angle 
    timer=millis();
}

say int timer = 0; before setup()

Of course you can add a bigger amount to the angle (or much slower to slow it down)

Thanks very much. I’ll give it a try. I tried using a small frame rate, but that doesn’t seem to slow down the frame display much. I wonder why a ‘For loop’ with a large number of iterations doesn’t seem to have any effect on the frame display rate. Cheers!

1 Like

That’s another approach than mine

In mine you slow down with adding smaller numbers to the angle

In yours please look at lerp in the reference

Okey-dokey…I’ll look at the LERP function. Thanks for the insights. Have a great day!
Cheers, Steve

“A good laugh and a long sleep are the best cures in the doctor’s book.” (Irish proverb)

Namaste.

1 Like

First Example

here - you can say speed = 0.0065; or speed = 0.00065; .....




final float speed = 0.065; 

float angle=0;

float radius = 160;

void setup() {
  size (1270, 770);
}

void draw() {
  background (0);

  // get x and y 
  float x = width/2 + cos(radians(angle)) * radius  * 2.9;
  float y = height/2 + sin(radians(angle)) * radius;

  ellipse(x, y, 17, 17);


  // ----------------
  // manage the angle 
  angle += speed; // what you add here is the speed !!!!!!
  if (angle>360)
  { 
    angle=0;
  }
}

Second Example

here is the timer example, bigger angle but waits 1,5 seconds




final float speed = 1.85; 

int timer = 0;

float angle=0;

float radius = 160;

void setup() {
  size (1270, 770);
}

void draw() {
  background (0);

  // get x and y 
  float x = width/2 + cos(radians(angle)) * radius  * 2.9;
  float y = height/2 + sin(radians(angle)) * radius;

  ellipse(x, y, 17, 17);

  // timer
  if (millis()-timer>1500) {
    // Change angle
    // ----------------
    // manage the angle 
    angle += speed; // what you add here is the speed !!!!!!
    if (angle>360)
    { 
      angle=0;
    }
    timer=millis();
  }//if
}