Elliptical orbits, objects following EllipseCurve

Hi all,

I’m working on my first three.js project, its an earth with comets at elliptical orbits… check below.




I’ve traced out the orbits I want with the EllipseCurve, and rotated them to give the eccentricity. The issue I’m having is, how to get the comets (the small circle in the image) to follow the ellipse curve? I’ve tried using getPoint() to get an array of coordinates, then move the comet to the locations of the ellipse. But, this isn’t working… plus I don’t think this is the correct way of doing this. Originally I tried using a rotating Object3D as an anchor, but soon realised I couldn’t use this as I couldn’t get an elliptical orbit.

Im kinda stuck for what to do, and I’m so new to this library I’m not sure where to look. Any advice is greatly appreciated.

Heres the ellipse code:



Heres a link to the repo if you want to check it out, the code is in the elipse.js file.

Thank you!!

Do you know these examples from the collection?

FlightRouteQuaternion
BasisToQuaternion
CarRacing
MovementOnCurve
MotionAlongCurve

1 Like

No, I’ll have a look now… all the examples I’ve seen so far were super complex and way over my head… I’ll do a little research

Thank you!

The extension of the internal quaternion methods used in some examples
( THREE.Quaternion.prototype.setFromBasis = function( e1, e2, e3 ) { ... )
you don’t need to understand the content. It allows for a clear code and can be easily used like an internal method. :slightly_smiling_face:

1 Like

Hi hofk,

Thanks for the post, It was really informative. Ive managed to move in what I believe is the correct direction just that little more.

If you don’t mind me asking another question… I’ve gone through the MoveAlongCurve example you provided and tried recreating it myself with the project I was working on. However I’ve run into the issue of the comet not loading, and I cant for the life of me figure out why…

The issue I believe is in the Flow section, because if I add it normally it has no issues and shows up. I’m a little unsure with Flow since its totally new to me.

I’m getting no error messages, so I’m a little confused.



The code if your interested.



Also Repo if it makes it easier.

Once again thank you, you’ve really saved this project.

Code screnshots are problematic. Better is to copy the decisive code into the post, mark it with the mouse and format it as code with </> from the toolbar.

1 Like

Sorry, I was unsure of how to do that on this site… noted for next time, thanks.

import "./style.css";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { Flow } from "three/examples/jsm/modifiers/CurveModifier.js";

const renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);

const camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    10000
);
const controls = new OrbitControls(camera, renderer.domElement);
camera.position.set(0, 0, 1000);
controls.update();

const scene = new THREE.Scene();
renderer.render(scene, camera);

/* world */

const worldTexture = new THREE.TextureLoader().load("./assets/world-map.jpg");
const world = new THREE.Mesh(
    new THREE.SphereGeometry(100, 64, 32),
    new THREE.MeshStandardMaterial({
        map: worldTexture,
        // wireframe: true,
    })
);
scene.add(world);

/* ellipse two */

const curveTwo = new THREE.EllipseCurve(
    0,
    0, // ax, aY
    200,
    200, // xRadius, yRadius
    0,
    2 * Math.PI, // aStartAngle, aEndAngle
    false // aClockwise
    // aRotation
);
curveTwo.closed = true;

// points array

const points = curveTwo.getPoints(100);
const line = new THREE.LineLoop(
    new THREE.BufferGeometry().setFromPoints(points),
    new THREE.LineBasicMaterial({ color: 0x000000 })
);
scene.add(line);

const cometTwo = new THREE.Mesh(
    new THREE.SphereGeometry(10, 10, 5),
    new THREE.MeshStandardMaterial({
        color: 0x000000,
        wireframe: true,
    })
);

const flow = new Flow(cometTwo);
flow.updateCurve(0, curveTwo);
scene.add(flow.object3D);

/* lighting */

const pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(-500, 500, 1000);
scene.add(pointLight);

/* function */

animate();

function animate() {
    requestAnimationFrame(animate);

    world.rotation.y += -0.001;

    flow.moveAlongCurve(0.0006);

    renderer.render(scene, camera);
}

Regardless of the error (?) I see a problem with this solution variant.

See bending of the geometry How to animate curved arrows in threejs? - #4 by hofk

1 Like

okay, I’ll do some research tonight… Would it be possible to quickly explain the issue you see? I’m happy to research but I don’t know what the problem is…

I see the post you’ve linked is to do with arrow bending along the line, but it that required for a circle? I just want it to follow the rails.

Thank you again!!

With flow, a mesh is bent from more than one length segment on the curve. You can see this in the pictures, I had overlooked it myself before.

I have not yet tried it with a sphere or circle. Just copy my example and try it.

1 Like

Hi hofk,

Hope you’re enjoying this fine Thursday.

I’ve been playing around with the examples you sent to me and have been trying to figure this problem out. I replaced the Box element with circle element and things seem to be working so far.

I think I’ve narrowed down the issues with my project… I have a feeling the issues is that I’m passing in a Vector2 array when the CatmullRomCurve3 expects a Vector3 array.




log of the arrays…



So my question is… is it possible to use getPoints() or a similar method on the lines drawn from the rotated EllipseCurve show in the screenshot in my original post?

I can use the getPoints() on the EllipseCurve to get a 2D array of the EllipseCurve (shown above)… However, if I want to get the eccentricity I need to use rotation on the ellipseCurve. This I cannot do on the EllipseCurve unless I make it a line (shown below), the issues is I cannot use getPoints() on a line.

const ellipseThree = new THREE.Line(geometryThree, ellipseMaterial);
ellipseThree.rotation.x = Math.PI * 0.6;
ellipseThree.rotation.y = Math.PI * 0.15;

Do you have any recommendations?

Once again thank you for any and all help.

Haven’t needed the ellipse yet. But I see the problem. Unlike CubicBezier and QuadraticBezier, three.js, like other curves, doesn’t have them for 3D.

Store the geometry for your line in a constant first and then use the rotation for the geometry. See three.js docs

1 Like

Maybe this topic will be helpful: Camera + EllipseCurve
Camera moves on the ellipse curve in 3D. You can use any other object instead of the camera.

2 Likes

Didn’t think about it at all. Is also in the collection.

CameraEllipseCurve

2 Likes

Honestly, you guys are the best…

hofk, you’ve been great and thank you for all the help!
Thank you too prisoner for the solution!

This has been driving me insane, I’ll raise a drink to you two tonight.

2 Likes