Search code examples
javascriptgraphicsthree.jsgeometryparticle-system

How to fix errant orientation and points in an elliptical particle cloud?


I'm creating an elliptical cloud of points in Three.js and have two problems that seem straight forward, but I've been stuck on now for a couple days:

  1. The cloud should be elliptically shaped with the longest axis on the x axis - currently it's oriented with the shortest axis on the x axis
  2. While my fiddle for the cloud looks perfectly elliptical, the working code in my file has a few points at y = 0 on the x axis that appear to be running to the beat of their own drummer - they are lined up like soldiers on the y = 0 on either side of the ellipse to the measure of length (see screenshot below). Both files contain the same math for the ellipse - what's going on here?

Thanks!

The code for the elliptical cloud of points:

particleCount = 300;
for (var p = 0; p < particleCount; p++) {
    // ELLIPTICAL
    var length = 200; // x (major axis)
    var width = 75; // y (minor axis)
    var pX = (Math.random() * length);
    // solve for length of vertical chord at pX:
    var chord;
    var rightBisector = Math.abs((length/2) - pX);
    chord = (2 * length) * Math.sqrt(1 - Math.exp(2 * Math.log(rightBisector/width)));
    var pY = (Math.random() * chord);
    pX -= length/2; // center the cloud horizontally
    pY -= chord/2; // center the cloud vertically
    // END ELLIPTICAL
    // Make image particle at pX, pY and add to system

elliptical cloud of points with errant particles on either side


Solution

  • It turns out all the errors lay in my misunderstanding of the ellipse equation someone kindly aided me on here. I've corrected the code below now realizing that I used the dimensions of the axes in places where I should have used the two different radii. I've edited some of the variable names to make things clearer.

    // ELLIPTICAL particle cloud
    var majorAxis = 200; // x (major axis)
    var minorAxis = 75; // y (minor axis)
    var majorRadius = majorAxis / 2;
    var minorRadius = minorAxis / 2;
    var pX = ( Math.random() * majorAxis );
    // solve for length of vertical chord at pX:
    var rightBisector = Math.abs( majorRadius - pX );
    var chord = (2 * minorRadius) * Math.sqrt( 1 - Math.exp( 2 * Math.log( rightBisector / majorRadius ) ) );
    var pY = ( Math.random() * chord );
    pX -= majorRadius; // center the cloud horizontally
    pY -= chord / 2; // center the cloud vertically
    // END ELLIPTICAL
    // Make image particle at pX, pY and add to system
    

    Now all is as it should be:

    corrected ellipse