# Simple Orbiter 2

Page 2 of 3   1, 2, 3

## Re: Simple Orbiter 2

// HooAhhh, We have a collision at 9 o'clock.

////////////////////////////////////////////////////////////

this.gravAndChargeRepulsion = function ( boids ) {

var boid,
magAndDir = new THREE.Vector3(),
tanAcceleration = new THREE.Vector3(),
totalAcceleration = new THREE.Vector3();
totalAcceleration.set( 0, 0, 0 );

for ( var i = 0, il = boids.length; i < il; i ++ ) {
boid = boids[ i ];
// = boid.position.distanceTo( this.position );
distanceSquared = boid.position.distanceToSquared( this.position );
//grav = boid.gravity / boid.length;
if ( distanceSquared > 0.1) {
// changing from distance to distanceSquared didn't
// seem to effect the fps indications.

// grav = boid.gravity / distance;
// a. Gravity = 1/d, Expansion theory.;
grav = boid.gravity / distanceSquared;
// b. I've tried both. Maybe distSq is slower?
// Keep distanceSquared if only to avoid the very slow sqrt function.

magAndDir.subVectors(boid.position,this.position );
// magAndDir.normalize(); That was a mistake.
// Much better behaviour without it.
theta = boid.spinAxis.angleTo(magAndDir);
char = boid.charge * Math.sin( 2 * theta);

distance4 = (distanceSquared * distanceSquared);
char = char / distance4;
magAndDir.multiplyScalar(grav - char);

tanAcceleration.crossVectors( boid.spinAxis, magAndDir );
tanAcceleration.normalize();
tanAcceleration.multiplyScalar(char);

// Begin collision detection.

// Source, "Pool Hall Lessons: Fast, Accurate Collision
// Detection Between Circles or Spheres"
// http://www.gamasutra.com/view/feature/131424/pool_hall_lessons_fast_accurate_.php

// The single collision 3D dynamic reduces to a 2D known
// solution. In the reference, movevec is the moving circle
// velocity vector used to determine the collision contact
// point with a stationary circle.

// Here, movevec - the next this.velocity - won’t be
// calculated until totalAcceleration is known.
// For clarity: this.velocity resulted from adding
// the previous totalAcceleration to the previous
// this.velocity. The next this.velocity is created
// outside this i-loop and its host function
// or each new this.velocity, is created in the
// function this.move().

// The particle's current velocity, this.velocity, is a
// close approximation, good enough for escape tests.

// The particle pairs that fail the escape tests here
// will be collision candidates.

// I'll keep the source instructions, but change the
// names slightly so the differences with this
// implementation will be easier to follow.

// First my small addition, a benchmark test.
// create a reasonable closing frame separation distance
// threshold or things can slow down quickly. Current
// maximum particle speed appears to be about 3units/frame.
var VectorC = new THREE.Vector3();
// VectorC, the vector from the center of the moving circle
// A to the center of B. A length of 7.5 units amounts to more
// than twice the observed maximum velocity. The target is too
// far away and collision cannot occur within that frame.
VectorC.subVectors( boid.position, this.position );
if(VectorC.length ()> 7.5){
continue; }

// If the length of the approxMoveVec is less than the
// distance between the centers of these circles minus
// their radii, there's no way they can hit.
var approxMoveVec = new THREE.Vector3();
// Note the two-moving sphere case.
var distSq;
distSq = (VectorC.length * VectorC.length) - sumRadiiSquared;
if(approxMoveVec.lengthSq < (distSq)){
continue; }

var VectorN = new THREE.Vector3();
// Normalize the approxMoveVec
VectorN.copy(approxMoveVec);
VectorN.normalize();
// D = N . C = ||C|| * cos(angle between N and C)
var D = VectorN.dot(VectorC);
// Another early escape: Make sure that A is moving
// towards B! If the dot product between the
// approxMoveVec and B.center - A.center is less that
// or equal to 0, A isn't isn't moving towards B
if(D <= 0){
continue; }

var F = (VectorC.length * VectorC.length) - (D * D);
// Escape test: if the closest that A will get to B
// more than the sum of their radii, there's no
// way they are going collide
continue; }

// We now have F and sumRadii, two sides of a right triangle.
// Use these to find the third side, sqrt(T)
var T = sumRadiiSquared - F;
// If there is no such right triangle with sides length of
// sumRadii and sqrt(f), T will probably be less than 0.
// Better to check now than perform a square root of a
// negative number.
if(T < 0){
continue; }

// Therefore the distance the circle has to travel along
// approxMoveVec is D - sqrt(T)
var dist2;
dist2 = D - Math.sqrt(T);
// Get the magnitude of the movement vector
var mag = approxMoveVec.length();
// Finally, make sure that the distance A has to move
// to touch B is not greater than the magnitude of the
// movement vector.
if(mag < dist2){
continue; }

// And the final set of reference lines:
// Set the length of the movevec so that the circles will just touch.
// approxMoveVec.normalize();
// approxMoveVec.times(dist2);
// return true;
// OK, just me now. Going further is a waste of time
// without knowing the particle’s actual velocity.

system.out.println("dist2 is " + dist2);
// The system doesn't print anything, but the animation
// consistently freezes here with the collision visible.
// All I need to do is refresh to start it back up again.
// By the way, this is the most sophisticated stopping
// point test I've ever handled.

// So far, there's been no real penalty. With 256 particles,
// fps has held at 24, since adding the first test. Without it,
// 128 particles were clocking in at 29 fps.

// Still present at this point, we have this.position, aka
// boid = boids[ i ] from the function render(), and
// boid = boids[ i ] from this.gravAndChargeRepulsion()
// in a photo-finish.

// How would I pass them to this.moveCollisonBounceEtc

// Must every joy come with such pain?

}

}

};

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

I admited being somewhat of a clod last week using the java cmd system.out.println as a programming tool. It reflected a certain desperation at the time. Then after a bout with an if-statement (testing equivalence - not making an assignment) I also realized that while I had studied Java, I had not yet studied JavaScript. So in my normal fashion, I went back to start, by beginning two new books: 1) http://eloquentjavascript.net/index.html; and 2) JavaScript: The Definitive guide. I loaded three.js Inspector but don’t see any utility to it yet. I also loaded Firebug on my Firefox. I am now using what I believe is a JavaScript console, to use the mini API cmd console.log(“doh”); to allow running javascript snippets or all the text examples on my browser. Also, an alert with variables listed has replaced system.out.println. Please forgive my loose use of the subject matter. Your patience is appreciated.

In any case, with less than a week left to this year, my best wishes to all for the next.

.

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

Great Bouncing Me Tea Oids!

Allow me to repeat myself, Happy New Year!

Collisions and Bounces. Success. Even if I say so myself.

The collisions look OK. Most have the periapsis wiggle to some degree introduced by the charge field’s tanAcceleration. The wildest “collision” occurs when two boids roll around each other at high speed, a quirk or feature of SO2 caused when two bids are too close ( < 1. 0) to each other. It's hard to tell, but there's an example the image above, halfway up at 12 o'clock. I’ve seen them since last month, so, nothing special. Only now, they usually break free of each other, and are sometimes hit in collisions too. There are a few other wierdities, like occasional long range collisions.

Overall, stability is improved. The boids are now "tangible". The radii act as margins preventing the production of high accelerations. I tended to use radii between 1 and 10 in working the bounces. Size makes for poor differentiation in this simulation. I haven't tried a very large single central object yet. I have increased velocity, and gravity, because of the improved stability.

I apologise for the awful code I posted on the 18th. The reference source used thus far is the same as I identified then, but of course the errors were mine. My first test worked by hiding many errors, identifying collisions by fluke. Well, with effort (and //misery too!), I finally saw as the console.creator intended: Beginning with the revelation - a multitude of NaN's caused by vector.length; (answer. it needs() after length).

ToDoHere:
1)Create a separate collide function _collide(). Move citation. In this.gravAndChargeRepulsion,
a new _collide() would be  used for collision detection; maybe it can be as simple as a flag or two. From this.move, _collide() would be the same as here, used to confirm collisions, and if true, calculate reactions. Presently, the Alerts below identify: a) the rare set (< the number  of boids) of collide===true which occurred for me on two startups. b) Negative distances also occurred during view position changes. In my observation - after running many hours in the background, just a few sqSideT and sqSideF fails. As should be expected. They don't affect the simulation, it's just an observation. approxMoveVec and moveVec are almost the same. Easy enough to find out;
2) Find out;
3) Everything is still in debug over-expanded form; Too many variables.
4) All the errors still waiting. Like the occasional collision and one, two move, separated by many units, (50 or more).
4) Need collision sounds, great for monitoring the rate of collisions. And a counter(?).
5) This too is just a start. A vital and necessary one to move forward.
6) Spins. Will need to also transfer angular momentum.

///////////// this.move = function ()////////////////////
// Thanks to the overall, great n-particle engine, three.js canvas_geometry_birds
// found at http://threejs.org. Also thanks to the "Pool Hall Lessons: Fast, Accurate
// Collision Detection Between Circles or Spheres"
// http://www.gamasutra.com/view/feature/131424/pool_hall_lessons_fast_accurate_.php

this.move = function () {

if ( collide === true ) {
boid = boids [counter];
// Use the true particle velocity, and the collision candidate
// boid. The other collision candidate is - this.(). D'oh meta!

var vectorC = new THREE.Vector3();
vectorC.subVectors(boid.position,this.position );
var distance = boid.position.distanceTo( this.position );
// distance - used during debug as a sanity check. With or
// without the alert("Working test distance = " + distance );

vecCSquared = vectorC.length() * vectorC.length();
var moveVec = new THREE.Vector3();
var diffVec = new THREE.Vector3();
// diffVec = ( boid.velocity - this.velocity );
// diffVec is the two-moving sphere case.
diffVec.copy(boid.velocity);
diffVec.sub(this.velocity);
// refQ: If the length of the moveVec is less than the
// refQ: distancebetween the centers of these circles
// refQ: minus their radii, there's no way they can hit.
if( moveVec.lengthSq < distSq ){
_acceleration.set( 0, 0, 0 );
collide = false;
alert("Test 1 moveVec.lengthSq is less than distSq " + moveVec.lengthSq +"   " + distSq );
};

var vectorN = new THREE.Vector3();
// Normalize the moveVec
vectorN.copy(moveVec);
vectorN.normalize();
//// sideD = vectorN . C = ||C|| * cos(angle between N and C)
var sideD = vectorN.dot(vectorC);
if(sideD <= 0){
_acceleration.set( 0, 0, 0 );
collide = false;
alert("Test 2. sideD < 0 " + sideD );
}

var sqSideF = (vectorC.length() * vectorC.length()) - (sideD * sideD);
_acceleration.set( 0, 0, 0 );
collide = false;
};

// refQ: If there is no such right triangle with sides length of
// refQ: sumRadii and sqrt(sqSideF), T sideT will probably be less than 0.
// refQ: Better to check now than perform a square root of a
// refQ: negative number.
var sqSideT = sumRadiiSquared - sqSideF;
if(sqSideT < 0){
_acceleration.set( 0, 0, 0 );
collide = false;
alert("Test 4. sqSideT < 0. sqSideT = " + sqSideT );
};

// refQ: Therefore the distance the circle has to travel along
// refQ: moveVec is sideD - sqrt(sqSideT)
var dist2Touch = sideD - Math.sqrt(sqSideT);
// refQ: Get the magnitude of the movement vector
var mag = moveVec.length();
// refQ: Finally, make sure that the distance A has to move
// refQ: to touch B is not greater than the magnitude of the
// refQ: movement vector.
if( mag < dist2Touch ){
_acceleration.set( 0, 0, 0 );
collide = false;
alert("Test 5. mag < dist2Touch" + mag +"   " + dist2Touch );
};

// refQ: Set the length of the movevec so that the circles
// refQ: will just touch.
var moveVecToContact = new THREE.Vector3();
moveVecToContact.copy(moveVec);
// Keep the velocity vector intact
moveVecToContact.normalize();
moveVecToContact.multiplyScalar(dist2Touch);
var mag2 = moveVecToContact.length();
var frameBreak = mag2/mag;
// frameBreak is a number between 0 and 1. This
// represents the point in time (as a fraction
// of moveVec's possible extension as well as the
// current frame) the circles touched.
var thisHereVelocity = new THREE.Vector3();
thisHereVelocity.copy(this.velocity);
thisHereVelocity.multiplyScalar(frameBreak);
//this particle should be in position.

var copyBoidVelocity = new THREE.Vector3();
copyBoidVelocity.copy(boid.velocity);
copyBoidVelocity.multiplyScalar(frameBreak);
// boid should also be in position.

// Determine collision reaction. Still mainly
// as described in the source document.
// refQ: First, find the normalized vector n from the
// refQ: center of circle 1 to the center of circle2
var vectorCNC = new THREE.Vector3();
vectorCNC.copy(this.position);
vectorCNC.sub(boid.position);
vectorCNC.normalize();

// refQ: Find the length of the vectorCNC component
// refQ: of each of the movementvectors along n.
var a1 = this.velocity.dot(vectorCNC);
var a2 = boid.velocity.dot(vectorCNC);
// refQ: a2 = v2 . n
// refQ: float a1 = v1.dot(n);
// refQ: float a2 = v2.dot(n);

// refQ: Using the optimized version,
// refQ: optimizedP =  2(a1 - a2)
// refQ:               -----------
// refQ:                 m1 + m2
// refQ: float optimizedP = (2.0 * (a1 - a2)) / (circle1.mass +
// refQ: circle2.mass);
var optimizedP;
optimizedP = (2.0 * (a1 - a2))/(this.mass + boid.mass);
// refQ: Calculate v1', the new movement vector of circle1
// refQ: v1' = v1 - optimizedP * m2 * n
// refQ: vectorNewV = this.velocity - optimizedP * circle2.mass * n;

var vectorV1Bounce = new THREE.Vector3();
vectorV1Bounce.copy(vectorCNC);
vectorV1Bounce.multiplyScalar(optimizedP*boid.mass);
var newThisVelocity = new THREE.Vector3();
newThisVelocity.copy(this.velocity);
newThisVelocity.sub(vectorV1Bounce);
this.velocity.copy(newThisVelocity);
newThisVelocity.multiplyScalar(1-frameBreak);

var vectorV2Bounce = new THREE.Vector3();
vectorV2Bounce.copy(vectorCNC);
vectorV2Bounce.multiplyScalar(optimizedP*this.mass);
var newThisVelocity2 = new THREE.Vector3();
newThisVelocity2.copy(boid.velocity);
boid.velocity.copy(newThisVelocity2);
// boid.velocity.multiplyScalar(1-frameBreak);
// boid.velocity.multiplyScalar(1/(1-frameBreak));
// boid is advanced to contact, but not further,
// testing air-gap rebounds

_acceleration.set( 0, 0, 0 );
collide = false;
counter = -1;

}
else {

_acceleration.set( 0, 0, 0 );
};

if ( this.position.y >   _height ) this.position.y = - _height;
if ( this.position.y < - _height ) this.position.y =  _height;
if ( this.position.z >  _depth ) this.position.z = - _depth;
if ( this.position.z < - _depth ) this.position.z =  _depth;
};

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

I’m still working the collision stuff. Like eliminating penetrations. As you can see, I’m close to mastering the line-slope-intercept! Yes, implementing perfectly elastic 3d spherical collisions has been fairly straightforward:
1) Find the collision point, (use interpolation);
2) Move the two spheres along their velocity vectors to just "touch";
3) Find the contact plane and the normal between the two spheres;
4) Exchange linear momentum. Velocities parallel to the contact plane are unaffected, while velocities perpendicular to the plane are basically exchanged;
5) Move boids along their new velocities to their post collision positions.

The missing step - Exchange angular momentum.

Up to now, I've stuck to vectors. Points, positions, velocities, and accelerations are all vectors, although (of course) not all vectors are mathematically equal. (Miles has extensively described many of mainstream’s misuse of vectors). Angular momentum is directly analogous to linear momentum, with angular: mass, inertia, velocity and acceleration. The two momentums are entirely separate – though I’m on the record looking for where they can interact, beside any off-center collision. Solving the rotational system involves additional complexity, like following the correct ‘order of rotations’. Suffice to say, all the math used to exchange angular momentum that I’ve come across thus far is exceedingly difficult. If I knew what I was doing, I would say, “buck up, start enjoying matrix algebra”.

Please, there’s got to be a simpler way.

Both linear and angular momenta transfer forces through a contact point. Well, actually the contact area. Infinitesimal points do not exist and real objects deform; and friction... I’ll try again.

Observe the expected contact areas of two spheres just before they collide. I’ll list what I think are the few cases:
1.a. No spins. Head-on collision. Both contact areas approach each other without changing their angular position. The contact areas just clap together at the difference velocity of both spheres (like velocities of 1 and -1 meet with a difference velocity of 2). While all linear momenta may be transferred, there is no angular momenta present.
1.b. No spins. Off-center collision. The contact areas of the two spheres come together with equal and opposite translational surface velocities parallel to and not greater than the difference velocity of both spheres. Again there is no angular momenta (? I don't believe this. I 'll doublecheck, since off-center hits cause angular rotations).
2.a. Spins. Head-on collision. Both contact areas approach each other without changing their relative angular position. The contact areas just clap together. This is only possible if the contact area includes a pair of equal and opposite spin-axis anti-poles. Note that the rotational velocity is independent of the spheres’ forward velocity.
2.b. Spins. Head-on collision. When the same spin-axis poles come together, the contact areas come together with a contact plane rotation equal to the combined rotations of both spheres.
2.c. All other collisions between spinning spheres involve both the addition of parallel, forward translational parallel velocities; and another spin based surface velocity set that also varies velocities from zero to two. A zero differential surface velocity can occur during a glancing surface collision – actually more like a gentle rolling contact between two side-by-side anti-parallel spin-axis spheres on a plane containing both equators. The maximum velocity differential occurs between two side-by-side parallel spin-axis, the translational velocity in that opposite extreme case can reach four. A large variation.

The point I’m trying to make is that each surface point has a unique set of surface velocity variations that can define any sphere moving and spinning through space. I believe those additional vectors will allow a complete vector solution to collisions involving both linear and angular momenta.

Wishful thinking?

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

Spin collisions are very difficult. I've reached the point you are at now and thought about the next step of introducing spin but haven't actually done it. I didn't need it for that particular project but have always had the idea of building a spin collision framework.

My suggestion is to keep it simple and add one thing at a time. Never work in angular units, always tangential velocities. Ignore inner spins, if you are heading towards stacked spins, until you need them (and you may not). A collision happens at a point, evaluate your spin values from that perspective. That point is the start of any velocity vectors you use whether they be linear or angular.

Your going to get into calculating angles between vectors and using some trig to figure out the resultant vector given 2 rotations. Compare the rotation axes of the particles: are they parallel or orthogonal or somewhere in between? Given the plane that the 2 axes are in, are they at equal levels (hitting at the equator of each particle) or are they at differing levels (hitting more at the top/bottom of the particles). These things effect how the collision happens.

You've posted some good diagrams already, keep working with those and just try to see the motions you are trying to work with. Look for any vectors or lines you can use to figure out things.

Good luck.

Nevyn

Posts : 1360
Join date : 2014-09-11

## Re: Simple Orbiter 2

Nevyn,
Thanks for the sanity check, and especially the constraint (no radians)!

In order to find actual collision points, I’m afraid one would need initial conditions and an axis rotation function – what I believe you recommended I avoid – and I agree.

I do have the boid object properties spin axis and rotation velocity (well, no rotVel yet actually, (say v=x at r=1)). We can estimate the spin tangential velocities through the relation, velAtLatitude = velAtEquator(cos(latitude)).

All vectors will be known, what better start?
.

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

I think you have misunderstood my statement. You can't avoid radians (and don't want to). All I meant is to avoid angular velocity values and stick to tangential velocity values. Keep everything straight as a good vector should be. Radians often give you horrible numbers but you can avoid that sometimes by working in units of PI. PI=180 degrees, PI/2=90, PI/4=45, etc, is much better than seeing 3.14, 1.57 or 0.707 although you will get used to reading radians if you keep at it long enough.

In your earlier posts, you had a picture of 2 spheres that were touching. The line between their centers is your baseline. Think of that line as being flat (along the X axis, say, but all I mean is that you consider the points to be the same in 2 dimensions and differ in the other). The collision point (assuming spheres of the same size, else divide accordingly) is half way along that line. Think of the collision point as being 0, 0, 0 and the baseline extends to either side of it in some dimension (X, say). Effectively, we have just created a translated and rotated coordinate system. This is just to think about, you won't need to create it in the math, it just helps to talk about the math by moving things to nice round numbers.

Now you need to figure out the direction of the spin axis of each particle with respect to the baseline. Find the angle between the baseline and the spin axis (the dot product, I think). If they are both perpendicular, ie 90deg, then you have an equator to equator collision. If an angle is less than 90 deg, then you are colliding near the top of that particle (but double check what a +ve rotation is in your 3D API as a <90 (actually it would be in radians, not degrees) value may mean you are colliding near the bottom rather than the top, I find it extremely helpful to create the points in the 3D scene so that you can see them and make sure they are where you expect).

Knowing the angle of attack allows you to calculate the tangential velocity from the collision point which allows you to determine the resultant velocity vectors. In the first instance, I would be tempted to just apply the resultant linear velocity vector to the existing linear velocity vectors and apply the resultant spin vector to the existing spin vectors. This will not lead to stacked spins but that is quite complicated and we don't really know how they work at this level. But it will allow you to fine tune the math and make sure you have that close to correct before complicating things.

That should get you thinking along the right lines. I haven't implemented anything this far along, but have thought about it a few times. Reading this thread makes me want to get back into the GPU code I wrote along these lines and extend it into a spin collision system.

Nevyn

Posts : 1360
Join date : 2014-09-11

## Re: Simple Orbiter 2

Copy. Sanity check negative; time order reversal too. It is fun (and miserable)! Treading carefully...

Before simulating convincing spin collisions, or laying claim to a charge field demo, one must see spinning!

This image shows seven boi”particles”ds (previously manifest as single spheres, spots, and flapping birds), each comprised of 6 spheres. All the individual particles have the same radius; larger means closer to the viewer. Each of the seven clusters contains a red and blue pair of spheres - the north/south spin axis, randomly generated. The other 4 colors are also random, and positioned at +/- : eWAxis and fBAxis. These two axii are duplicates and rotations of spinAxis around its z and x axii, not true orthogonal rotations. That results in the small mix of shapes shown. Just a little interest. Again, I want to see spinning.

As yet, there is none. Each particle orientation is fixed as it travels and bounces about.

Where are those wires?
.

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

Yes, they spin.

I’m happy to say that tribute to Miles and the rest of you now includes a fine set of marbles, built from circles, spheres and sprites. Several images are superimposed above, involving many hours of object/parent/child lessons; clearly the child in me won – BIG!

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

Looking good!

Cr6

Posts : 1085
Join date : 2014-08-09

## Re: Simple Orbiter 2

Thanks Cr6, I think they work like majic. Each is clearly visible, and when they're swarming they're every-which-way pretty. Of course their appearance doesn't make any difference in their behavior, but I'm not sure. The ortho shape is present in three of the four marbles, and it makes perfect sense. Each makes distinct visual spinwaves. Two spinrolling marbles make a case for spin stacking. I can easily see replacing them with all sorts of micro or macro objects.

Code:
`<script> var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight, SCREEN_WIDTH_HALF = SCREEN_WIDTH  / 2, SCREEN_HEIGHT_HALF = SCREEN_HEIGHT / 2; var camera, scene, renderer; var marble1, marble1s; var marble2, marble2s; var marble3, marble3s; var marble4, marble4s; var boid, boids, sphere, spheres, spot, spots; var nSphere, nSpheres, sSphere, sSpheres; var eSphere, eSpheres, wSphere, wSpheres; var fSphere, fSpheres, bSphere, bSpheres; var nSSphere, nSSpheres, eWSphere, eWSpheres; var fBSphere, fBSpheres;  var boxEdges; var stats;                    //if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); var hash = document.location.hash.substr( 1 ); if (hash) hash = parseInt(hash, 0); // TEXTURE WIDTH FOR SIMULATION tied to the menu // var WIDTH = hash || 16; var BYRDS = WIDTH; var PARTICLES = WIDTH;//Presents the current number of boids - Firefox doesn't show it.; var BOUNDS = 800, BOUNDS_HALF = BOUNDS / 2; //document.getElementById('boids').innerText = PARTICLES; function change(n) { location.hash = n; location.reload(); return false; } var options = ''; for (i=1; i<9; i++) { var j = Math.pow(2, i); options += '<a href="#" onclick="return change(' + j + ')">' + (j) + '</a> '; } document.getElementById('options').innerHTML = options;                         init();                                                animate(); function init() {                camera = new THREE.PerspectiveCamera( 55, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 ); camera.position.z = 600;  //Trying to add sound //var listener = new THREE.AudioListener(); //camera.add( listener );  controls = new THREE.OrbitControls( camera ); controls.damping = 0.2; controls.addEventListener( 'change', render ); scene = new THREE.Scene(); //scene.fog = new THREE.FogExp2( 0x9999ff, 0.00025 );//First try //couldn't see it  // LIGHT var light = new THREE.PointLight(0xffffff); var ambientLight = new THREE.AmbientLight( 0x222222 ); light.position.set(100,250,100); scene.add(light); scene.add(ambientLight); marble1s = []; marble2s = []; marble3s = []; marble4s = []; boids = []; spheres = []; nSpheres = []; sSpheres = []; eSpheres = []; wSpheres = []; fSpheres = []; bSpheres = []; nSSpheres = []; eWSpheres = []; fBSpheres = []; spots = []; //Show SpaceMarkers ////////////////////////////// var boxHW = 500; var boxHH = 500; var boxHD = 500; var cLine = 100; var lineMaterialR = new THREE.LineBasicMaterial( { color: 0xcc0000 , linewidth: 1.5 } ); var lineMaterialG = new THREE.LineBasicMaterial( { color: 0x00cc00 , linewidth: 1.5 } ); var lineMaterialB = new THREE.LineBasicMaterial( { color: 0x0000cc , linewidth: 1.5 } ); for ( var i = -1 ; i < 2; i = i + 2 ) { for ( var j = -1 ; j < 2; j = j + 2 ) { for ( var k = -1 ; k < 2; k = k + 2 ) { var originX = new THREE.Geometry(); originX.vertices.push(  new THREE.Vector3((i * boxHW), (j * boxHH), (k * boxHD)), new THREE.Vector3((i * (boxHW - cLine)), (j * boxHH), (k * boxHD))); var originXLeg = new THREE.Line( originX, lineMaterialR ); scene.add(originXLeg); var originY = new THREE.Geometry(); originY.vertices.push(  new THREE.Vector3((i * boxHW), (j * boxHH), (k * boxHD)), new THREE.Vector3((i * boxHW), (j * (boxHH - cLine)), (k * boxHD))); var originYLeg = new THREE.Line( originY, lineMaterialG ); scene.add(originYLeg); var originZ = new THREE.Geometry(); originZ.vertices.push(  new THREE.Vector3((i * boxHW), (j * boxHH), (k * boxHD)), new THREE.Vector3((i * boxHW), (j * boxHH), (k * (boxHD - cLine )))); var originZLeg = new THREE.Line( originZ, lineMaterialB ); scene.add(originZLeg); } } } ///////////Grid Helpers////////////// var gridXZ = new THREE.GridHelper(boxHH, 100); gridXZ.setColors( new THREE.Color(0x006600), new THREE.Color(0x006600) ); gridXZ.position.set( 0,-boxHH,0 ); //scene.add(gridXZ); var gridXZ2 = new THREE.GridHelper(boxHH, 100); gridXZ2.setColors( new THREE.Color(0x006600), new THREE.Color(0x006600) ); gridXZ2.position.set( 0,boxHH,0 ); //scene.add(gridXZ2); var gridXY = new THREE.GridHelper(boxHD, 100); gridXY.position.set( 0,0, -boxHD ); gridXY.rotation.x = Math.PI/2; gridXY.setColors( new THREE.Color(0x000066), new THREE.Color(0x000066) ); //scene.add(gridXY); var gridXY2 = new THREE.GridHelper(boxHD, 100); gridXY2.position.set( 0,0, boxHD ); gridXY2.rotation.x = Math.PI/2; gridXY2.setColors( new THREE.Color(0x000066), new THREE.Color(0x000066) ); //scene.add(gridXY2); var gridYZ = new THREE.GridHelper(boxHW, 100); gridYZ.position.set( boxHW, 0, 0 ); gridYZ.rotation.z = Math.PI/2; gridYZ.setColors( new THREE.Color(0x660000), new THREE.Color(0x660000) ); //scene.add(gridYZ); var gridYZ2 = new THREE.GridHelper(boxHW, 100); gridYZ2.position.set( -boxHW, 0, 0 ); gridYZ2.rotation.z = Math.PI/2; gridYZ2.setColors( new THREE.Color(0x660000), new THREE.Color(0x660000) ); //scene.add(gridYZ2); /////////////////////////  for ( var i = 0; i < BYRDS; i ++ ) { boid = boids[ i ] = new Boid(); //boid.position.x = (i*3)-300; //boid.position.y = (i*2.5)-250; //boid.position.z = (i*1.5)-150; //boid.position.x = 0; //boid.position.y = 0; //boid.position.z = 0; boid.position.x = Math.random() * 750 - 375; boid.position.y = Math.random() * 750 - 375; boid.position.z = Math.random() * 750 - 370; boid.velocity.x = (Math.random()-0.5)*2; boid.velocity.y = (Math.random()-0.5)*2; boid.velocity.z = (Math.random()-0.5)*2; boid.setAvoidWalls( true ); //Don't need walls. Will default to wraparound; boid.setWorldSize( 800, 400, 400 );                     boid.mass = 1; boid.radius = 5;                    boid.charge = 1;                    //boid.gravity = 2;  boid.gravity = 8/BYRDS;  // boid.gravity should be adjusted as the # of boids varies.;  // Current thinking: For boid.length x, then boid.gravity =: // x gravity ;  // 2 4 ; // 3 2.67 ; // 4 2 ; // 8 1 ; // 16 0.5 ; // 32 0.25 ; // 64 0.125 ; // 128 0.0625 ; // 256 0.03125 ; // gravity = 8/x ;                    // Doubling g from these values (ie. x*g=16)results in high velocities,; // explosive collapses and spinouts. Unstable? But it ;  // doesn't make sense to me to add x expansion fields directly.; // This x*gravity=8 seems real after several hours of observation.; //spinning objects.  boid.spinAxis = new THREE.Vector3(); boid.spinAxis.x = Math.random() * 2 - 1; boid.spinAxis.y = 1; boid.spinAxis.z = Math.random() * 2 - 1; boid.spinAxis.normalize();  //making a sprite var PI2 = Math.PI * 2; var program = function ( context ) { context.beginPath(); context.arc( 0, 0, 0.5, 0, PI2, true ); context.fill(); }  //Sprites var material = new THREE.SpriteCanvasMaterial( { color: Math.random() * 0xfafbfc, program: program } ); spot = spots[ i ] = new THREE.Sprite( material ); spot.position.set(boid.position); spot.scale.x = spot.scale.y = (boid.radius * 2.25); scene.add( spot ); //Sphere parameters: radius, segments along width, segments along height var sphereGeom =  new THREE.SphereGeometry( boid.radius, 4, 4 );  //var darkMaterial = new THREE.MeshBasicMaterial( { color: 0xafafaf } ); var darkMaterial = new THREE.MeshBasicMaterial( { color: Math.random() * 0x808080 + 0x808080 } ); //var darkMaterialL = new THREE.MeshLambertMaterial( { color: 0x000080 } ); //var darkMaterialP = new THREE.MeshPhongMaterial( { color: 0x000080 } ); sphere = spheres[ i ] =  new THREE.Mesh( sphereGeom, darkMaterial ); sphere.position.set(boid.position); //scene.add( sphere );  ///////////////////////////////////////////////// //marbles marble1 = marble1s[ i ] = new THREE.Object3D(); marble1.position.set( boids[ i ].position ); marble2 = marble2s[ i ] = new THREE.Object3D(); marble2.position.set( boids[ i ].position ); marble3 = marble3s[ i ] = new THREE.Object3D(); marble3.position.set( boids[ i ].position ); marble4 = marble4s[ i ] = new THREE.Object3D(); marble4.position.set( boids[ i ].position );  boid.spinPoles = new THREE.Vector3(); boid.spinPoles.copy(boid.spinAxis); boid.spinPoles.multiplyScalar(boid.radius);  var poleGeom =  new THREE.SphereGeometry( boid.radius/2, 3, 3 ); var nPoleMaterial = new THREE.MeshBasicMaterial( {  color: 0xcc0000 } ); var sPoleMaterial = new THREE.MeshBasicMaterial( {  color: 0x0000cc } ); var ePoleMaterial = new THREE.MeshBasicMaterial( {  color: Math.random() * 0xfafbfc } ); var wPoleMaterial = new THREE.MeshBasicMaterial( {  color: Math.random() * 0xfafbfc } ); var fPoleMaterial = new THREE.MeshBasicMaterial( {  color: Math.random() * 0xfafbfc } ); var bPoleMaterial = new THREE.MeshBasicMaterial( {  color: Math.random() * 0xfafbfc } ); nSphere = nSpheres[ i ] =  new THREE.Mesh( poleGeom, nPoleMaterial ); sSphere = sSpheres[ i ] =  new THREE.Mesh( poleGeom, sPoleMaterial ); eSphere = eSpheres[ i ] =  new THREE.Mesh( poleGeom, ePoleMaterial ); wSphere = wSpheres[ i ] =  new THREE.Mesh( poleGeom, wPoleMaterial ); fSphere = fSpheres[ i ] =  new THREE.Mesh( poleGeom, fPoleMaterial ); bSphere = bSpheres[ i ] =  new THREE.Mesh( poleGeom, bPoleMaterial );  var CircleGeometry = new THREE.CircleGeometry( boid.radius, 9 );  var nCircle = new THREE.Mesh( CircleGeometry, nPoleMaterial ); nCircle.rotation.x = -90 * Math.PI/180; var sCircle = new THREE.Mesh( CircleGeometry, sPoleMaterial ); sCircle.rotation.x = 90 * Math.PI/180;  var eCircle = new THREE.Mesh( CircleGeometry, ePoleMaterial ); eCircle.rotation.y = 90 * Math.PI/180;  var wCircle = new THREE.Mesh( CircleGeometry, wPoleMaterial ); wCircle.rotation.y = -90 * Math.PI/180;  var fCircle = new THREE.Mesh( CircleGeometry, fPoleMaterial ); //fCircle.rotation.y = 0;  var bCircle = new THREE.Mesh( CircleGeometry, bPoleMaterial ); bCircle.rotation.x = 180 * Math.PI/180;  nSphere.position.y = boid.radius/2;  sSphere.position.y = -boid.radius/2; eSphere.position.x = boid.radius/2; wSphere.position.x = -boid.radius/2; fSphere.position.z = boid.radius/2; bSphere.position.z = -boid.radius/2; //var nCircle1.copy(nCircle); marble1.add( nCircle ); marble1.add( sCircle ); marble1.add( eCircle ); marble1.add( wCircle );  marble1.add( fCircle );  marble1.add( bCircle );  //scene.add( marble1 );   marble2.add( nSphere );  marble2.add( sSphere );  marble2.add( eSphere ); marble2.add( wSphere ); marble2.add( fSphere ); marble2.add( bSphere ); //scene.add( marble2 );  var coreMaterial = new THREE.MeshBasicMaterial( {  color: Math.random() * 0xfafbfc } ); var coreBackMaterial = new THREE.MeshBasicMaterial( {  color: Math.random() * 0xfcfbfa } ); var CircleGeometry = new THREE.CircleGeometry( boid.radius, 9 );  for ( var j = 0; j < 3; j ++ ) { var coreCircle = new THREE.Mesh( CircleGeometry, coreMaterial ); coreCircle.rotation.x = j * 120 * Math.PI/180; marble3.add( coreCircle ); var coreBackCircle = new THREE.Mesh( CircleGeometry, coreBackMaterial ); coreBackCircle.rotation.x = j * 120 * Math.PI/180; coreBackCircle.rotation.y = 180 * Math.PI/180;  marble3.add( coreBackCircle ); }  scene.add( marble3 );  //var nSSphereMaterial = new THREE.MeshBasicMaterial( {  color: Math.random() * 0xfafbfc } ); //var eWSphereMaterial = new THREE.MeshBasicMaterial( {  color: Math.random() * 0xfafbfc } ); //var fBSphereMaterial = new THREE.MeshBasicMaterial( {  color: Math.random() * 0xfafbfc } ); //nSSphere = nSSpheres[ i ] =  new THREE.Mesh( // new THREE.SphereGeometry( boid.radius, 8, 8 ), nSSphereMaterial); //nSSphere.scale.x = 0.1; //nSSphere.scale.y = 1.0; //nSSphere.scale.z = 0.1; //nSSphere.rotation.y = 30* Math.PI/180; //eWSphere = eWSpheres[ i ] =  new THREE.Mesh( // new THREE.SphereGeometry( boid.radius, 8, 8 ), eWSphereMaterial); //eWSphere.scale.x = 1; //eWSphere.scale.y = 0.1; //eWSphere.scale.z = 0.1; //fBSphere = fBSpheres[ i ] =  new THREE.Mesh( // new THREE.SphereGeometry( boid.radius, 8, 8 ), fBSphereMaterial); //fBSphere.scale.x = 0.1; //fBSphere.scale.y = 0.1; //fBSphere.scale.z = 1; //marble4.add( nSSphere ); //marble4.add( eWSphere ); //marble4.add( fBSphere ); //scene.add( marble4 ); // Will probably delete above. The pin axis will change over time even  // without collisions.. I guess it doesn't make sense to try to  // rotate the sphere this way. Spin axis changes will occur //   //Sphere parameters: radius, segments along width, segments along height var sphereCGeom =  new THREE.SphereGeometry( boid.radius, 4, 4 );  //var darkMaterial = new THREE.MeshBasicMaterial( { color: 0xafafaf } ); var darkCMaterial = new THREE.MeshBasicMaterial( { color: Math.random() * 0x808080 + 0x808080 } ); //var darkMaterialL = new THREE.MeshLambertMaterial( { color: 0x000080 } ); //var darkMaterialP = new THREE.MeshPhongMaterial( { color: 0x000080 } ); nSSphere = nSSpheres[ i ]; nSSphere =  new THREE.Mesh( sphereCGeom, darkCMaterial ); nSSphere.scale.x = 0.1; nSSphere.scale.y = 1.0; nSSphere.scale.z = 0.1;  eWSphere = eWSpheres[ i ]; eWSphere =  new THREE.Mesh( sphereCGeom, darkCMaterial ); eWSphere.scale.x = 1; eWSphere.scale.y = 0.1; eWSphere.scale.z = 0.1;  fBSphere = eWSpheres[ i ]; fBSphere =  new THREE.Mesh( sphereCGeom, darkCMaterial ); fBSphere.scale.x = 0.1; fBSphere.scale.y = 0.1; fBSphere.scale.z = 1;  marble4.add( nSSphere ); marble4.add( eWSphere ); marble4.add( fBSphere );  //scene.add( marble4 );  }                         renderer = new THREE.CanvasRenderer(); //renderer.setClearColor( 0x000000 ); //renderer.setClearColor( 0x0000af ); renderer.setClearColor( 0xffffff ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT ); //document.addEventListener( 'mousemove', onDocumentMouseMove, false ); document.body.appendChild( renderer.domElement ); stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById( 'container' ).appendChild(stats.domElement); window.addEventListener( 'resize', onWindowResize, false ); ////////////////////////////////// var gui = new dat.GUI(); var parameters =  { a: 200, // numeric b: 200, // numeric slider c: "Hello, GUI!", // string d: false, // boolean (checkbox) e: "#ff8800", // color (hex) f: function() { alert("Stop!") }, g: function() { alert( parameters.c ) }, v : 0,    // dummy value, only type is important w: "...", // dummy value, only type is important x: 0, y: 0, z: 0 };  ///////////////////////////////////////////////////// //gui.add( parameters ) gui.add( parameters, 'a' ).name('Number'); gui.add( parameters, 'b' ).min(128).max(256).step(16).name('Slider'); gui.add( parameters, 'c' ).name('String'); gui.add( parameters, 'd' ).name('Boolean');  gui.addColor( parameters, 'e' ).name('Color');  var numberList = [1, 2, 3]; gui.add( parameters, 'v', numberList ).name('List');  var stringList = ["One", "Two", "Three"]; gui.add( parameters, 'w', stringList ).name('List');  gui.add( parameters, 'f' ).name('Please "Stop!"'); gui.add( parameters, 'g' ).name("Alert Message");  var folder1 = gui.addFolder('Coordinates'); folder1.add( parameters, 'x' ); folder1.add( parameters, 'y' ); folder1.close(); gui.close();  } /////////////////////////////////////////////////////  function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } function animate() { requestAnimationFrame( animate ); render(); stats.update(); }  function render() { for ( var i = 0, il = boids.length; i < il; i++ ) { boid = boids[ i ]; boid.run( boids ); spheres[ i ].position.copy( boids[ i ].position );  spot = spots[ i ]; spot.position.copy( boids[ i ].position ); marble1 = marble1s[i]; marble1.position.copy( boids[ i ].position ); marble1.rotateOnAxis (boid.spinAxis, 5 * Math.PI/180); marble2 = marble2s[i]; marble2.position.copy( boids[ i ].position ); marble2.rotateOnAxis (boid.spinAxis, 5 * Math.PI/180);  marble3 = marble3s[i]; marble3.position.copy( boids[ i ].position ); marble3.rotateOnAxis (boid.spinAxis, 5 * Math.PI/180);  marble4 = marble4s[i]; marble4.position.copy( boids[ i ].position ); marble4.rotateOnAxis (boid.spinAxis, 5 * Math.PI/180);  } renderer.render( scene, camera ); } </script>`

Here's the init loop script. It seems more like a collection of ideas at present. I'm way behind. This last week was trying to restructure this.move. The joy was in having backup copies.

Thanks Nevyn, These models do have a way of multiplying one's understanding.

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

I’d like to call attention to a gem from The American Journal of Physics, vol. 37, no. 1, January 1969, Kinematics of an Ultraelastic Rough Ball. http://www.rpi.edu/dept/phys/courses/PHYS1150/GarwinSuperBall.pdf. The math is turning out to be a favorite - translational and angular momentum exchanges in collisions between a superball and stationary surfaces – well, maybe someday. The analysis is clear and leads to an Ultraelastic Rough collision matrix.

The paper’s biggest surprise, I think it’s fair to say, is oscillation between translational and angular velocities from one collision to the next. The first bounce converts translational velocity to angular velocity, which is converted back to translational velocity after the next bounce. In effect, superballs take extra - almost vertical - bounces to get to wherever they’re going - translationally, compared with ‘normal’ balls. I guess that accounts for the “Ultra” in the paper’s title. If I understand correctly, the difference isn’t due to ‘slip’, it’s due to asynchronous energy reaction periods relating to the mass density distribution within the sphere … ? I’ll keep it in mind.

OK, Pop Quiz.

Inspector Clouseau leans on a globe,
in which direction will he go?

The trick answer is - east. We all travel east as the world turns below us. The answer I’m looking for is east or west, as the globe, fixed on its N-S axis is free to turn only in the E-W ‘directions’. The globe’s resulting angular velocity is due to the tangential acceleration provided by Clouseau’s elbow.

When two spheres collide, the primary sources of angular momentum are the two collision latitude tangential velocities. I’ll assert that these two velocities are the primary directions, even though they don’t usually align and I don’t understand how they interact yet.

We also have the translational velocity vectors that are ignored in the linear energy exchange, since they are in the contact plane. These must be replaced with new projections parallel or perpendicular to the tangential velocities. They remain within the contact plane to add or subtract from the main tangential vectors.

I think I'll begin by exchanging these velocity vectors within the existing spin axii. If there is not enough existing angular momenta to cover the exchange, then I guess the spin axis orientation should somehow make up the difference.

Note. I’m coming full circle. How does a sphere respond to the charge field? Does it get slowed down to the point where the spin axis begins to change? I see now how a charge differential front to back may speed-up or slow–down transverse tangential velocities. I can also see the same differential turning the spin axis. In my optimistic viewpoint, the charge field differential mechanism flows seamlessly to these collisions.

That's where I'm at.

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

Quick update. I've started coding the Angular Momentum Exchange shown above. I have both sets of latVels and transVels.

Next, I'll project each sphere's set to the other. It's too soon to share the code.

Last edited by LongtimeAirman on Fri Feb 19, 2016 7:40 pm; edited 1 time in total (Reason for editing : Correcting bottom right diagram)

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

Very ambitious and cool to boot.
I just wanted to throw out these links if it helps any with the new library:
Four dimensional rational spherical coordinates (Chapter 27 of Divine Proportions)

http://web.maths.unsw.edu.au/~norman/papers/Chapter27.pdf
http://milesmathis.forumotion.com/t42-quaternions

Cr6

Posts : 1085
Join date : 2014-08-09

## Re: Simple Orbiter 2

Cr6, "Ambitious"? Maybe single-mindedness – must be a vector solution - "and cool to boot". Yes, SO2 is already a nice particle engine.

There are many ways to use or improve it. With just randomly placed spinning marbles and linear collisions it looks and works better than I'd hoped. Of course there are still plenty of bugs. Maybe I should clean it up as is and upload it to GitHub as thanks for Birds. I could also change it to pursue my own game ideas; believe it or not, my goal (25 years ago) was to program a 3D pool game, but for lack of a compiler (s/w) I changed my hobby to stained glass/metal sculpture instead.

I wouldn’t consider SO2 finished until Nevyn or you told me it was. On the practical side, I’ll see if the angular collisions are working or not. I also believe the continuum - charge differential to tangential velocity to collisions – should be elegant. And stacking spins, I’m nowhere near stacking spins yet, except maybe I am.  How many discreet spins should a marble have anyway?

Thanks for reminding me that rational trigonometry should be part of the solution. While I declare that the latitudinal velocity is the mainline, what happens if the spin velocity is low, or the latitude is close to the spin Axis pole? At what ‘rate’ will the translational velocity become the mainline. Will conversion to quaternions enable me to directly add the two?

I jumped into the blue with a good deal of math trepidation and joy. Did you throw a jet pack at me? Are you working on Library ideas?

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

LTAM, I just have always found  Sine, Cosine, Tangent, etc. as "lookup book values" that maybe Rational Trig could give a more simplified approach in some cases? It would be a lot of work to make a new Javascript library that could imitate something like three.js with Rational Trig but down the road it might provide flexibility for matrix math (hits/direction/rotation/speed), etc. If I'm rambling, I blame the Whiskey.

https://en.wikipedia.org/wiki/Lookup_table#Computing_sines

This book has a few indications of classical "QT" electron matrix math with eigenvalues. The math is "waaayy tooo deeep" for my humble abilities.
C. Graaf and R. Broer,
Magnetic Interactions in Molecules and Solids
Theoretical Chemistry and Computational Modelling

Chapter 1:
1.2 Generation of Many Electron Spin Functions
1.2.1 Many Electron Spin Functions by Projection
----

Can't say that I've ever made a practical "kitchen sink" from these random ideas.
While I declare that the latitudinal velocity is the mainline, what happens if the spin velocity is low, or the latitude is close to the spin Axis pole? At what ‘rate’ will the translational velocity become the mainline. Will conversion to quaternions enable me to directly add the two?
Good questions, and is the program built for the viewer or just the objects without a viewer?

Cr6

Posts : 1085
Join date : 2014-08-09

## Re: Simple Orbiter 2

Nevyn, I'm happy with the results of this project so far. I’ve presented bits and pieces of Simple Orbiter as evidence of progress, certain you or someone at home could reassemble them, and, with half a mind, do better.

Have you or Cr6 seen this thing? I’d hate it if some danged old newby died hogging a Charge Field simulation waiting for angular inspiration.

I’d like to post a first draft.  Maybe organize it a bit. As you know, this project is far from finished. I intend to do as good a job as I’m able and turn it over to you. I’d appreciate any instructions you may have for me toward that end.

For the last month I’ve been in virtual orbit. I’m better prepared to share discussion and interpretations on the subject of the interaction of charged particles.
.

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

Cr6,
Nevyn PMed me to zip and send Simple Orbiter to him, so I did. I would have sent it to you but MM the Site won’t let me attach zip files. Worse, my mail server doesn’t have any messages from you. I word searched your name in my files and hit on compendium, but no further. I’ve been whiling away time going through your 15MB monster – how do you navigate through it? Lots of additional stuff, and I do love the pictures.
Send me a gmail message so I can send SO2 to you too. Then be amazed!

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

LongtimeAirman wrote:Cr6,
Nevyn PMed me to zip and send Simple Orbiter to him, so I did. I would have sent it to you but MM the Site won’t let me attach zip files. Worse, my mail server doesn’t have any messages from you. I word searched your name in my files and hit on compendium, but no further. I’ve been whiling away time going through your 15MB monster – how do you navigate through it? Lots of additional stuff, and I do love the pictures.
Send me a gmail message so I can send SO2 to you too. Then be amazed!

Okay LTAM,

Let me send you all my personal email in a PM. I don't know if I'll be much help with three.js issues. I'll have to defer to Neyvn's powers with that one.

I did look over mrdoob's github entries and noticed he makes fairly frequent updates. There's always a potential situation where you might stumble on to a bug in one of the libraries -- a lot of it looks taken from good 3-D C++ libraries built in the past. I should have looked at this closer before posting my prior post. Looks like three.js is using Quaternions/Slerp/etc. routines. I guess I better shut my mouth.

The only question is, do we have everything needed in three.js to represent Mathis' spin mechanics/collisions?

By the way, I'm fully cognizant of the time and effort it takes to "create" an original work programming this. Nevyn's work and your work here just simply impresses.

https://github.com/mrdoob/three.js/tree/master/src/math

Cr6

Posts : 1085
Join date : 2014-08-09

## Re: Simple Orbiter 2

Cr6, Zip launched, message deleted (or not saved anyway).

We're friends here.  A new first draft, feel free to break it.

Enjoy
.

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

Cr6 wrote:
The only question is, do we have everything needed in three.js to represent Mathis' spin mechanics/collisions?

Yes, everything required is in ThreeJS. Most of it is just math and decisions based on the mechanics. ThreeJS allows us to visualize it and also provides some handy things like vectors, matrices, quaternions, etc to help with the calculations.

My main question at the moment is what kind of system I want to build. You can look at it from really close up where you are watching a limited number of particles collide to get that fine detail of the collisions and how spins are gained/lost. On the other hand, you can look at it from afar where you have lots of particles colliding and you want to look at the field rather than the particles.

I want both but I think, at the moment, we all need a closer look at spin mechanics in action to get a better understanding of the quantum world. So I am leaning towards the former but I feel that the latter will kind of fall out of it. Once I have that spin mechanics behavior, I can apply it to other systems and it should be relatively easier to create the field model once I have the collision model. The difference is more to do with performance than anything else.

Nevyn

Posts : 1360
Join date : 2014-09-11

## Re: Simple Orbiter 2

Update

The particles already show a surprising range of spin behavior, including a slingshot effect. Two or more particles can whip around each other in constant contact for several ‘orbits’ before disappearing in some wild acceleration. I’ve tried to slow it down, but this is first draft. I thought I could somehow mirror or extend the action to the collisions.

“I’ll Try This!” immediately resulted in very high equatorial velocities. Translational velocities are easily converted to spin, while I have no mechanism to shed spin except through collision. To paraphrase a colleague, spins are hard.

I took a break from Boids. A non-stop politics binge. I want to be sick.

So, back to subject. I’ll put a couple of thoughts out there.

Pretty as it is, Boids is still mostly charged points. The unexpected spin behavior is not real.

Starting where I'm at, I think I can model close particle interaction as pre-e/m strength changes along quadrature lines (30N/30S/30E/30W), radially expanding, where the time or charge density is also dependent on the equatorial velocity, etc.

That drives the total number of particles down but I’d rather see a few as accurately as possible at this point.

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

Nevyn, Earlier in this thread, you shared your thoughts on the nature of tangential forces, http://milesmathis.forumotion.com/t128p15-simple-orbiter-2#991 :
This leads me to make some speculations:

The sum of spin on the charge photons can sum to zero. The tangential force vector would then be zero and provide no tangential velocity to any orbiting bodies. Our solar system has a 2:1 ratio of photons to anti-photons so it does not sum to zero. Are there solar systems that do not orbit but just sort of sit there as deep into the charge field of their star as possible? Would all of the planets cause each other to move based on their charge interactions?

If the tangential force is caused by an imbalance of charge to anti-charge, then the force is applied at either the top or the bottom of the orbiting body, not over its complete shell. This is not a nice clean push sideways. I think it would cause spin to a stationary orbiter. Therefore, the existing axial spin of the orbiter resists that spin and applies it as a torque to the whole body. That is, part of the force is used up working against the axial spin and the other part is allowed to express itself so the result is a sideways force.

The axial spin must be driven or it would soon stop. I think the axial spin is caused by the charge flowing through the orbiting body (north/south through-charge). Therefore the charge is working against itself (not the exact same photon but the mass of charge effecting the orbiter at a given time). This may result as heat and help explain the internal and external heat of planets.

On my next post http://milesmathis.forumotion.com/t128p15-simple-orbiter-2#996  I answered:
Nevyn, Thanks for your previous post. You shared several points that beg consideration and discussion. Let me get back to that when I include spin.

I hope you don't mind the delay. I’ve put a great deal of thought into the matter.

The sum of spin on the charge photons can sum to zero.
Sure, in a given system, the number of photons compared to the number of anti-photons can be equal. Or say, far enough away, the total charges in a volume sums to zero. But that’s not correct. It ignores matter, or even net charge flow. The energy present, high or low, may be independent of that sum.

The tangential force vector would then be zero and provide no tangential velocity to any orbiting bodies.
Disagree. Consider Miles’ diagram. The one where photons enter the south pole and leave at some small positive latitude - up to 30 deg, and anti-photons enter the north pole and exit the earth south of the equator. (The image service is gone. Or it isn't working for me).

It really doesn’t matter whether the total number of photons equal antiphotons or not. The earth is structuring charge flow such that photon and antiphoton tangential velocities complement when delivering forces about the equatorial plane. They reinforce, not cancel, tangential velocities for bodies orbiting the spin axis.

Would all of the planets cause each other to move based on their charge interactions?
And gravity too. I think so – absolutely. It’s a main premise of my model. If the sun were somehow plucked from the sky, our dominant objects, the gas giants would immediately begin to re-order the system.

The axial spin must be driven or it would soon stop.
I do not see this. Why would spin stop? Up or down photons entering their respective poles cause the same overall rotation direction. Granted, the spin is somehow tied to the energy level of the local charge field, but what determines a limit?

I think the axial spin is caused by the charge flowing through the orbiting body (north/south through-charge).
I believe that the axial spin of the dominant body, our sun, is caused by charge recycling. The Earth’s axial spin depends mainly on the sun’s tangential forces.

My question, also, I’ve really enjoyed Miles’ latest paper, including this new - spin on structure (sorry), so I’ll cite it as well, “ The Stark Effect”,  http://milesmathis.com/stark.pdf.
At any temperature above zero, charge will create structure, both in itself and in any material, even a gas.  To start with, the gas will align its poles to the applied field, to allow for better channeling at the atomic level.

What is the mechanism that aligns the spin axis to maximize direct polar channeling? It seems to be present at all scales, from electrons to galaxies.

LongtimeAirman

Posts : 1044
Join date : 2014-08-10

## Re: Simple Orbiter 2

Hi Airman,

I have a quick response for you but I may need to flesh out these answers a bit later when I have more time.

LongtimeAirman wrote:
Nevyn wrote:The sum of spin on the charge photons can sum to zero.
Sure, in a given system, the number of photons compared to the number of anti-photons can be equal. Or say, far enough away, the total charges in a volume sums to zero. But that’s not correct. It ignores matter, or even net charge flow. The energy present, high or low, may be independent of that sum.

Yes, it ignores matter because I was looking at the effects of charge on matter. If we wanted to find the total energy content then we would need to look at the matter present and factor that in but I was trying to look at what charge would do to the matter. I was only looking at the cause of the tangential vector, not what the vector is applied to. In that way, the sum of the spin on the charge photons can sum to zero and therefore there is no tangential force to cause a circular orbit.

LongtimeAirman wrote:
Nevyn wrote:The tangential force vector would then be zero and provide no tangential velocity to any orbiting bodies.
Disagree. Consider Miles’ diagram. The one where photons enter the south pole and leave at some small positive latitude - up to 30 deg, and anti-photons enter the north pole and exit the earth south of the equator. (The image service is gone. Or it isn't working for me).

It really doesn’t matter whether the total number of photons equal antiphotons or not. The earth is structuring charge flow such that photon and antiphoton tangential velocities complement when delivering forces about the equatorial plane. They reinforce, not cancel, tangential velocities for bodies orbiting the spin axis.

But I was not looking at the equatorial force. That is (mostly) irrelevant to the orbital motion of the body itself and only applies to bodies that orbit it. I say mostly irrelevant because the equatorial charge emission does interact with the incoming charge (from the body we are orbiting) to cause magnetospheres, charge pauses, etc, which may limit the amount or direction of charge that actually reaches the orbiting body.

I was suggesting that the through-charge, and the equatorial emission to a lesser extent, causes the spin of the body not its tangential motion to that which it is orbiting. It is the action upon the body, by the charge passing through it, that causes the axial rotation of that body because each individual photon has some spin.

LongtimeAirman wrote:
Nevyn wrote:Would all of the planets cause each other to move based on their charge interactions?
And gravity too. I think so – absolutely. It’s a main premise of my model. If the sun were somehow plucked from the sky, our dominant objects, the gas giants would immediately begin to re-order the system.

Yes, if we removed the sun then everything would adjust to orbit about jupiter (or possibly a jupiter and saturn binary system) but that isn't what I meant. I was thinking that an equal charge field (photons to anti-photons) would lead to no tangential forces for the orbiting bodies so they would find some equilibrium with all other bodies. This would leave them at a set distance from the central body but not circling around it.

LongtimeAirman wrote:
Nevyn wrote:The axial spin must be driven or it would soon stop.
I do not see this. Why would spin stop? Up or down photons entering their respective poles cause the same overall rotation direction. Granted, the spin is somehow tied to the energy level of the local charge field, but what determines a limit?

In a vacumm, the spin would not stop, but these bodies are not in a vacumm. They are constantly bombarded with charge from the central body and each other. This would reduce the spin component over time. Since we do not see a reduction in the spin of orbiting bodies then it must be driven by something.

LongtimeAirman wrote:
Nevyn wrote:I think the axial spin is caused by the charge flowing through the orbiting body (north/south through-charge).
I believe that the axial spin of the dominant body, our sun, is caused by charge recycling. The Earth’s axial spin depends mainly on the sun’s tangential forces.

If it causes spin on the main body then it must cause spin on orbiting bodies as well. I don't see why it would only work for the larger body but not the smaller ones.

As I understand it, Miles has suggested that the suns tangential forces (from its emission) cause the circular motion (in conjunction with gravity and charge emission pushing it away) not the axial rotation, although it may be a factor in it.

LongtimeAirman wrote:
My question, also, I’ve really enjoyed Miles’ latest paper, including this new - spin on structure (sorry), so I’ll cite it as well, “ The Stark Effect”,  http://milesmathis.com/stark.pdf.
Mathis wrote:At any temperature above zero, charge will create structure, both in itself and in any material, even a gas.  To start with, the gas will align its poles to the applied field, to allow for better channeling at the atomic level.

What is the mechanism that aligns the spin axis to maximize direct polar channeling? It seems to be present at all scales, from electrons to galaxies.

I'm not sure of this mechanism myself. I probably need to read this paper again and see if I still agree with my speculation.

Nevyn

Posts : 1360
Join date : 2014-09-11

## Re: Simple Orbiter 2

Thanks Nevyn. I do like your middle paragraph.

If the tangential force is caused by an imbalance of charge to anti-charge, then the force is applied at either the top or the bottom of the orbiting body, not over its complete shell. This is not a nice clean push sideways. I think it would cause spin to a stationary orbiter. Therefore, the existing axial spin of the orbiter resists that spin and applies it as a torque to the whole body. That is, part of the force is used up working against the axial spin and the other part is allowed to express itself so the result is a sideways force.

It’s exactly what I was asking for. A differentiation along the 30N/30S lines based upon relative resistance of a pole, as opposed to the general surface of the object. Miles also said that a pole provides a natural field “resistance”, paraphrasing again.

I think that’s close, aside from the first sentence conditional - I don’t believe an imbalance of up/down photons is necessary to generate pre-m tangential accelerations to a body in orbit. Also, I guess you’re talking gyroscopic torque.

Aligning spin poles to the charge field provides minimum resistance to the charge field lines. Minimum resistance makes more physical sense to me than "allow for better channeling", even though that is the result.

Definite aha moment!

Last edited by LongtimeAirman on Fri Mar 18, 2016 10:30 pm; edited 2 times in total (Reason for editing : Cleaned up sentence begining: I think that's close; and Minimum resistance)

LongtimeAirman

Posts : 1044
Join date : 2014-08-10