This site requires JavaScript, please enable it in your browser!
Greenfoot back
Greenhorn
Greenhorn wrote ...

2014/3/6

Moving an Object in an Ellipse

Greenhorn Greenhorn

2014/3/6

#
Hello, I am trying to move an object in an ellipse. This is my code so far: setLocation(c - (int) Math.ceil(Math.sqrt(a)), b); while (xCoordinate < initialXCoordinate + horizontalDistance){ xCoordinate++; yCoordinate = d + (int) Math.ceil(Math.sqrt(b*b*(1 - (xCoordinate/a)*(xCoordinate/a)))); setLocation(xCoordinate, yCoordinate); } while (xCoordinate > initialYCoordinate - horizontalDistance){ xCoordinate--; yCoordinate = d + (int) Math.ceil(- Math.sqrt(b*b*(1 - ((xCoordinate-c)/a)*((xCoordinate-c)/a)))); setLocation(xCoordinate, yCoordinate); } } The code follows the equation of an ellipse on the Cartesian Plane. By using a function, I am hoping to define the trajectory of the object. However, this method immediately sets the object to the coordinates (0, 0). Does anyone know what is wrong with my method? Or if there is an easier way to draw an ellipse?
danpost danpost

2014/3/6

#
I think the main problem is in how you are using the 'while' loops. Any loop ('for', 'do', or 'while') will execute through completion within one act cycle. Only the end result will be displayed. The cycling of acts is what creates animation. You need to change your 'while's to 'if's for starters.
danpost danpost

2014/3/6

#
How elliptical are your ovals? are they close to circular, or far from it? does the speed the actor travels around the oval need to be pretty much constant, or is there a little room for wiggle there? I am just trying to figure out what options you may have available to you. There is the line following method to have your actor follow a 'transparent' oval (which would be a constant speed). There is iterating through the angular rotation (which would result in a variable range in speeds -- the closer to the center of the oval, the slower the actor would go). There is another way, which I used in my Our Inner Solar System scenario; but, as far as actor speed, that method works better for this 3D type motion.
Greenhorn Greenhorn

2014/3/11

#
Thanks! Really liked the Inner Solar System Scenario. However, I am trying to get objects to move in 2D. This was my method signature for orbit: protected void orbit(int a, int b, int c, int d, boolean direction){ I was trying to control how elliptical the oval would be using parameters. The speed which the actor travels at is constant.
danpost danpost

2014/3/11

#
I will see if I can figure something out for you.
danpost danpost

2014/3/11

#
At what rate of speed will it travel? and, do you want the actor to face the direction of movement?
danpost danpost

2014/3/11

#
I have figured out a way for constant speed movement in an elliptical pattern. However, there are some limitation which limit the minimum that the speed can be. I found that a fair minimum speed is about 5 (10 would be better). What I did was use the fact that the sum of the distances to the focal point is always equal to the long axis, basically adjusting the angle from the last known location until we end up just at or inside the edge of the ellipse. My class code ended up to be this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import greenfoot.*;
 
public class Track extends World
{
    int f = 200 // distance focal points are from center
    int, d = 30; // minimum distance of ellipse from either focal point
    int speed = 5; // speed of car
     
    public Track()
    {
        super(800, 600, 1);
        Actor actor = new Actor()
        {
            public void act()
            {
                String key = Greenfoot.getKey();
                if ("up".equals(key) && speed < d) speed++;
                if ("down".equals(key) && speed > 5) speed--;
                int x = getX(), y = getY();
                move(speed);
                while (Math.hypot(getX()-400+f, getY()-300)+Math.hypot(getX()-400-f, getY()-300) > 2*(f+d))
                {
                    setLocation(x, y);
                    turn(1);
                    move(speed);
                }
            }
        };
        GreenfootImage image = new GreenfootImage("car01.png");
        image.scale(image.getWidth()/2, image.getHeight()/2);
        actor.setImage(image);
        actor.setRotation(90);
        addObject(actor, 400+f+d, 300);
    }
}
You can adjust 'f' and 'd' as desired.
You need to login to post a reply.