Intervals: moving along parabola?

Greetings pandas,

I don’t want to spam the forum with too many help requests, but I was struggling with the code trying to make an object move along a parabola path. I also studied the Solar System snippet from Panda tutorial.

Is there a better approach to this algorithm than Intervals?

Anyway, my first code snippet is the following. I got a sphere object follow a circle path.

        self.sunobject = loader.loadModel("models/sphere")
        self.sunobject.reparentTo(render)
    	self.orbit_root_sun = render.attachNewNode('orbit_root_sun')
        self.sunobject.reparentTo(self.orbit_root_sun)
        self.orbit_root_sun.setPos(350, -500, 50)
        self.orbit_root_sun.setScale(6.0)
        self.sunobject.setPos(50, 0, 0)
        self.sunobject.setScale(6.0, 6.0, 6.0)
    	self.orbit_period_sun = self.orbit_root_sun.hprInterval(7, Vec3(0, 0, -360))
        self.sunPace = self.orbit_period_sun
    	self.sunPace.loop()

The next snippet is very close to what I want to achive. I combined the forward movement with rotation in a combination of Sequence/Parallel. My intension was to merge a circular movement with a forward movement, so the combined path would be a parabola. Here goes:

        self.sunobject1 = loader.loadModel("models/sphere01")
        self.sunobject1.reparentTo(render)
        self.sunobject1.setPos(350, -500, 0)
        self.sunobject1.setScale(6.0, 6.0, 6.0)
    	self.orbit_forward_sun1 = self.sunobject1.posInterval(7, Vec3(250, -500, 0))
    	self.orbit_backward_sun1 = self.sunobject1.posInterval(7, Vec3(350, -500, 0))
    	self.orbit_rotate_sun1 = self.sunobject1.hprInterval(7, Vec3(0, 0, 360))
        self.sunPace1 = Sequence(Parallel(self.orbit_forward_sun1, self.orbit_rotate_sun1), Parallel(self.orbit_backward_sun1, self.orbit_rotate_sun1), name = "sunPace1")
    	self.sunPace1.loop()

The only problem is that the object rotates versus its own centre, not versus a point in space.

Any advise of how I could adjust the code to achieve a desired effect? Sort of to combine the above 2 snippets into one effect.

I could easily prepare an animation .egg file with the object moving along parabola and insert it, but I would like to code it.

To approximate the elliptoid movement of a planet I use this :

planet.setPos(radius * X * sin(time), radius * cos(time), 0)

X = 0.7 or something

If you don’t want physically correct movement, you can try it.

Thanks. That’s a ‘quasi’ solution, but might be good enough. The object.setPos defines object’s position once. I would need to loop it somehow, no?

Also, any idea if I can solve it using the Intervals? I like the Sequence/Parallel approach and I think it can be done in this way somehow.

There is this : http://www.panda3d.org/manual/index.php/Projectile_Intervals

I didn’t test it, but the resulting movement should be parabola.

Why not do something like this:

axisNode = render.attachNewNode("dummy")
myNode.reparentTo(axisNode)
LerpPosHprInterval(axisNode, <duration>, <targetPos>, <targetHpr>).start()

A parabola is basically a stretched circle sector, so this should work. I would assume this is what it was made for.

If you wanted to use Manou’s trigonometry, you would have to wrap it inside a LerpFunc interval.

Using Lerp Intervals gives me exactly the same results as with Sequence/Parallel. It’s basically the same.

So the same problem, the sphere rotates versus its centre not versus a point in 3D space.

Here is the code to illustrate it:

        self.sunobject = loader.loadModel("models/sphere")
        self.sunobject.reparentTo(render)
    	self.orbit_root_sun = render.attachNewNode('orbit_root_sun')
        self.sunobject.reparentTo(self.orbit_root_sun)
        self.orbit_root_sun.setPos(350, -500, 50)
        self.orbit_root_sun.setScale(12.0)
        LerpPosHprInterval(self.orbit_root_sun, 7, (250, -500, 50), (0, 0, 360)).start()

On the other hand, I’m getting quite good results with the Projectile Intervals method as per this code snippet:

        self.sunobject = loader.loadModel("models/sphere")
        self.sunobject.reparentTo(render)
        self.sunobject.setPos(350, -500, 50)
        self.sunobject.setScale(12.0)
        self.trajectory = ProjectileInterval(self.sunobject, startPos = Point3(350, -500, 0), endPos = Point3(250, -500, 0), duration = 7)
        self.trajectory.loop()

In the first code, you first reparent Sun to Orbit, and then you move and scale the Orbit. This means the Sun is still in (0, 0, 0) position relative to the Orbit node. You then apply an inverval to the Orbit node, which obviously results in the Sun rotating around it’s center, because the world-space positions of both nodes are the same.

As coppertop is saying, you just need to change:

       self.sunobject = loader.loadModel("models/sphere")
       self.sunobject.reparentTo(render)
       self.orbit_root_sun = render.attachNewNode('orbit_root_sun')
       self.sunobject.reparentTo(self.orbit_root_sun)
       self.orbit_root_sun.setPos(350, -500, 50)
       self.orbit_root_sun.setScale(12.0)
       LerpPosHprInterval(self.orbit_root_sun, 7, (250, -500, 50), (0, 0, 360)).start()

to:

       self.sunobject = loader.loadModel("models/sphere")
       self.orbit_root_sun = render.attachNewNode('orbit_root_sun')
       self.sunobject.reparentTo(self.orbit_root_sun)
       self.sunobject.setPos(350, -500, 50)
       self.sunobject.setScale(12.0)
       LerpPosHprInterval(self.orbit_root_sun, 7, (250, -500, 50), (0, 0, 360)).start()

Not that I removed the line where sunobject is reparented to render. It isn’t needed, since you change the parent almost immediately afterward.

Yes the line where sunobject is reparented to render is not needed, ok. Yet as coppertop pointed out this is not really the case. It’s the sun object vs the orbit node.

So I’m struggling to re-write the code, so the rotation is correct. I tried to first reparent the sun to the orbit and then setPos the sun to (0, 50, 0) vs the orbit to move it out of the orbit’s center, but it doesn’t seem to work. Is this approach correct?

Put the orbit anchor at the point you want the planet to rotate around. Reparent the sun to the orbit anchor and place the sun at y 50 or something. Then change the H on the orbit anchor.