Animate the PI = 4 experiment
+2
Vexman
Cr6
6 posters
Page 2 of 8
Page 2 of 8 • 1, 2, 3, 4, 5, 6, 7, 8
Re: Animate the PI = 4 experiment
.
Quick update.
// this.trackCircumP = 2*Math.PI*this.r;
// this.trackCircumK = 8*this.r;
Everything looks good? More later.
.
Quick update.
Airman. Agreed. Here’s how the straight path in both the animatePassive and the animateDynamic functions compare.Nevyn wrote. You shouldn't need anything more than v=d/t for the straight section. We don't have any accelerations as used in those equations.
- Code:
// sphereS.position.x += this.forInc; // animatePassive
sphereS.position.x += dT*vel; // animateDynamic
Airman. Correct. I'm converting from one angle function to another so it's an easy task. The circumferences are calculated in daControlValues.Nevyn wrote. The curves will be more tricky…
// this.trackCircumP = 2*Math.PI*this.r;
// this.trackCircumK = 8*this.r;
- Code:
var dT = 0.024; // ???? This is a strange number? It seems to be a constant of some kind.
var T = this.increments*1.25*dT; // total time
var omegaG = 2*Math.PI; // Circumference G or K
var omegaK = 2 * 4 ;
var vel = 10 * this.r / T;
var angleC = vel*dT/this.trackCircumP;
// A = 2PI*v*t/(2*PI*r) angle a function of the circumference traveled.
var angleC = vel*dT/this.trackCircumP;
sphereC.position.set( this.r*Math.sin( angleC ), 0, this.r*Math.cos( angleC ));
Everything looks good? More later.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
- Code:
var dT = 0.024; // ???? This is a strange number? It seems to be a constant of some kind.
This is the time for this frame, in seconds. Which makes it about 40 frames per second. Strange choice. It doesn't really matter too much and can be used to control the speed of the animation. I would replace it with a fraction like 1/60 or 1/30.
- Code:
var T = this.increments*1.25*dT; // total time
Why is this line needed? You shouldn't need the total time in a dynamic calculation since it should only be thinking about the transition from the current position to the next. i.e. 1 frame.
What does the 1.25 stand for? I guess you are using it as the speed control since it is effectively changing the value of dT.
- Code:
sphereC.position.set( this.r*Math.sin( angleC ), 0, this.r*Math.cos( angleC ));
This will always rotate from a set position, it will not add to the current position. So if the ball is 1/4 way around the circle, adding another angle will not move it from that position, but will move if from 0 (which is usually the X dimension in a cartesion graph).
Think about creating a Quaternion from the angle. Apply the quaternion to the position vector of the ball.
Re: Animate the PI = 4 experiment
.
Hey Nevyn, I just saw your latest post, so I have yet to make any of your suggested changes.
One thing though, Explaining why everything looked good yesterday was that after copying and changing the title to animateDynamic, I hadn't changed the next line requesting an animation frame from animatePassive. Dumb.
So now I see that the two tracks do operate independently. And I'm where you asked me to be.
Ortho view, both spheres are almost at the finish lines – with the same rolls.
Airman. I converted the animatePassive into animateDynamic by finding the three variables: incremental time dT, total time T and straight velocity vel. Everything is running well. The image above shows the two spheres end the track with synchronized rolls.
I include the animateDynamic function below, but I’d like to focus on this inLoop section, the code that advances the sphere abound the circular path.
if ( this.inLoop ) {
this.curTrackAngle += this.angInc;
sphereC.rotation.y = this.curTrackAngle;
this.inLoopCounter += 1 ;
// var angleC = omegaG * vel*dT*this.inLoopCounter/this.trackCircumP; // maybe 5/4 too fast
// var angleC = omegaK * vel*dT*this.inLoopCounter/this.trackCircumP; // faster 4/3 too fast
var angleC = vel*5*dT*this.inLoopCounter/this.trackCircumP; // I found a perfect(?) 5 by trial and effort
sphereC.position.set( this.r*Math.sin( angleC ), 0, this.r*Math.cos( angleC ));
};
I tried to follow your directions explicitly. I found that neither an omegaG nor omegaK multiplier allowed the two spheres to end simultaneously (by my eyeballs). I quickly found the multiplier 5 worked perfectly. I don’t understand it.
I noticed you noticed, but here I go on a bit about dT = 0.024.
// this.increments = 4167; // A counter, not a clock. Here are the experimental track times.
// Select T, the desired time to travel d. 4167 = roughly 100 secs. 500 about 12 sec, 2500 = 1 min
// 5000, just a second or two over two minutes to complete the courses.
// dT = T/this.increments = 120/5000 = 0.024 sec, 90/3750 = 0.024. Why is dT fixed?
I’m using a counter, not a clock. I suppose I tapped into the CPU rate?
.
Hey Nevyn, I just saw your latest post, so I have yet to make any of your suggested changes.
One thing though, Explaining why everything looked good yesterday was that after copying and changing the title to animateDynamic, I hadn't changed the next line requesting an animation frame from animatePassive. Dumb.
So now I see that the two tracks do operate independently. And I'm where you asked me to be.
Ortho view, both spheres are almost at the finish lines – with the same rolls.
Nevyn wrote. I suggest you implement it using the full A = 2PI*v*t/(2*PI*r) equation.
A = 2PIg*v*t/(2*PIk*r)
= PIg*v*t/(PIk*r)
Airman. I converted the animatePassive into animateDynamic by finding the three variables: incremental time dT, total time T and straight velocity vel. Everything is running well. The image above shows the two spheres end the track with synchronized rolls.
I include the animateDynamic function below, but I’d like to focus on this inLoop section, the code that advances the sphere abound the circular path.
if ( this.inLoop ) {
this.curTrackAngle += this.angInc;
sphereC.rotation.y = this.curTrackAngle;
this.inLoopCounter += 1 ;
// var angleC = omegaG * vel*dT*this.inLoopCounter/this.trackCircumP; // maybe 5/4 too fast
// var angleC = omegaK * vel*dT*this.inLoopCounter/this.trackCircumP; // faster 4/3 too fast
var angleC = vel*5*dT*this.inLoopCounter/this.trackCircumP; // I found a perfect(?) 5 by trial and effort
sphereC.position.set( this.r*Math.sin( angleC ), 0, this.r*Math.cos( angleC ));
};
I tried to follow your directions explicitly. I found that neither an omegaG nor omegaK multiplier allowed the two spheres to end simultaneously (by my eyeballs). I quickly found the multiplier 5 worked perfectly. I don’t understand it.
- Code:
function animateDynamic() {
requestAnimationFrame( animateDynamic );
var omegaG = 2 * Math.PI;
var omegaK = 2 * 4 ;
var dT = 0.024;
var T = this.increments*1.25*dT;
var vel = 10 * this.r / T;
this.cClicks += 1;
this.sClicks += 1;
// Next if is NOT USED YET Check to see whether the start/finish line occurs within the next dT*vel.
// If so, this section will determine determine exactly where the boundary occurs.
// if (( sphereC.position.x + dT*vel >= 0 ) && ( sphereC.position.z == this.r ) && ( this.inLoop == false )) {
// this.overShot = sphereC.position.x + dT*vel - 0;
// this.fRatio = this.overShot/dT*vel;
// this.curTrackAngle = -this.angInc + this.fRatio*this.angInc;
// };
sphereC.rotation.z -= this.ang2Inc;
sphereC.position.x += dT*vel;
if ((sphereC.position.x >= 0) && ( sphereC.position.z == this.r )){
this.inLoop = true;
};
if ( this.inLoop ) {
this.curTrackAngle += this.angInc;
sphereC.rotation.y = this.curTrackAngle;
this.inLoopCounter += 1 ;
// var angleC = omegaG * vel*dT*this.inLoopCounter/this.trackCircumP; // maybe 5/4 too fast
// var angleC = omegaK * vel*dT*this.inLoopCounter/this.trackCircumP; // faster 4/3 too fast
var angleC = vel*5*dT*this.inLoopCounter/this.trackCircumP; // I found a perfect(?) 5 by trial and effort
sphereC.position.set( this.r*Math.sin( angleC ), 0, this.r*Math.cos( angleC ));
};
if ( (sphereC.position.x >= 0) && ( this.cClicks > this.increments*1.25 )) {
sphereC.position.set( -2*this.r, 0, this.r );
this.curTrackAngle = 0;
this.inLoop = false ;
this.inLoopCounter = 0;
this.cClicks = 0 ;
};
sphereS.rotation.z -= this.ang2Inc;
sphereS.position.x += dT*vel;
if (( sphereS.position.x >= 8*this.r ) && ( this.sClicks > this.increments*1.25 )){
sphereS.position.set( -2*this.r, 0, this.tracSep ); // this.sTrackZ[j] );
this.curBallAngle = 0;
this.sClicks = 0;
};
renderer.render( scene, camera );
};
I noticed you noticed, but here I go on a bit about dT = 0.024.
// this.increments = 4167; // A counter, not a clock. Here are the experimental track times.
// Select T, the desired time to travel d. 4167 = roughly 100 secs. 500 about 12 sec, 2500 = 1 min
// 5000, just a second or two over two minutes to complete the courses.
// dT = T/this.increments = 120/5000 = 0.024 sec, 90/3750 = 0.024. Why is dT fixed?
I’m using a counter, not a clock. I suppose I tapped into the CPU rate?
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
.
Did you notice - that last image I posted - that if you cross your eyes you can see a third, middle, three dimensional sphere? Stereopsis - try this one.
var T = this.increments*1.25*dT; // total time
sphereC.position.set( this.r*Math.sin( angleC ), 0, this.r*Math.cos( angleC ));
Nevyn wote. This will always rotate from a set position, it will not add …
Think about creating a Quaternion from the angle. Apply the quaternion to the position vector of the ball.
Airman. I posted in some alarm because I saw I wasn't controlling the sphere in the circular track . Correcting requestAnimationFrame( animateDynamic ); and using the this.inLoopCounter properly positions the sphere on the circular track. I believe that solution is adequate but will change it to a quaternion if you like – are you sure?
var angleC = vel*5*dT*this.inLoopCounter/this.trackCircumP;
I still need to figure out why 5 worked in angleC. I expected omegaK to work. What next? Do you have any idea?
.
Did you notice - that last image I posted - that if you cross your eyes you can see a third, middle, three dimensional sphere? Stereopsis - try this one.
var T = this.increments*1.25*dT; // total time
Airman. I’m just using the total time T, incremental time dT, and the total distance d = 10*r and velocity vel. I suppose I can stick to just the next dT*vel. I'm not sure what you mean by dynamic.Nevyn wote. Why is this line needed? You shouldn't need the total time in a dynamic calculation since it should only be thinking about the transition from the current position to the next. i.e. 1 frame.
Airman. Increments is used as the Time control. The number of increments applies to the circular track or the 8*r straight track. The number of increments for the entire track, including the initial 2*r section becomes 1.25 times this.increments.Nevyn wote. What does the 1.25 stand for? I guess you are using it as the speed control since it is effectively changing the value of dT.
sphereC.position.set( this.r*Math.sin( angleC ), 0, this.r*Math.cos( angleC ));
Nevyn wote. This will always rotate from a set position, it will not add …
Think about creating a Quaternion from the angle. Apply the quaternion to the position vector of the ball.
Airman. I posted in some alarm because I saw I wasn't controlling the sphere in the circular track . Correcting requestAnimationFrame( animateDynamic ); and using the this.inLoopCounter properly positions the sphere on the circular track. I believe that solution is adequate but will change it to a quaternion if you like – are you sure?
var angleC = vel*5*dT*this.inLoopCounter/this.trackCircumP;
I still need to figure out why 5 worked in angleC. I expected omegaK to work. What next? Do you have any idea?
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
I know the attraction of it, but trying to change the existing function will be error prone. It really is a different way of seeing the problem, so it is better to start afresh. Look over my previous outline here: https://milesmathis.forumotion.com/t554p25-animate-the-pi-4-experiment#5635.
Setup an array of track sections where each section knows its start and end distance. Note that it is not a 3D point. It is the distance along the track, regardless of curvature. The ball will also need to know the distance along the track that it has traveled (which will be updated every frame). They will be compared in order to find the current track section(s) to use.
Everything is with respect to the current frame. At the start of the function, we are at the current point along the tracks. By the end of the function, we are at the next point along the tracks. You just need to fill in the gap with the rules of the system. The only tricky part is when you are on a straight track and a curved track section during the same frame, but even that isn't hard to deal with, it just requires a little bit of thought.
What do I mean by dynamic? That it reacts to its current situation. The code shows no signs of knowing before or after. It isn't predicted, and then made to go through the motions. Think of things from the balls perspective. That is what everything happens to in this system. That is how the code should be structured. The ball only has a few simple questions:
Where am I?
What can I do?
The track represents the limitations of the ball. It is what guides it. So the ball is going to think of things in respect to that.
Where am I on this track?
What type of section am I in?
What can I do on this type of section?
How much time do I have to do it?
Setup an array of track sections where each section knows its start and end distance. Note that it is not a 3D point. It is the distance along the track, regardless of curvature. The ball will also need to know the distance along the track that it has traveled (which will be updated every frame). They will be compared in order to find the current track section(s) to use.
Everything is with respect to the current frame. At the start of the function, we are at the current point along the tracks. By the end of the function, we are at the next point along the tracks. You just need to fill in the gap with the rules of the system. The only tricky part is when you are on a straight track and a curved track section during the same frame, but even that isn't hard to deal with, it just requires a little bit of thought.
What do I mean by dynamic? That it reacts to its current situation. The code shows no signs of knowing before or after. It isn't predicted, and then made to go through the motions. Think of things from the balls perspective. That is what everything happens to in this system. That is how the code should be structured. The ball only has a few simple questions:
Where am I?
What can I do?
The track represents the limitations of the ball. It is what guides it. So the ball is going to think of things in respect to that.
Where am I on this track?
What type of section am I in?
What can I do on this type of section?
How much time do I have to do it?
Re: Animate the PI = 4 experiment
.
Evidence of effort.
I'm working on the section/boundary frame-end/re-positioning, expecting to see a single to(the)boundary value less than Td*vel - NOT many values. Something gets hung up at the first and second 2*this.r boundary. Routine stuff. The code is too ugly to share at present, I think I need another day or two to get this to where I can share.
.
Evidence of effort.
I'm working on the section/boundary frame-end/re-positioning, expecting to see a single to(the)boundary value less than Td*vel - NOT many values. Something gets hung up at the first and second 2*this.r boundary. Routine stuff. The code is too ugly to share at present, I think I need another day or two to get this to where I can share.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
No rush. Just work through it. Think about it. Make sure you understand why the code is the way it is, at least mathematically.
Re: Animate the PI = 4 experiment
.
Status. Almost there.
I believe I’ve made progress but it’s hard to tell. In order to keep track of both sphereC and sphereS I created a heap of new variables and so keep the two spheres separate. All that’s left is for me to make the angle as a function of a point on the circumference. I’ve done it once already but you suggested I use quaternions instead. I tried and feel particularly frustrated in not having done so. I recall you using that solution - How exactly did you do that?
I was curious about whether I understood your last comment about frames, and ended up on this three.js Cookbook free chapter. Determining The Frame Rate For Your Scene.
https://subscription.packtpub.com/book/web_development/9781783981182/1/ch01lvl1sec15/determining-the-frame-rate-for-your-scene
For once, the instructions were so simple I didn’t need to read them, the code 'pictures' were enough. Everything from including the new source
New function createStats() {}; right after function onWindowResize() { }
Created a new var stats. And included a stats.update(); at the end of the animateDynamic function.
The FPS thingee appeared as if by majic.
.
Status. Almost there.
I believe I’ve made progress but it’s hard to tell. In order to keep track of both sphereC and sphereS I created a heap of new variables and so keep the two spheres separate. All that’s left is for me to make the angle as a function of a point on the circumference. I’ve done it once already but you suggested I use quaternions instead. I tried and feel particularly frustrated in not having done so. I recall you using that solution - How exactly did you do that?
I was curious about whether I understood your last comment about frames, and ended up on this three.js Cookbook free chapter. Determining The Frame Rate For Your Scene.
https://subscription.packtpub.com/book/web_development/9781783981182/1/ch01lvl1sec15/determining-the-frame-rate-for-your-scene
For once, the instructions were so simple I didn’t need to read them, the code 'pictures' were enough. Everything from including the new source
- Code:
<script src="js/libs/stats.min.js"></script>
New function createStats() {}; right after function onWindowResize() { }
Created a new var stats. And included a stats.update(); at the end of the animateDynamic function.
The FPS thingee appeared as if by majic.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
.
Everything appears to be working properly, including rolling spins, under the new animate Dynamic function.
I used parametric rotations and not quaternions to position and rotate the sphere on the curved track.
Here’s the animateDynamic function
I believe I followed the intent if not the letter of the algorithm you identified on 24 September. https://milesmathis.forumotion.com/t554p25-animate-the-pi-4-experiment#5635 , let me know if you see otherwise or want anything else changed.
I'll be cleaning up then resuming the next challenge, the controls.
.
Everything appears to be working properly, including rolling spins, under the new animate Dynamic function.
I used parametric rotations and not quaternions to position and rotate the sphere on the curved track.
- Code:
var trackAngle = 2*Math.PI*(this.distNextC - cTracSectK)/this.trackCircumK;
sphereC.position.set( this.r*Math.sin( trackAngle ), 0, this.r*Math.cos( trackAngle ));
Here’s the animateDynamic function
- Code:
function animateDynamic() {
requestAnimationFrame( animateDynamic );
var dT = 0.006;
this.T = this.increments * dT; // this.increments = 1000. T = 1000*0.024 = 24 sec
var vel = 10 * this.r / T;
// from daControlValues ///////////
// this.distTraveledS = 0;
// this.distTraveledC = 0;
// this.T;
// this.trackCircumP = 2*Math.PI*this.r;
// this.trackCircumK = 8*this.r;
///////////////////////////////////////
var cTrackLengthP = 2*this.r + 2*Math.PI*this.r;
var cTrackLengthK = 2*this.r + 8*this.r;
var cTracSectP = cTrackLengthP/5;
var cTracSectK = cTrackLengthK/5;
var sTrackLength = 10*this.r;
var sTrackSect = 10*this.r/5;
var quaternion = new THREE.Quaternion;
sphereS.rotation.z -= this.ang2Inc;
sphereC.rotation.z -= this.ang2Inc;
this.distNextS = this.distTraveledS + dT*vel;
this.distNextC = this.distTraveledC + dT*vel;
this.curSectionS = Math.floor( this.distTraveledS / sTrackSect );
this.curSectionC = Math.floor( this.distTraveledC / cTracSectK );
this.nexSectionS = Math.floor( this.distNextS / sTrackSect );
this.nexSectionC = Math.floor( this.distNextC / cTracSectK );
if ( this.nexSectionS == this.curSectionS + 1 ){ // sphereS has passed a section boundary.
var pastBoundary = this.distNextS - this.nexSectionS * 2 * this.r;
//this.distNextS = this.distTraveledS + dT*vel - pastBoundary; // sphereS is now on the section boundary.
//console.log( 'nexSectionS = ' + this.nexSectionS + ', curSectionS = ' + this.curSectionS + ', pastBoundary = ' + pastBoundary );
//console.log( 'distTraveledS = ' + this.distTraveledS + ', distNextS = ' + this.distNextS );
this.curSectionS = this.curSectionS + 1;
};
if ( this.nexSectionC == this.curSectionC + 1 ){ // sphereC has passed a section boundary.
var pastBoundary = this.distNextC - this.nexSectionC * 2 *this.r;
//this.distNextC = this.distTraveledS + dT*vel - pastBoundary; // sphereC is now on the section boundary.
//console.log( 'nexSectionC = ' + this.nexSectionC + ', curSectionC = ' + this.curSectionC + ', pastBoundary = ' + pastBoundary );
//console.log( 'distTraveledC = ' + this.distTraveledC + ', distNextC = ' + this.distNextC );
//this.curSectionC = this.curSectionC + 1;
this.curSectionC = this.nexSectionC;
};
if ( this.distNextC < cTracSectK ) { // cTrackLengthP // the sphere stops at the pi(g) mark.
sphereC.position.set( -2*this.r+ this.distNextC, 0, this.r ); // ( -2*this.r+ this.distNextS, 0, this.r ); // sTrackLength
this.distTraveledC = this.distNextC;
this.curSectionC = this.nexSectionC;
}
else if (( this.distNextC >= cTracSectK ) && ( this.distNextC < cTrackLengthK )) { // In the loop
var trackAngle = 2*Math.PI*(this.distNextC - cTracSectK)/this.trackCircumK;
sphereC.position.set( this.r*Math.sin( trackAngle ), 0, this.r*Math.cos( trackAngle ));
sphereC.rotation.y = trackAngle;
this.distTraveledC = this.distNextC;
this.curSectionC = this.nexSectionC;
}
else if ( this.distNextC >= cTrackLengthK ) {
sphereC.position.set( -2*this.r, 0, this.r );
this.distTraveledC = 0;
this.curSectionC = 0;
};
if ( this.distNextS < sTrackLength ) {
sphereS.position.set( -2*this.r+ this.distNextS, 0, this.tracSep );
this.distTraveledS = this.distNextS;
this.curSectionS = this.nexSectionS;
}
else if ( this.distNextS >= sTrackLength ) {
sphereS.position.set( -2*this.r, 0, this.tracSep );
this.distTraveledS = 0;
this.curSectionS = 0;
};
renderer.render( scene, camera );
stats.update();
};
I believe I followed the intent if not the letter of the algorithm you identified on 24 September. https://milesmathis.forumotion.com/t554p25-animate-the-pi-4-experiment#5635 , let me know if you see otherwise or want anything else changed.
I'll be cleaning up then resuming the next challenge, the controls.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
.
Sorry Charge Field Fans, it's been difficult slogging. Mostly frustration in not getting a working dat GUI installed.
For those interested in the programming, here's a reference, Introduction to THREE.js - 4 – Creating and Controlling an Animation with the DAT.GUI Interface
In trying to follow the directions I first came to realize my code is probably too complicated. Here it is, stripped of all the variables and functions.
But, surprise, surprise; I’ve also come to realize that both those sources identify the animation function by the same name - the function render, preceded by the function call render().
It's too soon to say, at least I've got something to work on.
.
Sorry Charge Field Fans, it's been difficult slogging. Mostly frustration in not getting a working dat GUI installed.
For those interested in the programming, here's a reference, Introduction to THREE.js - 4 – Creating and Controlling an Animation with the DAT.GUI Interface
In trying to follow the directions I first came to realize my code is probably too complicated. Here it is, stripped of all the variables and functions.
- Code:
init();
animateDynamic();
- Code:
]);
- Code:
// function init() {
var grp = new THREE.Group();
scene = new THREE.Scene();
this.r = 1; // Track radius
this.w = 0.25// track width
this.q = 0.5; // track separation
…
stats = createStats();
document.body.appendChild( stats.domElement );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, true );
renderer.render( scene, camera );
stats.update();
//};
But, surprise, surprise; I’ve also come to realize that both those sources identify the animation function by the same name - the function render, preceded by the function call render().
- Code:
render();
function render() {
... // some action
requestAnimationFrame(render);
renderer.render(scene, camera);
}
It's too soon to say, at least I've got something to work on.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
The heart of a ThreeJS application is the render function. It does not need to be called render. It can be any name you want. It is the way you define and use it that matters.
The most important, even critical, part is that call to requestAnimationFrame, which is given the function to use for rendering. i.e. this function which happens to be called render.
You have to call the render function your self on the first time, but it will repeatedly call itself (although not recursively) through the requestAnimationFrame function. This is the way browsers have defined an animating application. If you were working in a more traditional language, with no browser, then you would need to create a loop that does this sort of thing. It is called a render loop. Since ThreeJS is in a browser, some of that is handled by the browser, so you don't see a normal loop, but it should be thought of as one.
Commenting out the init function declaration, but leaving the guts of it still executing, will cause those statements to be executed where ever they are specified in the code. That may not be the best, or even a good, place for it to be executed. Also, you have references to this in that function, but there is no this, so I am not sure where those values end up (probably on the window object supplied by the browser).
You don't need an init function, but you do need initialization code. Most of the ThreeJS examples just write that init code where they want it (with respect to the rest of the code so that it is executed when it should). However, I prefer an explicit function because it is more flexible to change when it is executed and it is easier to copy it to another project. It also allows you to use intermediate variables within that function. If you do that without a function, then those variables exist for the life time of the application. They also cause clutter in the window object and can cause problems by overwriting other variables with the same name.
For example, I had problems in Atomic Viewer because I had a variable called performance. I didn't know that the browser already has a variable with that name that was used for fast time calculations, such as those required by ThreeJS. It took some time to find that problem and fix it.
I'm not sure what your problems are with DATGUI, but something to be aware of is that it uses an object that it references properties in. That probably sounds confusing so I will try to explain it.
Let's say you want 2 menu items, one called One and one called Two. The easiest way to provide that is to create an object with properties using those names, like this:
Now, you just tell DATGUI that you want to create a menu item for each of them.
See how DATGUI is actually given the parent object, menuData, and not the values for One and Two? It will retrieve those values when it wants them and it will update them when the user changes its value in the menu. You can also update them yourself, but you then need to tell DATGUI to update the menu or the user won't see those changes.
The most important, even critical, part is that call to requestAnimationFrame, which is given the function to use for rendering. i.e. this function which happens to be called render.
You have to call the render function your self on the first time, but it will repeatedly call itself (although not recursively) through the requestAnimationFrame function. This is the way browsers have defined an animating application. If you were working in a more traditional language, with no browser, then you would need to create a loop that does this sort of thing. It is called a render loop. Since ThreeJS is in a browser, some of that is handled by the browser, so you don't see a normal loop, but it should be thought of as one.
Commenting out the init function declaration, but leaving the guts of it still executing, will cause those statements to be executed where ever they are specified in the code. That may not be the best, or even a good, place for it to be executed. Also, you have references to this in that function, but there is no this, so I am not sure where those values end up (probably on the window object supplied by the browser).
You don't need an init function, but you do need initialization code. Most of the ThreeJS examples just write that init code where they want it (with respect to the rest of the code so that it is executed when it should). However, I prefer an explicit function because it is more flexible to change when it is executed and it is easier to copy it to another project. It also allows you to use intermediate variables within that function. If you do that without a function, then those variables exist for the life time of the application. They also cause clutter in the window object and can cause problems by overwriting other variables with the same name.
For example, I had problems in Atomic Viewer because I had a variable called performance. I didn't know that the browser already has a variable with that name that was used for fast time calculations, such as those required by ThreeJS. It took some time to find that problem and fix it.
I'm not sure what your problems are with DATGUI, but something to be aware of is that it uses an object that it references properties in. That probably sounds confusing so I will try to explain it.
Let's say you want 2 menu items, one called One and one called Two. The easiest way to provide that is to create an object with properties using those names, like this:
- Code:
var menuData = {
One: 1,
Two: 2
};
Now, you just tell DATGUI that you want to create a menu item for each of them.
- Code:
var gui = ...
gui.add( menuData, 'One' );
gui.add( menuData, 'Two' );
See how DATGUI is actually given the parent object, menuData, and not the values for One and Two? It will retrieve those values when it wants them and it will update them when the user changes its value in the menu. You can also update them yourself, but you then need to tell DATGUI to update the menu or the user won't see those changes.
Re: Animate the PI = 4 experiment
.
We can control spherical hues.
Thanks Nevyn, I must say, you bring out the best in me. I'm very grateful. OK, lots of changes. init() remains intact. I renamed animateDynamic() to render() – and would have killed a chicken too if I had one. render() is called from close to the end of the init function. I removed any remains – lingering vars - of previous animations.
I eliminated all instances of, ”this.”. Now global variables are declared in the main, before init() is called. Shown here.
Only increments and Color works “properly”, mostly ad hoc, color was added as an afterthought, and I didn't expect keeping it.
Changing w and q will knock at least one ball off off its track. This may require more thought than I’d expected.
I’ll continue cleaning up before posting any additional code changes.
Thanks again.
.
We can control spherical hues.
Thanks Nevyn, I must say, you bring out the best in me. I'm very grateful. OK, lots of changes. init() remains intact. I renamed animateDynamic() to render() – and would have killed a chicken too if I had one. render() is called from close to the end of the init function. I removed any remains – lingering vars - of previous animations.
I eliminated all instances of, ”this.”. Now global variables are declared in the main, before init() is called. Shown here.
- Code:
var mesh;
var camera, scene, renderer;
var stats;
var sphereMat;
var r = 1;
var w = 0.25// track width
var q = 0.5; // track separation
var bRadius = 0.25; // *r;
var distTraveledS = 0;
var distTraveledC = 0;
var increments = 100;
init();
function init() {
Only increments and Color works “properly”, mostly ad hoc, color was added as an afterthought, and I didn't expect keeping it.
Changing w and q will knock at least one ball off off its track. This may require more thought than I’d expected.
I’ll continue cleaning up before posting any additional code changes.
Thanks again.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
.
Showing a problem, the two spheres are off their identified tracks, and close to their finishing ‘locations’.
I’m still learning about the control panel. I need to include the ball radius parameter.
I moved all functions out of the init function. That appeared to improve the fps from about 32 to 38.
There’s a problem when changing the track parameters. Above you can see that r, the circular track radius has been increased from 1 to 1.4. The balls are in their ‘correct’ locations in space, but the tracks need to be reinitialized when changes are made to r, w, or q.
Since this program is in a constant loop, I may need a re-initialize button. And then I’d like to include a checkbox in order to stop the continuous loop, and another button to launch a single runs.
Anyway, Here’s the entire body (minus the html head), problems and all. I'll keep working to improve it.
Showing a problem, the two spheres are off their identified tracks, and close to their finishing ‘locations’.
I’m still learning about the control panel. I need to include the ball radius parameter.
I moved all functions out of the init function. That appeared to improve the fps from about 32 to 38.
There’s a problem when changing the track parameters. Above you can see that r, the circular track radius has been increased from 1 to 1.4. The balls are in their ‘correct’ locations in space, but the tracks need to be reinitialized when changes are made to r, w, or q.
Since this program is in a constant loop, I may need a re-initialize button. And then I’d like to include a checkbox in order to stop the continuous loop, and another button to launch a single runs.
Anyway, Here’s the entire body (minus the html head), problems and all. I'll keep working to improve it.
- Code:
<body>
<script src="js/three.min.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/libs/dat.gui.min.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
var camera, scene, renderer;
var stats;
var gui;
var sphereMat;
var r = 1;
var w = 0.25; // track width
var q = 0.5; // track separation
var bRadius = 0.25; // *r;
var distTraveledS = 0;
var distTraveledC = 0;
var TracTSecs = 25; // seconds
init();
function init() {
var grp = new THREE.Group();
scene = new THREE.Scene();
var viewSize = 8*r;
var widt = window.innerWidth;
var heit = window.innerHeight;
var aspectRatio = widt/heit;
var tubeTot = 60; // 5, 120
var tRadius = bRadius; // r; // 0.75 * r;
var tubeInc = 10*r/tubeTot;
// Centerpath coordinate arrays.
var tracSep = r+q+w;
var sTrackX = [ -2*r, 0, 2*r, 4*r, 6*r, 8*r, 2*Math.PI*r ];
var cTrackX = [ -2*r, 0, r, 0, -r, 0 ];
//camera = new THREE.PerspectiveCamera( 70, aspectRatio, 0.1*r, 100*r );
camera = new THREE.OrthographicCamera( -aspectRatio*viewSize/2, aspectRatio*viewSize/2, viewSize/2, -viewSize/2);
camera.position.set( 0, 0, 4*r );
camera.lookAt(0, 0, -5*r);
controls = new THREE.OrbitControls( camera, renderer ); // comes with errors
controls.target.set( 0, 0, -5*r );
camera.updateProjectionMatrix();
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//scene.background = new THREE.Color('FFFFFF'); // #009900 pool table green // #0000FF nice high contrast blue //
sphereMat = new THREE.MeshBasicMaterial( { wireframe: true, color: 'yellow' } ); // yellow
var material = new THREE.LineBasicMaterial( { color: 'red', linewidth: 0.5*r } ); // markers
var material2 = new THREE.LineBasicMaterial( { color: 'grey' } ); // Increment markers
var MAT_LINE_CP = new THREE.LineBasicMaterial( { color: 0x00cc00, linewidth: 0.5 } ); // distances
//cTrackCenter -4 curved paths
for(th=1;th<=360;th+=1) {
var radians1 = (Math.PI/180) * th;
var radians2 = (Math.PI/180) * (th + 1);
if (th === 359) { radians2 = (Math.PI/180) }
for ( i = -1; i < 2; i=i+2 ) {
var configRadius = r + i*w;
var XYPlaneLine = new THREE.Geometry();
XYPlaneLine.vertices.push(
new THREE.Vector3( configRadius * Math.cos(radians1), 0, -configRadius*Math.sin(radians1) ),
new THREE.Vector3( configRadius * Math.cos(radians2), 0, -configRadius*Math.sin(radians2) ) );
var XYLine = new THREE.Line( XYPlaneLine, MAT_LINE_CP);
grp.add(XYLine);
configRadius = r + i*w;
var XYPlaneLine = new THREE.Geometry();
XYPlaneLine.vertices.push(
new THREE.Vector3( r * Math.cos(radians1), i*tRadius, -r*Math.sin(radians1) ),
new THREE.Vector3( r * Math.cos(radians2), i*tRadius, -r*Math.sin(radians2) ));
var XYLine = new THREE.Line( XYPlaneLine, MAT_LINE_CP);
grp.add(XYLine);
};
};
// S track markers
for ( j = 0; j < 7; j++ ) {
var sHML = new THREE.Geometry( 1, 1, 1 );
sHML.vertices.push(new THREE.Vector3( sTrackX[j], 0, r+q+2*w ) );
sHML.vertices.push(new THREE.Vector3( sTrackX[j], 0, r+q ) );
var sHMLine = new THREE.Line( sHML, material );
grp.add( sHMLine ); // horizontal
var sVML = new THREE.Geometry( 1, 1, 1 );
sVML.vertices.push(new THREE.Vector3( sTrackX[j], w, tracSep ) ); // sTrackZ[j]
sVML.vertices.push(new THREE.Vector3( sTrackX[j], -w, tracSep ) );
var sVMLine = new THREE.Line( sVML, material );
grp.add( sVMLine ); // vertical
};
// C track straight section markers
for ( m = 0; m < 2; m++ ) {
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( cTrackX[m], 0, r-w ) );
geometry.vertices.push(new THREE.Vector3( cTrackX[m], 0, r+w ) );
var line = new THREE.Line( geometry, material );
grp.add( line );
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( cTrackX[m], -tRadius, r ) );
geometry.vertices.push(new THREE.Vector3( cTrackX[m], tRadius, r ) );
var line = new THREE.Line( geometry, material );
grp.add( line );
};
// parallel circles curved path's initial straight section
for( ber=0; ber<tubeTot/5+1; ber++ ) { ///////////changed
for(th=1;th<=360;th+=12) {
var radians1 = (Math.PI/180) * th;
var radians2 = (Math.PI/180) * (th + 12);
if (th === 348) { radians2 = (Math.PI/180) }
var yZPlaneCircle = new THREE.Geometry();
yZPlaneCircle.vertices.push( //viewing x and y.
new THREE.Vector3( 0, tRadius*Math.sin(radians1), -tRadius * Math.cos(radians1) ),
new THREE.Vector3( 0, tRadius*Math.sin(radians2), -tRadius * Math.cos(radians2) ) );
var tCircle = new THREE.Line( yZPlaneCircle, material2);
tCircle.position.set( -2*r+ber*tubeInc, 0, r );
grp.add(tCircle);
};
};
// parallel circles straight path
for( num=0; num<=tubeTot; num++ ) {
for(th=1;th<=360;th+=18) {
var radians1 = (Math.PI/180) * th;
var radians2 = (Math.PI/180) * (th + 18);
if (th === 342) { radians2 = (Math.PI/180) }
var yZPlaneCircle = new THREE.Geometry();
yZPlaneCircle.vertices.push( //viewing x and y.
new THREE.Vector3( 0, tRadius*Math.sin(radians1), -tRadius * Math.cos(radians1) ),
new THREE.Vector3( 0, tRadius*Math.sin(radians2), -tRadius * Math.cos(radians2) ) );
var tCircle = new THREE.Line( yZPlaneCircle, material2);
tCircle.position.set( -2*r+num*tubeInc, 0, tracSep );
grp.add(tCircle);
};
};
// parallel circles circular path
var curAngl;
var curAnglInc = 2*Math.PI*r/(4*tubeTot/5);
var yZPlaneCircle = new THREE.Geometry();
for(th=1;th<=360;th+=18) {
var radians1 = (Math.PI/180) * th;
var radians2 = (Math.PI/180) * (th + 18);
if (th === 342) { radians2 = (Math.PI/180) }
yZPlaneCircle.vertices.push(
new THREE.Vector3( 0, tRadius*Math.sin(radians1), -tRadius * Math.cos(radians1) ),
new THREE.Vector3( 0, tRadius*Math.sin(radians2), -tRadius * Math.cos(radians2) ) );
};
for( ber=0; ber < tubeTot; ber++ ) {
var tCircle = new THREE.Line( yZPlaneCircle, material2);
curAngl = ber*curAnglInc;
tCircle.rotation.y = curAngl + Math.PI/2;
tCircle.position.set( r * Math.cos(curAngl), 0, -r * Math.sin(curAngl) );
grp.add(tCircle);
};
// S track lengths
for ( k = -1; k < 2; k=k+2 ) {
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( sTrackX[0], 0, r+w+q+k*w ) );
geometry.vertices.push(new THREE.Vector3( sTrackX[5], 0, r+w+q+k*w ) );
var line = new THREE.Line( geometry, MAT_LINE_CP );
grp.add( line );
// S track lengths:
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( sTrackX[0], k*tRadius, r+w+q ) );
geometry.vertices.push(new THREE.Vector3( sTrackX[5], k*tRadius, r+w+q ) );
var line = new THREE.Line( geometry, MAT_LINE_CP );
grp.add( line );
// C track lengths: +/-z edges
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( cTrackX[0], 0, r-k*w ) );
geometry.vertices.push(new THREE.Vector3( cTrackX[1], 0, r-k*w ) );
var line = new THREE.Line( geometry, MAT_LINE_CP );
grp.add( line );
// C track lengths:
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( cTrackX[0], k*tRadius, r ) );
geometry.vertices.push(new THREE.Vector3( cTrackX[1], k*tRadius, r ) );
var line = new THREE.Line( geometry, MAT_LINE_CP );
grp.add( line );
}
// C track markers
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( r-w, 0, 0 ) );
geometry.vertices.push(new THREE.Vector3( r+w, 0, 0 ) );
var line = new THREE.Line( geometry, material );
grp.add( line ); // C track One Marker
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( r, -tRadius, 0 ) );
geometry.vertices.push(new THREE.Vector3( r, tRadius, 0 ) );
var line = new THREE.Line( geometry, material );
grp.add( line ); // C track One Marker
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( 0, 0, -r-w ) );
geometry.vertices.push(new THREE.Vector3( 0, 0, -r+w ) );
var line = new THREE.Line( geometry, material );
grp.add( line ); // C track Two Marker
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( 0, -tRadius, -r ) );
geometry.vertices.push(new THREE.Vector3( 0, tRadius, -r ) );
var line = new THREE.Line( geometry, material );
grp.add( line ); // C track Two Marker
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( -r-w, 0, 0 ) );
geometry.vertices.push(new THREE.Vector3( -r+w, 0, 0 ) );
var line = new THREE.Line( geometry, material );
grp.add( line ); // C track Three Marker
var geometry = new THREE.Geometry( 1, 1, 1 );
geometry.vertices.push(new THREE.Vector3( -r, -tRadius, 0 ) );
geometry.vertices.push(new THREE.Vector3( -r, tRadius, 0 ) );
var line = new THREE.Line( geometry, material );
grp.add( line ); // C track Three Marker
// Balls
var sphereGeom = new THREE.SphereGeometry( bRadius, 16, 16 );
sphereC = new THREE.Mesh( sphereGeom, sphereMat );
sphereC.position.set( -2*r, 0, r );
sphereS = new THREE.Mesh( sphereGeom, sphereMat );
sphereS.position.set( -2*r, 0, tracSep );
ballOne = new THREE.Object3D();
ballOne.add(sphereC);
var ballTwo = new THREE.Object3D();
ballTwo.add(sphereS);
grp.add( ballOne, ballTwo );
grp.position.set( -2.5*r, 0, -6*r ); //repositions the world rotation point
scene.add(grp);
stats = createStats();
document.body.appendChild( stats.domElement );
window.addEventListener( 'resize', onWindowResize, true );
render();
displaygui();
};
function displaygui(){
gui = new dat.GUI();
parameters =
{
r: 1,
w: 0.25,
q: 0.125,
TracTSecs: 25,
color: "#ffff00",
};
var folder1 = gui.addFolder('Tracks');
var rTrack = folder1.add( parameters, 'r' ).min(1).max(10).step(0.1).listen();
var wTrack = folder1.add( parameters, 'w' ).min(0.01).max(0.5).step(.01).listen();
var qTrack = folder1.add( parameters, 'q' ).min(0).max(1).step(0.01).listen();
//folder1.open();
rTrack.onChange(function(value)
{ r = value; });
wTrack.onChange(function(value)
{ w = value; });
qTrack.onChange(function(value)
{ q = value; });
var TracTInSecs = gui.add( parameters,'TracTSecs').min(3).max(200).step(1).listen();
TracTInSecs.onChange(function(value)
{ TracTSecs = value; });
var ballColor = gui.addColor( parameters, 'color' ).name('Color').listen();
ballColor.onChange(function(value) // onFinishChange
{ sphereMat.color.setHex( value.replace("#", "0x") ); });
function updateStuff() {
r = parameters.r;
w = parameters.w;
q = parameters.q;
TracTSecs = parameters.TracTSecs;
sphereMat.color.setHex( parameters.color.replace("#", "0x") );
};
};
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
};
function createStats() {
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0';
stats.domElement.style.top = '0';
return stats;
};
function render() {
var T = TracTSecs;
var vel = 10 * r / T;
var increments = T*30; // roughly the fps
var dT = T/increments;
var tracSep = r+q+w; // duplicated in init. ////////////
var trackCircumP = 2*Math.PI*r;
var trackCircumK = 8*r;
var cTrackLengthP = 2*r + 2*Math.PI*r;
var cTrackLengthK = 2*r + 8*r;
var cTracSectP = cTrackLengthP/5;
var cTracSectK = cTrackLengthK/5;
var sTrackLength = 10*r;
var sTrackSect = 10*r/5;
var quaternion = new THREE.Quaternion;
var bCircum = 2 * Math.PI * bRadius;
var ang2rot = 10*r/bCircum;
var kMult = 4/Math.PI;
var ang2Inc = 4 * ang2rot * kMult/ increments;
var distNextS = distTraveledS + dT*vel;
var distNextC = distTraveledC + dT*vel;
var curSectionS = Math.floor( distTraveledS / sTrackSect );
var curSectionC = Math.floor( distTraveledC / cTracSectK );
var nexSectionS = Math.floor( distNextS / sTrackSect );
var nexSectionC = Math.floor( distNextC / cTracSectK );
sphereS.rotation.z -= ang2Inc;
sphereC.rotation.z -= ang2Inc;
if ( nexSectionS == curSectionS + 1 ){
var pastBoundary = distNextS - nexSectionS * 2 * r;
curSectionS = curSectionS + 1;
};
if ( nexSectionC == curSectionC + 1 ){
var pastBoundary = distNextC - nexSectionC * cTracSectK ; // 2 *r; //
curSectionC = nexSectionC;
};
if ( distNextC < cTracSectK ) {
sphereC.position.set( -2*r+ distNextC, 0, r );
distTraveledC = distNextC;
curSectionC = nexSectionC;
}
else if (( distNextC >= cTracSectK ) && ( distNextC < cTrackLengthK )) { // In the loop
var trackAngle = 2*Math.PI*(distNextC - cTracSectK)/trackCircumK;
sphereC.position.set( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ));
sphereC.rotation.y = trackAngle;
distTraveledC = distNextC;
curSectionC = nexSectionC;
}
else if ( distNextC >= cTrackLengthK ) {
sphereC.position.set( -2*r, 0, r );
distTraveledC = 0;
curSectionC = 0;
};
if ( distNextS < sTrackLength ) {
sphereS.position.set( -2*r+ distNextS, 0, tracSep );
distTraveledS = distNextS;
curSectionS = nexSectionS;
}
else if ( distNextS >= sTrackLength ) {
sphereS.position.set( -2*r, 0, tracSep );
distTraveledS = 0;
curSectionS = 0;
};
renderer.render( scene, camera );
requestAnimationFrame( render );
stats.update();
};
</script>
</body>
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
Why does the user need to change these things? I can't see a reason to change the track width (or ball). The only control I think you absolutely need is a speed control. Maybe some start, stop, reset controls, and a step control to move it frame by frame if you feel up to it.
Re: Animate the PI = 4 experiment
.
Ortho view, near the finish lines.
We have a speed control, var trTimeInSecs. The user can dial up the number of seconds it takes for the balls to complete the tracks. Increment is now a function of trTimeInSecs, var increment = trTimeInSecs *35. Alternatively, trTimeInSecs can be converted into a velocity by dividing by 10*r.
Color kind of grows on you, I’ll get rid of it if you like.
Track changes. I thought we might give the user the option two or three options: 1) Scale the PI Equal 4 Experiment to match the values used by StevenO – where the ball radius is less than a tenth of the curved track radius and the tracks are completed in about a second. Or 2) Scale the ball radii to about a quarter of the track radius to allow close examination of the rolling action, which is what is shown by most of the recent PI Equal 4 images. Let the the user access to swap out the cycloid, pi(k) and expected rolling actions pi(g) to see the difference. Or 3) Scale the balls a magnitude smaller than that.
Camera choice. Let’s give the user the choice between an orthogonal versus perspective cameras –both cameras have their advantages and disadvantages as the prior images have shown. Might something like this work to switch cameras? Or might a reset capability simplify things?
Yes indeedy. I’m sure you could tell I needed a break; I’m fully recovered now. That dat gui had been a huge bugaboo for me for a couple of years now. Good to get past that mental barrier.
I’m not at all certain the curved track sphere is rolling correctly, and would very much hope that anyone may examine the rolling as well. I believe start, stop, (back and forth) reset and step controls would allow that.
Feel free to correct my thinking.
.
Ortho view, near the finish lines.
We have a speed control, var trTimeInSecs. The user can dial up the number of seconds it takes for the balls to complete the tracks. Increment is now a function of trTimeInSecs, var increment = trTimeInSecs *35. Alternatively, trTimeInSecs can be converted into a velocity by dividing by 10*r.
Color kind of grows on you, I’ll get rid of it if you like.
Track changes. I thought we might give the user the option two or three options: 1) Scale the PI Equal 4 Experiment to match the values used by StevenO – where the ball radius is less than a tenth of the curved track radius and the tracks are completed in about a second. Or 2) Scale the ball radii to about a quarter of the track radius to allow close examination of the rolling action, which is what is shown by most of the recent PI Equal 4 images. Let the the user access to swap out the cycloid, pi(k) and expected rolling actions pi(g) to see the difference. Or 3) Scale the balls a magnitude smaller than that.
Camera choice. Let’s give the user the choice between an orthogonal versus perspective cameras –both cameras have their advantages and disadvantages as the prior images have shown. Might something like this work to switch cameras? Or might a reset capability simplify things?
- Code:
if (this._cameraState.type == CameraMode.Perspective) {
this._mainCamera = this._perspectiveCamera;
this._mainCamera.position.copy(this._orthographicCamera.position);
this._mainCamera.rotation.copy(this._orthographicCamera.rotation);
} else if (this._cameraState.type == CameraMode.Orthographic) {
this._mainCamera = this._orthographicCamera;
this._mainCamera.position.copy(this._perspectiveCamera.position);
this._mainCamera.rotation.copy(this._perspectiveCamera.rotation);
}
this._control.object = this._mainCamera;
Maybe some start, stop, reset controls, and a step control to move it frame by frame if you feel up to it.
Yes indeedy. I’m sure you could tell I needed a break; I’m fully recovered now. That dat gui had been a huge bugaboo for me for a couple of years now. Good to get past that mental barrier.
I’m not at all certain the curved track sphere is rolling correctly, and would very much hope that anyone may examine the rolling as well. I believe start, stop, (back and forth) reset and step controls would allow that.
Feel free to correct my thinking.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
.
The cycloidRoll checkbox is added.
It works. I believe the cycloidRoll option is necessary, and confusing. The default is true, but when cycloidRoll is unchecked as above, extending the seconds to 200 and getting very close to the track, above or toward the side; the balls in either track seem to glide forward above the surface without contact. When cycloidRoll is true, the balls are clearly rolling. The action needs some study.
I’ve had no luck with changing cameras.
One out of two new controls ain't bad. I’ll try finding a way to start/stop and step next.
.
The cycloidRoll checkbox is added.
It works. I believe the cycloidRoll option is necessary, and confusing. The default is true, but when cycloidRoll is unchecked as above, extending the seconds to 200 and getting very close to the track, above or toward the side; the balls in either track seem to glide forward above the surface without contact. When cycloidRoll is true, the balls are clearly rolling. The action needs some study.
- Code:
var ang2Inc;
var bCircum = 2 * Math.PI * bRadius;
var ang2rot = 10*r/bCircum;
var kMult = 4/Math.PI;
if ( kPiOrNot )
ang2Inc = 4 * ang2rot * kMult/ increments;
else
ang2Inc = Math.PI * ang2rot / increments;
I’ve had no luck with changing cameras.
- Code:
// var value = parameters.cameraView
// if ( value )
// camera = cameraO;
// else
// camera = cameraP;
One out of two new controls ain't bad. I’ll try finding a way to start/stop and step next.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
Creating a drop-down menu in DATGUI requires either an array of items to choose from, or an object. The difference is that the array will contain the items themselves, but the object allows you to use a name for each item that is shown to the user, but the actual value selected is something else.
The first one uses an array. When the user selects 'chrome', say, then the text.message value will be set to 'chrome'.
The second one uses an object, so selecting 'Slow' would set text.speed to 0.1.
Note that the array or object is only providing values to select. It is not used to set/retrieve the current value to/from. That still works like all other menu items and comes from the text object, in this example, and the property name specified (message or speed).
- Code:
// Choose from accepted values
gui.add(text, 'message', [ 'pizza', 'chrome', 'hooray' ] );
// Choose from named values
gui.add(text, 'speed', { Stopped: 0, Slow: 0.1, Fast: 5 } );
The first one uses an array. When the user selects 'chrome', say, then the text.message value will be set to 'chrome'.
The second one uses an object, so selecting 'Slow' would set text.speed to 0.1.
Note that the array or object is only providing values to select. It is not used to set/retrieve the current value to/from. That still works like all other menu items and comes from the text object, in this example, and the property name specified (message or speed).
Re: Animate the PI = 4 experiment
.
MaterialOne and MaterialTwo appear to be proper pull down boxes, but they cannot be changed.
Attempting to click on the apparent pull down arrows for MaterialOne or MaterialTwo are futile. No alternatives are displayed and nothing changes. The other three parameters – Seconds, CycloidRoll, and Color all behave properly.
The fact that the spheres’ color can be changed makes it seem likely that I should also be able to change the spheres’ appearance from mesh into a solid or normal color. I can certainly initialize them as mesh basic or normal. Please ignore the Lambert or Phong as they appear as a mat black even though I added a point light to the scene, I’m just interested in getting a pull down. These two functions are from the Stemkowski source I’d cited recently.
Since you offered help, I went over ‘everything’ again. Several changes with little or no progress to show for it.
Here are the displaygui and update sphere functions.
By the way I had also tried implementing the http://workshop.chromeexperiments.com/examples/gui/#2--Constraining-Input example with [ 'pizza', 'chrome', 'hooray' ] that you described in your last post. I’m not delirious, I’m clearly doing something wrong. So I took the opportunity to review arrays and objects
A BRIEF JavaScript TUTORIAL: PART 1
https://discoverthreejs.com/book/introduction/javascript-tutorial-1/
It seems that javaScript has progressed since I learned it. Did you notice that the ‘var’ designators have been replaced with ‘let’ in the two functions above? I replaced all the ‘var’, variable identifiers with ‘const’ (for constants) and ‘let’ the newer variable designator. I learned several details I hadn’t come across before. Here's a great link to Mozilla’s Array page. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
After beating myself silly here I think I found my first clear evidence that I may be able to Pause.
https://discoverthreejs.com/book/first-steps/resize/
Promising?
.
MaterialOne and MaterialTwo appear to be proper pull down boxes, but they cannot be changed.
Attempting to click on the apparent pull down arrows for MaterialOne or MaterialTwo are futile. No alternatives are displayed and nothing changes. The other three parameters – Seconds, CycloidRoll, and Color all behave properly.
The fact that the spheres’ color can be changed makes it seem likely that I should also be able to change the spheres’ appearance from mesh into a solid or normal color. I can certainly initialize them as mesh basic or normal. Please ignore the Lambert or Phong as they appear as a mat black even though I added a point light to the scene, I’m just interested in getting a pull down. These two functions are from the Stemkowski source I’d cited recently.
Since you offered help, I went over ‘everything’ again. Several changes with little or no progress to show for it.
Here are the displaygui and update sphere functions.
- Code:
function displaygui(){
gui = new dat.GUI();
parameters =
{
MaterialOne: "Wireframe",
MaterialTwo: "Wireframe",
timeInSecs: 25,
CycloidRoll: true,
color: "#ffff00"
};
let sphereMaterialOne = gui.add( parameters, 'MaterialOne', [ "Basic", "Lambert", "Phong", "Wireframe" ] ).listen();
sphereMaterialOne.onChange(function(value)
{ updateSphere(); });
let sphereMaterialTwo = gui.add( parameters, 'MaterialTwo', { a:"Basic", b:"Lambert", c:"Phong", d:"Wireframe" } ).listen();
sphereMaterialTwo.onChange(function(value)
{ updateSphere(); });
let sphereColor = gui.addColor( parameters, 'color' ).name('Color').listen();
sphereColor.onChange(function(value) // onFinishChange
{ updateSphere(); });
let TracTInSecs = gui.add( parameters,'timeInSecs').min(1).max(200).step(1).name('Seconds').listen();
TracTInSecs.onChange(function(value)
{ trTimeInSecs = value; });
let rollingPi = gui.add( parameters, 'CycloidRoll').listen();
rollingPi.onChange(function(value)
{ kPiOrNot = value; });
// gui.close();
};
function updateSphere() {
let value = parameters.materialOne;
let newMaterial;
if (value == "Basic")
newMaterial = new THREE.MeshBasicMaterial( { color: 0x000000 } );
else if (value == "Lambert")
newMaterial = new THREE.MeshLambertMaterial( { color: 0x000000 } );
else if (value == "Phong")
newMaterial = new THREE.MeshPhongMaterial( { color: 0x000000 } );
else // (value == "Wireframe") // only wireframe is left
newMaterial = new THREE.MeshBasicMaterial( { wireframe: true } );
sphereMat.material = newMaterial;
value = parameters.materialTwo;
if (value == "a")
newMaterial = new THREE.MeshBasicMaterial( { color: 0x000000 } );
else if (value == "b")
newMaterial = new THREE.MeshLambertMaterial( { color: 0x000000 } );
else if (value == "c")
newMaterial = new THREE.MeshPhongMaterial( { color: 0x000000 } );
else if (value == "d")
newMaterial = new THREE.MeshBasicMaterial( { wireframe: true } );
sphereMat.material = newMaterial;
sphereMat.color.setHex( parameters.color.replace("#", "0x") );
};
By the way I had also tried implementing the http://workshop.chromeexperiments.com/examples/gui/#2--Constraining-Input example with [ 'pizza', 'chrome', 'hooray' ] that you described in your last post. I’m not delirious, I’m clearly doing something wrong. So I took the opportunity to review arrays and objects
A BRIEF JavaScript TUTORIAL: PART 1
https://discoverthreejs.com/book/introduction/javascript-tutorial-1/
It seems that javaScript has progressed since I learned it. Did you notice that the ‘var’ designators have been replaced with ‘let’ in the two functions above? I replaced all the ‘var’, variable identifiers with ‘const’ (for constants) and ‘let’ the newer variable designator. I learned several details I hadn’t come across before. Here's a great link to Mozilla’s Array page. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
After beating myself silly here I think I found my first clear evidence that I may be able to Pause.
https://discoverthreejs.com/book/first-steps/resize/
Using setAnimationLoop()
Switching to the setAnimationLoop method allows us to abstract away requestAnimationFrame() completely. Delete your current animate() function and replace with the setAnimationLoop code.
Promising?
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
You don't want to stop the rendering loop in order to pause the animation. That stops all rendering, so the user can't move the camera around while paused. You have to add it into your rendering function. Something like this:
Notice that the scene is always rendered, however, the processing code is only run when not paused.
- Code:
function render()
{
setAnimationFrame( render );
if( !paused )
{
// TODO normal processing
}
renderer.render( scene, camera );
}
Notice that the scene is always rendered, however, the processing code is only run when not paused.
Re: Animate the PI = 4 experiment
I don't think you want to use the listen function on the gui. That causes DAT to check the values and update the menu items if they change. This can be expensive, although it shouldn't be a problem in this case. Basically, only use listen if you are going to change the values yourself, in code, or some other way other than DATGUI.
Other than that, the onChange function should be called when the menu item is changed. Can you confirm that it is being executed by adding a console.log to it?
I assume the parameters variable is being initialized outside of the code that you posted. Can you confirm that? There should be a line like this in the global scope (i.e. at the same level as the render function).
You probably should initialize it there, rather than in the displaygui function, although it doesn't matter too much.
Other than that, the onChange function should be called when the menu item is changed. Can you confirm that it is being executed by adding a console.log to it?
I assume the parameters variable is being initialized outside of the code that you posted. Can you confirm that? There should be a line like this in the global scope (i.e. at the same level as the render function).
- Code:
var parameters;
You probably should initialize it there, rather than in the displaygui function, although it doesn't matter too much.
Re: Animate the PI = 4 experiment
.
Here’s the console output showing my gui changes to Color, Seconds, CycloidRoll and Paused. Note, the red errors are caused whenever the orbital camera zooms (or dollys).
dynamic animate(). Is the render function you used a new render function? I placed this 'similar code' to the end of the animate() function at the end of the piEqFour script.
I'm not all that bothered by the lack of a non-working pull-down parameter, for the time being anyway.
.
Amn. Thank you Sir, good to know. I removed ‘.listen’ from all the gui parameter items.I don't think you want to use the listen function on the gui. …. Basically, only use listen if you are going to change the values yourself, in code, or some other way other than DATGUI.
Amn. updateSphere can only be called by the onChange function. I moved the control changes to CycloidRoll and trTimeInSecs to the updateSphere function to keep all the parameters together. Here’s the current updateSphere function including the console log.Other than that, the onChange function should be called when the menu item is changed. Can you confirm that it is being executed by adding a console.log to it?
- Code:
function updateSphere() {
console.log( 'materialOne = '+ parameters.materialOne +', materialTwo = '+ parameters.materialTwo
+', color = '+ parameters.color +', Seconds = '+ parameters.timeInSecs + ', kPiOrNot = '+ parameters.CycloidRoll );
let value = parameters.materialOne;
let newMaterial;
if (value == "Basic")
newMaterial = new THREE.MeshBasicMaterial( { color: 0x000000 } );
else if (value == "Lambert")
newMaterial = new THREE.MeshLambertMaterial( { color: 0x000000 } );
else if (value == "Phong")
newMaterial = new THREE.MeshPhongMaterial( { color: 0x000000 } );
else // (value == "Wireframe") // only wireframe is left
newMaterial = new THREE.MeshBasicMaterial( { wireframe: true } );
sphereMat.material = newMaterial;
value = parameters.materialTwo;
if (value == "a")
newMaterial = new THREE.MeshBasicMaterial( { color: 0x000000 } );
else if (value == "b")
newMaterial = new THREE.MeshLambertMaterial( { color: 0x000000 } );
else if (value == "c")
newMaterial = new THREE.MeshPhongMaterial( { color: 0x000000 } );
else if (value == "d")
newMaterial = new THREE.MeshBasicMaterial( { wireframe: true } );
sphereMat.material = newMaterial;
sphereMat.color.setHex( parameters.color.replace("#", "0x") );
value = parameters.timeInSecs;
trTimeInSecs = value;
value = parameters.CycloidRoll;
kPiOrNot = value;
value = parameters.Pause;
paused = value;
};
Here’s the console output showing my gui changes to Color, Seconds, CycloidRoll and Paused. Note, the red errors are caused whenever the orbital camera zooms (or dollys).
Amn. Affirmative. Here’s the current main variable list - left messy to show prior thinking/efforts; it includes ‘let parameters;’.I assume the parameters variable is being initialized outside of the code that you posted. Can you confirm that? There should be a line like this in the global scope (i.e. at the same level as the render function). You probably should initialize it there … .
- Code:
<script>
let camera, cameraO, cameraP;
let scene, renderer;
let stats, gui;
const r = 1;
const w = 0.25; // track width
const q = 0.5; // track separation
const bRadius = 0.25; // *r;
let kPiOrNot = true;
let orthoView = true;
let orthoCamera = true;
let paused = false;
let parameters;
//let pchArray = ['pizza', 'chrome', 'hooray'];
let sphereMat;
let sphereGeom;
let sphereC, sphereS;
let distTraveledS = 0;
let distTraveledC = 0;
let trTimeInSecs = 25; // seconds
//const rollingPi = 4; // Math.PI;
const trackCircumK = 8*r;
//velocity = 10*r/trTimeInSecs;
//let speed = { Stopped: 0, Slow: 0.5, Fast: 1 };
//let whichPI = 'kinematic'; // 'geometric'
//let e = ['Apple', 'Banana'];
//let materialOne = [ "Basic", "Lambert", "Phong", "Wireframe" ];
//let materialTwo = { a:"Basic", b:"Lambert", c:"Phong", d:"Wireframe" };
//const materialOne = [ "Basic", "Lambert", "Phong", "Wireframe" ];
//const materialTwo = { a:"Basic", b:"Lambert", c:"Phong", d:"Wireframe" };
init();
function init() {
You don't want to stop the rendering loop in order to pause the animation. That stops all rendering, so the user can't move the camera around while paused. You have to add it into your rendering function. Something like this:
- Code:
function render()
{
setAnimationFrame( render );
if( !paused )
{
// TODO normal processing
}
renderer.render( scene, camera );
}
Amn. I never expected it could be that easy. Maybe that’s part of the reason ‘some people’ regard the requestAnimationFrame as the best function ever. Confusing things, I’d changed the name of the function render() back to
Notice that the scene is always rendered, however, the processing code is only run when not paused.
- Code:
requestAnimationFrame( animate );
if ( !paused ) {
renderer.render( scene, camera );
};
stats.update();
};
</script>
I'm not all that bothered by the lack of a non-working pull-down parameter, for the time being anyway.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
Don't use let, use var. There are differences between them and they can cause problems if you use let in the wrong place. It could be causing the problem with parameters.
The pausing code has nothing to do with requestAnimationFrame. The problem is you put the renderer.render( scene, camera ); part inside the pause block. Look at my example again and see that it is outside of it. That is why the orbit control isn't working.
My example render function is not a new function, you are supposed to change the existing one to reflect that, but add the processing code to the pause block. I suggest you put that processing code into its own function (which you may have already) and just call it from inside the !paused block.
With respect to event handlers, you should have a unique function for each (unless they can be shared, but they can't in this case). You can put them all together in one function, but then you are updating everything when only one thing has actually changed. Note that event handlers are often inline functions, declared where they are used rather than a full function definition.
Full function example:
Inline function definition:
The pausing code has nothing to do with requestAnimationFrame. The problem is you put the renderer.render( scene, camera ); part inside the pause block. Look at my example again and see that it is outside of it. That is why the orbit control isn't working.
My example render function is not a new function, you are supposed to change the existing one to reflect that, but add the processing code to the pause block. I suggest you put that processing code into its own function (which you may have already) and just call it from inside the !paused block.
With respect to event handlers, you should have a unique function for each (unless they can be shared, but they can't in this case). You can put them all together in one function, but then you are updating everything when only one thing has actually changed. Note that event handlers are often inline functions, declared where they are used rather than a full function definition.
Full function example:
- Code:
function render()
{
}
Inline function definition:
- Code:
gui.onChange( function( value )
{
}
);
Re: Animate the PI = 4 experiment
.
The pause checkbox is now working correctly, with orbital camera and action resuming from where it was stopped. You can see the fps is at 60 while I found a good starting line image.
Whether it's correct or not, here’s the animate function with the internal if ( !paused ) loop beginning just after the variable declarations, and requestAnimationFrame( animate ) command.
Thanks. I can now well appreciate the in-line versus the full named function descriptions, with the onChange as well as the parameters functions. I changed the displaygui function to let the onChange functions update their respective variables and eliminated the function updateSphere. I didn’t get much further today, busier than usual, and the paperwork comes first.
Now I can think of steps.
.
Amn. Copy that, all const and let designators have been changed back to var. I believe I’d mentioned my problem with the pull-down parameters before changing them to let and const, no problem switching them back. I also ‘fully typed’ two new draw down parameters, bodyMat array and object types. I say fully typed, someone showed me a Turkish question mark used as a semicolon planted in code to prevent copy/paste actions from working correctly. May be an urban code legend. Anyway, still no active pull-down parameters.Don't use let, use var. There are differences between them and they can cause problems if you use let in the wrong place. It could be causing the problem with parameters.
Amn. Even with clear instructions, I must make at least one or two mistakes before I do anything right. May as well get my mistakes out of the way as soon as possible. I was overwhelmed seeing the simple !pause loop working; stopped in amazement and went ahead and posted for the day, fully expecting a proper pause including orbital controls today.The pausing code has nothing to do with requestAnimationFrame. The problem is you put the renderer.render( scene, camera ); part inside the pause block. Look at my example again and see that it is outside of it. That is why the orbit control isn't working.
The pause checkbox is now working correctly, with orbital camera and action resuming from where it was stopped. You can see the fps is at 60 while I found a good starting line image.
Whether it's correct or not, here’s the animate function with the internal if ( !paused ) loop beginning just after the variable declarations, and requestAnimationFrame( animate ) command.
- Code:
function animate() {
var T = trTimeInSecs;
var velocity = 10*r/trTimeInSecs;
//var vel = 10 * r / T;
var increments = T*35; // roughly the fps
var dT = T/increments;
var tracSep = r+q+w; // duplicated in init.
var cTrackLengthP = 2*r + 2*Math.PI*r;
var cTrackLengthK = 2*r + 8*r;
var cTracSectP = cTrackLengthP/5;
var cTracSectK = cTrackLengthK/5;
var sTrackLength = 10*r;
var sTrackSect = 10*r/5;
var quaternion = new THREE.Quaternion;
var ang2Inc;
var bCircum = 2 * Math.PI * bRadius;
var ang2rot = 10*r/bCircum;
var kMult = 4/Math.PI;
if ( kPiOrNot )
ang2Inc = 4 * ang2rot * kMult/ increments;
else
ang2Inc = Math.PI * ang2rot / increments;
var distNextS = distTraveledS + dT*velocity;
var distNextC = distTraveledC + dT*velocity;
var curSectionS = Math.floor( distTraveledS / sTrackSect );
var curSectionC = Math.floor( distTraveledC / cTracSectK );
var nexSectionS = Math.floor( distNextS / sTrackSect );
var nexSectionC = Math.floor( distNextC / cTracSectK );
requestAnimationFrame( animate );
if ( !paused ) { // TODO normal processing
sphereS.rotation.z -= ang2Inc;
sphereC.rotation.z -= ang2Inc;
if ( nexSectionS == curSectionS + 1 ){
var pastBoundary = distNextS - nexSectionS * 2 * r;
curSectionS = curSectionS + 1;
};
if ( nexSectionC == curSectionC + 1 ){
pastBoundary = distNextC - nexSectionC * cTracSectK ; // 2 *r; //
curSectionC = nexSectionC;
};
if ( distNextC < cTracSectK ) {
sphereC.position.set( -2*r+ distNextC, 0, r );
distTraveledC = distNextC;
curSectionC = nexSectionC;
}
else if (( distNextC >= cTracSectK ) && ( distNextC < cTrackLengthK )) { // In the loop
var trackAngle = 2*Math.PI*(distNextC - cTracSectK)/trackCircumK;
sphereC.position.set( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ));
sphereC.rotation.y = trackAngle;
distTraveledC = distNextC;
curSectionC = nexSectionC;
}
else if ( distNextC >= cTrackLengthK ) {
sphereC.position.set( -2*r, 0, r );
distTraveledC = 0;
curSectionC = 0;
};
if ( distNextS < sTrackLength ) {
sphereS.position.set( -2*r+ distNextS, 0, tracSep );
distTraveledS = distNextS;
curSectionS = nexSectionS;
}
else if ( distNextS >= sTrackLength ) {
sphereS.position.set( -2*r, 0, tracSep );
distTraveledS = 0;
curSectionS = 0;
};
};
renderer.render( scene, camera );
stats.update();
};
</script>
Thanks. I can now well appreciate the in-line versus the full named function descriptions, with the onChange as well as the parameters functions. I changed the displaygui function to let the onChange functions update their respective variables and eliminated the function updateSphere. I didn’t get much further today, busier than usual, and the paperwork comes first.
Now I can think of steps.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
.
The latest: a stepAhead (frame) checkbox, and new PI type folder.
Here's how the step ahead works, in the animate function, the !pause loop start is changed to:
if pause is checked true, one can step through each subsequent animation frame rendering by clicking on stepAhead two times. The first to uncheck the box, and the second to execute the next single frame step. Rudimentary right? but adequate. The color shown is white, which can make rolling studies easier. For example, by creating masks. I screen copy the paused animation, then paste (in transparent mode) the white lined spheres onto the color of my choice – and so convert all the isolated pixels of the white lined image to any color. Also in paint, I change the black background from black to white. One can then take a series of images, changing the color slightly each time (or not) in order to build a multiple image of the rolling contact point on the track. There are probably easier ways, and paint is going away, but first, there’s something more important.
Nevyn, as you can see, I haven’t forgotten. We’d like to confirm Miles angular velocity equation, note the new PI folder with pi choices. Forgive me for taking so long to get here. My latest delay is my attention to paperwork and less than complete understanding of your 10 October posting. https://milesmathis.forumotion.com/t554p50-animate-the-pi-4-experiment#5692
Old and new gui parameter additions including folder.
Some existing and two new animate function variables.
Finally, the existing animate function’s circular track section code.
I still need to figure out the necessary changes to that last section. There seems like more than enough to work with, organizing it like this certainly helped. Feel free to comment or correct.
.
The latest: a stepAhead (frame) checkbox, and new PI type folder.
Here's how the step ahead works, in the animate function, the !pause loop start is changed to:
- Code:
if (( !paused ) || ( ( paused ) && ( stepA ) )) {
stepA = false;
if pause is checked true, one can step through each subsequent animation frame rendering by clicking on stepAhead two times. The first to uncheck the box, and the second to execute the next single frame step. Rudimentary right? but adequate. The color shown is white, which can make rolling studies easier. For example, by creating masks. I screen copy the paused animation, then paste (in transparent mode) the white lined spheres onto the color of my choice – and so convert all the isolated pixels of the white lined image to any color. Also in paint, I change the black background from black to white. One can then take a series of images, changing the color slightly each time (or not) in order to build a multiple image of the rolling contact point on the track. There are probably easier ways, and paint is going away, but first, there’s something more important.
Nevyn, as you can see, I haven’t forgotten. We’d like to confirm Miles angular velocity equation, note the new PI folder with pi choices. Forgive me for taking so long to get here. My latest delay is my attention to paperwork and less than complete understanding of your 10 October posting. https://milesmathis.forumotion.com/t554p50-animate-the-pi-4-experiment#5692
OK, I’ve made ready. Here's how. Two new and existing main variables.I suggest you implement it using the full A = 2PI*v*t/(2*PI*r) equation, but have 2 variables for the PI values (piK and piG, for example) so it would become:
A = 2PIg*v*t/(2*PIk*r)
= PIg*v*t/(PIk*r)
Then you can adjust the values of PIg and PIk to determine which one looks right when viewing the motion.
- Code:
var piG = Math.PI;
var piK = 4;
var piTopKOrNot = true;
var piBottomKOrNot = true;
var kPiOrNot = true; // CycloidRoll
Old and new gui parameter additions including folder.
- Code:
CycloidRoll: true,
twopivt: true,
twopir: true,
var whichPI = gui.addFolder('PI type. Check/true for K, leave blank for G');
var rollingPi = whichPI.add( parameters, 'CycloidRoll');
rollingPi.onChange(function(value)
{ kPiOrNot = value; });
var numeratorPi = whichPI.add( parameters, 'twopivt');
numeratorPi.onChange(function(value)
{ piTopKOrNot = value; }); // A = 2PI*v*t/(2*PI*r). piTopKOrNot is used for 2PI*v*t
var denominatorPi = whichPI.add( parameters, 'twopir');
denominatorPi.onChange(function(value)
{ piBottomKOrNot = value; }); // A = 2PI*v*t/(2*PI*r). piBottomKOrNot is used for (2*PI*r)
whichPI.open();
Some existing and two new animate function variables.
- Code:
var cTrackLengthP = 2*r + 2*Math.PI*r;
var cTrackLengthK = 2*r + 8*r;
var cTracSectP = cTrackLengthP/5;
var cTracSectK = cTrackLengthK/5;
var distNextC = distTraveledC + dT*velocity;
// A = 2PI*v*t/(2*PI*r) = numerator/denominator.
var numerator;
var denominator;
Finally, the existing animate function’s circular track section code.
- Code:
else if (( distNextC >= cTracSectK ) && ( distNextC < cTrackLengthK )) { // In the loop
var trackAngle = 2*Math.PI*(distNextC - cTracSectK)/trackCircumK;
sphereC.position.set( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ));
sphereC.rotation.y = trackAngle;
distTraveledC = distNextC;
curSectionC = nexSectionC;
};
I still need to figure out the necessary changes to that last section. There seems like more than enough to work with, organizing it like this certainly helped. Feel free to comment or correct.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
- Code:
if (( !paused ) || ( ( paused ) && ( stepA ) ))
Is the same as
- Code:
if( !paused || stepA )
However, you can implement stepping slightly differently and it will be a bit more clear.
Stepping is just selective pausing. Essentially, when the user says they want to step a single frame, they are saying 'I want to unpause this, run a single frame, and then re-pause it'. So we can do exactly that.
- Code:
if( !paused )
{
// normal processing code
...
if( stepping )
{
paused = true;
}
}
This puts a bit more of the effort into the event handlers, but not much.
Using a check-box to control pausing is bad. You need a button, and DAT allows you to use them. You can use a checkbox for the stepping, but I would tend to use a button for that too. I would also bind them to key events so the user can press the space bar, or something like that. See if you can figure out how to use buttons.
Here are the event handlers:
Pause handler:
- Code:
function( event ) {
// toggle the current state
paused = !paused;
}
Step handler:
- Code:
function( event ) {
stepping = true;
paused = false;
}
They are written as inline function (also called anonymous functions), so you should be able to drop them into the button creation code for DAT.
Re: Animate the PI = 4 experiment
.
Both spheres traveling along their tracks in a downward direction have just past their initial sections and red starting lines. The track angle rotation of the curved track sphere is already apparent. Oh, and buttons. And off of daylight savings.
The gui additions.
The two event functions.
I haven’t begun thinking/worrying about using the spacebar.
The PI switch is working. Here’s the current animate function’s circular track section code again, with two new if/else statements.
As you guessed on 10 October, and as I had previously coded correctly through trial and error - but which can now be verified true, motion around the circular track operates correctly only when the distance traveled is based on geometric pi, while the circumference must be calculated using kinematic pi. The simplification A = vt/r is not valid.
Would you care to elaborate on why this is a good confirmation of Miles angular velocity equation? I understand that curved motion is, in fact, a function of the radius of motion. How does that affect ( effect/affect I don't know how this word works either) the PI equal Four application?
P.S. remembered to add the gui additions.
.
Both spheres traveling along their tracks in a downward direction have just past their initial sections and red starting lines. The track angle rotation of the curved track sphere is already apparent. Oh, and buttons. And off of daylight savings.
Like teats on a boar bad? The new Pause and Next Frame buttons work slightly better than they did as check boxes. If in haste, one presses Next Frame instead of Pause, the screen will still pause. Here’re the two new items on the end of the parameters list.Using a check-box to control pausing is bad
- Code:
parameters =
{
timeInSecs: 40,
CycloidRoll: true,
twopivt: false,
twopir: true,
color: "#FFFF00",
StepAhead: false,
pauseButton: function(){ pauseButtonPressed() },
nFrameButton: function(){ nextFramePressed() }
};
The gui additions.
- Code:
gui.add( parameters, 'pauseButton' ).name("Pause");
gui.add( parameters, 'nFrameButton' ).name("Next Frame");
The two event functions.
- Code:
function pauseButtonPressed()
{
// toggle the current state
paused = !paused;
};
function nextFramePressed()
{
if ( paused ) {
stepA = true;
}
else if ( !paused ) {
paused = true;
stepA = false;
}
};
I haven’t begun thinking/worrying about using the spacebar.
The PI switch is working. Here’s the current animate function’s circular track section code again, with two new if/else statements.
- Code:
else if (( distNextC >= cTracSectK ) && ( distNextC < cTrackLengthK )) {
// Curve motion. distance traveled/CTrack circumference.
// 2PI*v*t/2*PI*r = PI*v*t/PI*r).
if ( piTopKOrNot ) {
numerator = piK * (distNextC - cTracSectK);
}
else {
numerator = piG * (distNextC - cTracSectK);
};
if ( piBottomKOrNot ) {
denominator = piK * r;
}
else {
denominator = piG * r;
};
var trackAngle = numerator/denominator;
sphereC.position.set( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ));
sphereC.rotation.y = trackAngle;
distTraveledC = distNextC;
curSectionC = nexSectionC;
}
Airman. A is the angle traveled by the object in circular motion. You said that if the pi’s used in the numerator and the denominator were the same, the angle traveled would reduce to, A = vt/r.
Nevyn wrote.
A = 2PIg*v*t/(2*PIk*r)
= PIg*v*t/(PIk*r)
Once you have this up and running, we might try using that full equation and see how it goes. If we find that we need it, then that is good confirmation of Miles angular velocity equation.
As you guessed on 10 October, and as I had previously coded correctly through trial and error - but which can now be verified true, motion around the circular track operates correctly only when the distance traveled is based on geometric pi, while the circumference must be calculated using kinematic pi. The simplification A = vt/r is not valid.
Would you care to elaborate on why this is a good confirmation of Miles angular velocity equation? I understand that curved motion is, in fact, a function of the radius of motion. How does that affect ( effect/affect I don't know how this word works either) the PI equal Four application?
P.S. remembered to add the gui additions.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
It currently is not confirmation of Miles' angular velocity equation, because it is not being used. You need to replace the v variable in my equation you posted above with the angular velocity equation. My guess is that it won't make much difference, if any. At the sizes we are working at here, the curvature of that equation is so close to straight that the differences will be small. However, the smaller you make this track, the more it will become important and needed.
It would probably be more correct to add it in rather than leave it out, but it isn't that important for this problem and what you are trying to show. I guess I would be interested to see it applied, and maybe run 2 tracks next to each other: one with and one without that equation. Your code is not setup for that, though, and it would take some thought to make it so. Actually, as I think about it, it wouldn't be that hard, but probably not worth the effort regardless.
I knew that A=vt/r was not right. It doesn't even look right. I was also pretty sure that the top half of the equation I was building would use 3.14, and the bottom half would use 4, once I realised that I had re-derived the same equation that I did in my Spin Velocity paper. It is always good to have confirmation, though.
I noticed you expanded this function out a bit:
But you didn't need to. They are actually equivalent, but yours uses more effort to perform the same work. Firstly, you don't need that if( !paused ) of the else statement, because if the first condition fails (if( paused )) then you know that paused is equal to false, so you don't need to test it again. Secondly, you don't need the if statements at all, because we don't care about the current state of anything. We just want to set paused to false, so that the next frame is executed, and stepA to true, so that it will pause after it executes it. This way, the next frame button works in all situations. Even if the system is not currently paused, it will pause it after executing the next frame.
It would probably be more correct to add it in rather than leave it out, but it isn't that important for this problem and what you are trying to show. I guess I would be interested to see it applied, and maybe run 2 tracks next to each other: one with and one without that equation. Your code is not setup for that, though, and it would take some thought to make it so. Actually, as I think about it, it wouldn't be that hard, but probably not worth the effort regardless.
I knew that A=vt/r was not right. It doesn't even look right. I was also pretty sure that the top half of the equation I was building would use 3.14, and the bottom half would use 4, once I realised that I had re-derived the same equation that I did in my Spin Velocity paper. It is always good to have confirmation, though.
I noticed you expanded this function out a bit:
- Code:
function nextFramePressed()
{
if ( paused ) {
stepA = true;
}
else if ( !paused ) {
paused = true;
stepA = false;
}
But you didn't need to. They are actually equivalent, but yours uses more effort to perform the same work. Firstly, you don't need that if( !paused ) of the else statement, because if the first condition fails (if( paused )) then you know that paused is equal to false, so you don't need to test it again. Secondly, you don't need the if statements at all, because we don't care about the current state of anything. We just want to set paused to false, so that the next frame is executed, and stepA to true, so that it will pause after it executes it. This way, the next frame button works in all situations. Even if the system is not currently paused, it will pause it after executing the next frame.
Re: Animate the PI = 4 experiment
I think I see a slight misunderstanding of how boolean logic works. When a boolean expression is being evaluated, not all of that expression may actually be evaluated. Let's look at some examples to see how this operates.
AND
In an AND expression, generally denoted by && in the languages we have been dealing with, you have at least 2 terms in the expression(we will keep it simple and only have 2). The AND operator requires that both sides evaluate to true, or the whole expression fails. Therefore, since we need both to succeed for the whole expression to succeed, if the first part fails, then we don't need to execute the second part. We already know that the whole expression is going to fail, so why waste the time evaluating the second expression?
OR
In an OR expression, generally denoted by ||, we find the opposite of an AND expression. In this case, either expression can make the whole expression succeed. So if the first part evaluates to true, then there is no need to evaluate the second part. Only if the first part fails will the second part be evaluated. So if the second part is evaluated, we know that the first one failed. There is no need to check it again.
The same things apply to if and else statements. If an else expression is being evaluated, then we know that the preceding ifs and else's have already failed. There is no need to check them again.
For these reasons, you must never rely on the execution of code in a boolean expression. That is, you should not call some function that performs something that you need done, because you don't know if it will get executed. That sort of code belongs inside of the if or other control structure, never in the boolean expression. Note that you have not done this, I am just pointing it out.
AND
In an AND expression, generally denoted by && in the languages we have been dealing with, you have at least 2 terms in the expression(we will keep it simple and only have 2). The AND operator requires that both sides evaluate to true, or the whole expression fails. Therefore, since we need both to succeed for the whole expression to succeed, if the first part fails, then we don't need to execute the second part. We already know that the whole expression is going to fail, so why waste the time evaluating the second expression?
OR
In an OR expression, generally denoted by ||, we find the opposite of an AND expression. In this case, either expression can make the whole expression succeed. So if the first part evaluates to true, then there is no need to evaluate the second part. Only if the first part fails will the second part be evaluated. So if the second part is evaluated, we know that the first one failed. There is no need to check it again.
The same things apply to if and else statements. If an else expression is being evaluated, then we know that the preceding ifs and else's have already failed. There is no need to check them again.
For these reasons, you must never rely on the execution of code in a boolean expression. That is, you should not call some function that performs something that you need done, because you don't know if it will get executed. That sort of code belongs inside of the if or other control structure, never in the boolean expression. Note that you have not done this, I am just pointing it out.
Re: Animate the PI = 4 experiment
.
The latest includes html information: Miles Mathis’ Physics page link, Title, list of controls and minimum Spacebar directions.
Here’s the extended Spacebar directions; holding the spacebar down allows action to continue; releasing the Spacebar pauses motion. Briefly pressing or tapping the spacebar advances the scene by frames. Perfect, although a Spacebar escape might be nice.
Sir, I tried following your directions as carefully as I could, thank you very much. I deleted the else condition but I couldn’t make the Next Frame button work without the if statement. As it turns out, the Next Frame button is also working perfectly. Using Next Frame will create a Pause, and each next Frame button click advances the scene a frame forward. Here's the current next step event handler.
In trying to post this message I see you are getting more into the logic. Good.
I found a threejs example that contains html info and uses the keyboard, “three.js - platformer demo”, and wittled the nine keys and two functions down to one. The same Next Frame logic now appears in the new keyboardControl function.
This PI Equal Four application runs horribly slow on my internet Explorer. I saw a tutorial and read somewhere that requestAnimationFrame functions varied across different browsers. They recommended adding the following code at the top of the script. I did and saw no change, does it have any value or should I get rid of it?
Seems like I’ve been making lots of changes lately, I haven’t included the CSS style or div info code changes, I’ll wait a bit.
The tracks don’t need to change size, they are a maximum distance reference limit, 10*r, with r being a millimeter or a light year. Allowing spheres to be much smaller than the tube – in radius, as small as we like, they will travel along the tube centerlines. It would then be possible for this app to show Miles’ or your full angular formula.
.
The latest includes html information: Miles Mathis’ Physics page link, Title, list of controls and minimum Spacebar directions.
Here’s the extended Spacebar directions; holding the spacebar down allows action to continue; releasing the Spacebar pauses motion. Briefly pressing or tapping the spacebar advances the scene by frames. Perfect, although a Spacebar escape might be nice.
Sir, I tried following your directions as carefully as I could, thank you very much. I deleted the else condition but I couldn’t make the Next Frame button work without the if statement. As it turns out, the Next Frame button is also working perfectly. Using Next Frame will create a Pause, and each next Frame button click advances the scene a frame forward. Here's the current next step event handler.
In trying to post this message I see you are getting more into the logic. Good.
- Code:
function nextFramePressed()
{
if ( paused ) {
stepA = true;
}
else {
paused = true;
stepA = false;
}
};
I found a threejs example that contains html info and uses the keyboard, “three.js - platformer demo”, and wittled the nine keys and two functions down to one. The same Next Frame logic now appears in the new keyboardControl function.
- Code:
var keyboardControls = (function() {
var keys = { SP : 32 };
var keysPressed = {};
(function( watchedKeyCodes ) {
var handler = function( down ) {
return function( e ) {
var index = watchedKeyCodes.indexOf( e.keyCode );
if( index >= 0 ) {
keysPressed[watchedKeyCodes[index]] = down; e.preventDefault();
if ( paused ) {
stepA = true;
}
else {
paused = true;
stepA = false;
}
}
};
};
window.addEventListener( "keydown", handler( true ), false );
window.addEventListener( "keyup", handler( false ), false );
})([
keys.SP ]);
})();
This PI Equal Four application runs horribly slow on my internet Explorer. I saw a tutorial and read somewhere that requestAnimationFrame functions varied across different browsers. They recommended adding the following code at the top of the script. I did and saw no change, does it have any value or should I get rid of it?
- Code:
window.requestAnimationFrame =
window.requestAnimationFrame ||
window.webkitReqeustAnimationFrame ||
window.mozReqeustAnimationFrame ||
window.oReqeustAnimationFrame ||
window.msReqeustAnimationFrame ||
function(callback) {
window.setTimeout(callback,1e3/60);
};
Seems like I’ve been making lots of changes lately, I haven’t included the CSS style or div info code changes, I’ll wait a bit.
However, the smaller you make this track, the more it will become important and needed.
The tracks don’t need to change size, they are a maximum distance reference limit, 10*r, with r being a millimeter or a light year. Allowing spheres to be much smaller than the tube – in radius, as small as we like, they will travel along the tube centerlines. It would then be possible for this app to show Miles’ or your full angular formula.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
.
Ok, that’s not correct. The PI=4 Experiment application shows a circular tube track at a fixed radius of curvature, regardless of the sphere size. The tubular tracks mimic StevenO’s PI=4 Experiment. You required it and I must admit I very much like the app’s tubes. Let the animated experiment tracks represent some maximum size, what good is it if we allow smaller spheres without greater curvatures of motion? One may vary timing slightly to accommodate the full formula but then nothing is being compared.
Seven parallel/concentric sets of PI=4 tracks.
How might we simulate the full circular motion formula? I submit the above diagram as one possibility.
Seven green parallel straight tracks each 10*r long, each tangent to a different concentric blue circle at varying radius of r. Seven initial overlapped 2*r straight sections. The two tracks would be separated according to the spheres’ diameter. The red lines are the 2*r distance markers.
At which point I think, why include straight tracks? We know pi=4. We might want to compare the circular motions of any two different radial tracks. One thought led to another and soon I was looking down at the solar system.
I’m back. I think the existing app’s initial setup might be tweeked or not. I’m happy with it, and feeling pangs of post partum blues. I’m glad you agreed to this project. I’ve learned a lot – concentrating on circular motion. Glad you required the tubes. You never indicated your aproval of the hoops. Come to think of it, I suppose I should try and see whether wireframe tube material is an alternative to the parallel hoops.
Looking slightly ahead, how does this process end? Do I simply post the existing code? Can a standalone app be compiled – able to run without the complete .js sources such that anyone might be able to see it? Did you have any interest in making a running copy available at the Lab?
.
You’re right, using the if statement I assumed I needed to cover all cases. Saving energy at if statements and explaining why makes for very interesting lessons. You demonstrate a fine ability at logic, you explaining why I do something wrong is scary, and greatly increases your credibility. I've missed some of what you've said, overall you've certainly taught me a lot, and forced me to learn it too by golly.Nevyn wrote. I think I see a slight misunderstanding of how boolean logic works. When a boolean expression is being evaluated, not all of that expression may actually be evaluated.
Airman said. They will travel along the tube centerlines.
Ok, that’s not correct. The PI=4 Experiment application shows a circular tube track at a fixed radius of curvature, regardless of the sphere size. The tubular tracks mimic StevenO’s PI=4 Experiment. You required it and I must admit I very much like the app’s tubes. Let the animated experiment tracks represent some maximum size, what good is it if we allow smaller spheres without greater curvatures of motion? One may vary timing slightly to accommodate the full formula but then nothing is being compared.
Seven parallel/concentric sets of PI=4 tracks.
How might we simulate the full circular motion formula? I submit the above diagram as one possibility.
Seven green parallel straight tracks each 10*r long, each tangent to a different concentric blue circle at varying radius of r. Seven initial overlapped 2*r straight sections. The two tracks would be separated according to the spheres’ diameter. The red lines are the 2*r distance markers.
At which point I think, why include straight tracks? We know pi=4. We might want to compare the circular motions of any two different radial tracks. One thought led to another and soon I was looking down at the solar system.
I’m back. I think the existing app’s initial setup might be tweeked or not. I’m happy with it, and feeling pangs of post partum blues. I’m glad you agreed to this project. I’ve learned a lot – concentrating on circular motion. Glad you required the tubes. You never indicated your aproval of the hoops. Come to think of it, I suppose I should try and see whether wireframe tube material is an alternative to the parallel hoops.
Looking slightly ahead, how does this process end? Do I simply post the existing code? Can a standalone app be compiled – able to run without the complete .js sources such that anyone might be able to see it? Did you have any interest in making a running copy available at the Lab?
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
You've lost me with these latest multi-track images. I don't see what they offer or what they are trying to achieve. I think you may have misunderstood what I meant by the track being smaller and requiring Miles' angular velocity equation. I meant a complete scale down to the photon level. This would not change the track dimensions in a relative manner, but would just change the absolute distances to be around 10^-24m.
Where does this process end? With something that is publishable, if that is what you want to achieve, or it stops whenever you want, if you just wanted to learn about circular motion and/or programming techniques. I wanted you to take more control of the application and development process, and you have done that. I wanted you to own it. I wanted you to see that you can tackle an idea and progress through it using 3D models to help you see it a bit deeper than just thought alone might have done. I wanted to rip away the training wheels so that you might gain the confidence to approach these sorts of things on your own. I am still here for help and guidance, but you can do things on your own, too.
So, I see this going in one of two ways: you develop a web page that both contains this animation, and a description of what it is showing; or you look through Miles' PI=4 papers and find somewhere that this animation will fit into it so that it can be added to my Interactive Papers section. The latter might be easier, and you may find multiple spots for it, so don't limit yourself to just one. If you want to go that way, then we will need to go through how I put those pages together, but it isn't much different to what you are doing already, so don't be worried about that.
Where does this process end? With something that is publishable, if that is what you want to achieve, or it stops whenever you want, if you just wanted to learn about circular motion and/or programming techniques. I wanted you to take more control of the application and development process, and you have done that. I wanted you to own it. I wanted you to see that you can tackle an idea and progress through it using 3D models to help you see it a bit deeper than just thought alone might have done. I wanted to rip away the training wheels so that you might gain the confidence to approach these sorts of things on your own. I am still here for help and guidance, but you can do things on your own, too.
So, I see this going in one of two ways: you develop a web page that both contains this animation, and a description of what it is showing; or you look through Miles' PI=4 papers and find somewhere that this animation will fit into it so that it can be added to my Interactive Papers section. The latter might be easier, and you may find multiple spots for it, so don't limit yourself to just one. If you want to go that way, then we will need to go through how I put those pages together, but it isn't much different to what you are doing already, so don't be worried about that.
Re: Animate the PI = 4 experiment
.
Those latest two multi-track images were just concept ideas. Having given it a fair amount of thought I believe concentric orbitals can provide a good way to demonstrate the full circular motion formula. I’ll be happy to work the idea up formally in due course. In no way do I wish to alter the current app as indicated by those two diagrams.
Ripping off my training wheels indeed! I thought it was a race against time to produce a semi-complete package before it was too late. The thought of carrying-on is a great relief. Glad to be at your disposal. Adding to your interactive papers would be wonderful.
In this image, the 122 hoops (alas, no flames yet) – 61 per track, have been replaced by two cylinders and a torus.
Cylinders and Torus. Rather than some transparent solid, I went with wireframe material. The code is far more efficient, saving 73 code lines, (down from 526 to 453), including 122 distance hoops built into the geometries. The downside is – the spheres are much less visible. The cross sections of the tubes or torus should appear round; four sides is an unacceptable diamond square that draws way too much attention to itself. Eight sides is round enough, and is shown in the image above, but with 8 long 10*r lines come two new alternate spin sets of 8 long spiral lines; 24 grey lines compared to the previous four long green lines. The spheres are much less visible. The only other problem is the “Cannot use import statement outside a module” errors when accessing both new threejs geometry sources.
Tossing out the cylinders and torus and their sources, and sticking with the previous grey circles and long green lines, I nonetheless corrected a gross inefficiency I knew I would eventually get around to. Circles were being re-created 3 times in both the straight sections and curved. Now, yZPCircle is created once. Saving appox 21 code lines, ending at 505. I think I’ll do the same with the 11 track markers. Good to know I’m finally saving energy.
.
Those latest two multi-track images were just concept ideas. Having given it a fair amount of thought I believe concentric orbitals can provide a good way to demonstrate the full circular motion formula. I’ll be happy to work the idea up formally in due course. In no way do I wish to alter the current app as indicated by those two diagrams.
Ripping off my training wheels indeed! I thought it was a race against time to produce a semi-complete package before it was too late. The thought of carrying-on is a great relief. Glad to be at your disposal. Adding to your interactive papers would be wonderful.
In this image, the 122 hoops (alas, no flames yet) – 61 per track, have been replaced by two cylinders and a torus.
Cylinders and Torus. Rather than some transparent solid, I went with wireframe material. The code is far more efficient, saving 73 code lines, (down from 526 to 453), including 122 distance hoops built into the geometries. The downside is – the spheres are much less visible. The cross sections of the tubes or torus should appear round; four sides is an unacceptable diamond square that draws way too much attention to itself. Eight sides is round enough, and is shown in the image above, but with 8 long 10*r lines come two new alternate spin sets of 8 long spiral lines; 24 grey lines compared to the previous four long green lines. The spheres are much less visible. The only other problem is the “Cannot use import statement outside a module” errors when accessing both new threejs geometry sources.
Tossing out the cylinders and torus and their sources, and sticking with the previous grey circles and long green lines, I nonetheless corrected a gross inefficiency I knew I would eventually get around to. Circles were being re-created 3 times in both the straight sections and curved. Now, yZPCircle is created once. Saving appox 21 code lines, ending at 505. I think I’ll do the same with the 11 track markers. Good to know I’m finally saving energy.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
Can you use a transparent tube and show some screenshots? Wireframe can be useful, but rarely what you want in a final product.
Don't be afraid to use a heavy transparency. Maybe 0.2 for the opacity. You might have to play with the color so that the tube is still visible. Tube transparency could also be added as a menu control, if you want. However, if used for an interactive paper, the menu will be unavailable, so don't get too attached to it.
The markers should be more visible than the rest of the tube, too. They could use some labels for the main ones we care about, showing how they match on both tracks.
What I would really like is for the current section of tube that the balls are in to light up somehow. Maybe they become a different color, a bit brighter than normal, or even a completely different color, whatever works well. The labels could also light up, even if the tubes don't.
Don't be afraid to use a heavy transparency. Maybe 0.2 for the opacity. You might have to play with the color so that the tube is still visible. Tube transparency could also be added as a menu control, if you want. However, if used for an interactive paper, the menu will be unavailable, so don't get too attached to it.
The markers should be more visible than the rest of the tube, too. They could use some labels for the main ones we care about, showing how they match on both tracks.
What I would really like is for the current section of tube that the balls are in to light up somehow. Maybe they become a different color, a bit brighter than normal, or even a completely different color, whatever works well. The labels could also light up, even if the tubes don't.
Re: Animate the PI = 4 experiment
.
Yes I was skeptical, it’s easy to see the mostly transparent, aerogel-like material making up the cylinders and torus do make the tracks appear more unified or defined; the lines aren’t just hanging in empty space. Even though your suggested opacity level looked best there’s no way around the fact objects inside the tube are dimmer. All the lines and hoops were inside the tubes, note the two-toned blue sphere at the right, so I expanded the hoops and marker lines outward.
There’s one exceptional odd area, the section of torus that intersects with the initial straight section leading to the starting/finishing lines.
.
Amn. Of course; here are two sets - white and blue clear materials for comparison.Can you use a transparent tube and show some screenshots? Wireframe can be useful, but rarely what you want in a final product.
Yes I was skeptical, it’s easy to see the mostly transparent, aerogel-like material making up the cylinders and torus do make the tracks appear more unified or defined; the lines aren’t just hanging in empty space. Even though your suggested opacity level looked best there’s no way around the fact objects inside the tube are dimmer. All the lines and hoops were inside the tubes, note the two-toned blue sphere at the right, so I expanded the hoops and marker lines outward.
There’s one exceptional odd area, the section of torus that intersects with the initial straight section leading to the starting/finishing lines.
Amn. I eliminated grey hoops that were drawn at the same locations as the red markers and so now the markers are more distinct, let me know if you’d like to make them moreso. Points if you notice the marker horizontal arms are still a bit short.The markers should be more visible than the rest of the tube, too. They could use some labels for the main ones we care about, showing how they match on both tracks.
Amn. Two possibilities come to my over-optimistic, in-experienced mind. 1) install point lights inside each sphere, The tubes, made out of meshBasicMaterial ‘don’t react to light’. They may need to be upgraded to Lambert in order to make the track light up where the sphere is. Or 2) use shader material. That sounds sexier but probably way more complicated.What I would really like is for the current section of tube that the balls are in to light up somehow.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
You definitely don't want to use lights, nor shaders either. All you need is to create individual track segments with their own Material object (not shared) and update the color property of the Material depending on whether the ball is in that segment or not.
I don't think the grey markers are needed. They just clutter up the track. The red ones are fine. Maybe make the PI marker a different color to differentiate it.
That small section is caused by the additive blending on two transparent things that are inline with respect to the camera. You can change the blending method, but I don't know what is available and whether it will fix it as you want it to. Worth a go, though.
While transparent tubes will lower the intensity of the ball color, only you really know that. The general user will just see it in that subdued way. It is easy to get used to vibrant colors, but that doesn't mean they are better. I get hooked on vibrancy quite often, and have to convince myself away from it.
I don't think the grey markers are needed. They just clutter up the track. The red ones are fine. Maybe make the PI marker a different color to differentiate it.
That small section is caused by the additive blending on two transparent things that are inline with respect to the camera. You can change the blending method, but I don't know what is available and whether it will fix it as you want it to. Worth a go, though.
While transparent tubes will lower the intensity of the ball color, only you really know that. The general user will just see it in that subdued way. It is easy to get used to vibrant colors, but that doesn't mean they are better. I get hooked on vibrancy quite often, and have to convince myself away from it.
Re: Animate the PI = 4 experiment
.
Thanks for calling me off the lights, I had gotten two stuck in the tube openings.
Just when the hoops and markers were cooperating – the hoops are gone. I take it you want me to drop the four long green lines as well? Done. The red horizontal and vertical lines too?
I'll change the pi marker next. Do you still want labels? Lighting sections of the tubes eh, interesting. I must contemplate that.
Noticed today that there’s no DAT gui when I run this thing in fireFox. No problem, I'll continue using chrome.
.
Thanks for calling me off the lights, I had gotten two stuck in the tube openings.
Just when the hoops and markers were cooperating – the hoops are gone. I take it you want me to drop the four long green lines as well? Done. The red horizontal and vertical lines too?
I'll change the pi marker next. Do you still want labels? Lighting sections of the tubes eh, interesting. I must contemplate that.
Noticed today that there’s no DAT gui when I run this thing in fireFox. No problem, I'll continue using chrome.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
Looking better already!
The red markers could be replaced by something a bit more 3D. They can go outside of the tube, and they can be wider than a line. They also don't need to be transparent, if that works. Think of some sort of join across 2 separate tubes that rises above the tube, with beveled edges that connect to the tubes. That would be 3 pieces: 2 beveled edges and a center piece. The center piece could be what highlights as the ball passes that marker. That's just one idea that could work.
Some textures would probably be useful, too. At least for the balls, but even the tubes, maybe. That does get complicated but you can use the textures from my site to avoid cross origin problems.
What are those red and green thingy's on the bottom right? Failed spheres?
I'm kinda liking the idea of a light being inside the ball. But it would not roll with the ball, but must curve around the circle. Could be tricky, but could look good too.
The red markers could be replaced by something a bit more 3D. They can go outside of the tube, and they can be wider than a line. They also don't need to be transparent, if that works. Think of some sort of join across 2 separate tubes that rises above the tube, with beveled edges that connect to the tubes. That would be 3 pieces: 2 beveled edges and a center piece. The center piece could be what highlights as the ball passes that marker. That's just one idea that could work.
Some textures would probably be useful, too. At least for the balls, but even the tubes, maybe. That does get complicated but you can use the textures from my site to avoid cross origin problems.
What are those red and green thingy's on the bottom right? Failed spheres?
I'm kinda liking the idea of a light being inside the ball. But it would not roll with the ball, but must curve around the circle. Could be tricky, but could look good too.
Re: Animate the PI = 4 experiment
.
The two images are intended to convey the resulting ‘dramatic’ light and shodows cast, especially on the curved track.
It wasn’t too difficult to install a point light in each sphere and advance them along with the spheres. They don’t need to rotate. The red line markers are currently transparent rubber grommets that don’t always light up.
The red and green thingy's were point light helpers. Now the helpers are much smaller blue spheres and white octagons identifying the point light source.
I have no problem with the torus/initial straight section overlap.
Now that the grey lines are gone, I turned them into 50 or 60 tube sections. The result, all the internal walls, worked just as well as the grommets and were just as distracting as the grey lines. Now I’m happy without them. Keep it pure and simple, there’s plenty involved in getting the lighting right. That is, of course, if you agree.
Here, the section markers are two concentric circles.
How do I ensure that all surfaces - front, back, and inside of the grommets and tubes are reflecting light?
.
The two images are intended to convey the resulting ‘dramatic’ light and shodows cast, especially on the curved track.
It wasn’t too difficult to install a point light in each sphere and advance them along with the spheres. They don’t need to rotate. The red line markers are currently transparent rubber grommets that don’t always light up.
The red and green thingy's were point light helpers. Now the helpers are much smaller blue spheres and white octagons identifying the point light source.
I have no problem with the torus/initial straight section overlap.
Now that the grey lines are gone, I turned them into 50 or 60 tube sections. The result, all the internal walls, worked just as well as the grommets and were just as distracting as the grey lines. Now I’m happy without them. Keep it pure and simple, there’s plenty involved in getting the lighting right. That is, of course, if you agree.
Here, the section markers are two concentric circles.
How do I ensure that all surfaces - front, back, and inside of the grommets and tubes are reflecting light?
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
Airman wrote:How do I ensure that all surfaces - front, back, and inside of the grommets and tubes are reflecting light?
Every Material object has a side property which can be THREE.FrontSide, THREE.BackSide, or THREE.DoubleSide. This determines which side will be rendered. If the camera is facing the back side, but only the front should be rendered, then it won't render. Set the grommets (and probably the tubes) to DoubleSide and it should work as you want it to.
Try using a SpotLight. This has a position and a direction, which should point along the velocity vector for the ball. This may require some special handling for the curved section (which I was referring to in the last post). You may be able to just set the lights direction to the velocity and everything will work out. Just have a play with it and see what you can do.
Re: Animate the PI = 4 experiment
.
Thanks, DoubleSide makes both the cylinders and torus look better.
A spot light from above.
With respect to the spot light, it's a bit slow at present. The: position, intensity, angle, no problem. I haven’t pointed it reliably yet, let alone at a moving target. The world and the group coordinates are off a little, allowing coordinate simplicity and orbital camera ease.
I’ll keep at it.
.
Thanks, DoubleSide makes both the cylinders and torus look better.
A spot light from above.
Copy that. My first effort at including a spot light is included. You can’t tell from this image, the spotLight helper shows the light is directed at the center of the circular track. This first ‘opportunity’ for learning lights has been more fun than I’d expected.Nevyn wrote. Try using a SpotLight.
With respect to the spot light, it's a bit slow at present. The: position, intensity, angle, no problem. I haven’t pointed it reliably yet, let alone at a moving target. The world and the group coordinates are off a little, allowing coordinate simplicity and orbital camera ease.
I’ll keep at it.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
I was thinking that the spot light would be inside the ball. Like head-lights on your car.
Re: Animate the PI = 4 experiment
.
The track's top and bottom views.
Understood. Spotlights inside the spheres, acting like car headlights. I usually post regularly, wherever I am. Yesterday, I could only manage pointing a stationary spotlight at (0,0,0).
After that post and a few more hours frustration I found the answer to my question.
spotlight-cant-set-target-correctly
https://discourse.threejs.org/t/spotlight-cant-set-target-correctly/3674
That reference includes an interesting horizontal spotlight that might make a good spinning emergency vehicle light - or a rolling particle (?).
Apparently the spotlight, spotlight.position and spotlight.target all must be global variables which are added to the scene and updated in the animation loop.
I installed the spot light in the sphere on the straight track. The sphere in the curved track still has the internal point light. There’s also an ambient light, and a point light also in the straight track sphere.
Why does the bottom of the track look so much nicer than the top?
.
The track's top and bottom views.
Understood. Spotlights inside the spheres, acting like car headlights. I usually post regularly, wherever I am. Yesterday, I could only manage pointing a stationary spotlight at (0,0,0).
After that post and a few more hours frustration I found the answer to my question.
spotlight-cant-set-target-correctly
https://discourse.threejs.org/t/spotlight-cant-set-target-correctly/3674
That reference includes an interesting horizontal spotlight that might make a good spinning emergency vehicle light - or a rolling particle (?).
Apparently the spotlight, spotlight.position and spotlight.target all must be global variables which are added to the scene and updated in the animation loop.
I installed the spot light in the sphere on the straight track. The sphere in the curved track still has the internal point light. There’s also an ambient light, and a point light also in the straight track sphere.
Why does the bottom of the track look so much nicer than the top?
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
You don't want to use the target property. That is used to make the light point at that target, but you don't have a target to follow.
You should be able to put the light into a Group that contains the ball, but is higher than where the rolling rotation is being applied. If you don't have one, create one. That is, the Group is used to move the ball along the track, while a lower Group (or maybe even the sphere itself) is rotated based on the rolling action. This allows the light to move along with the ball, but is not rotated with it. However, you do need the rotation from the curved track to be applied to that higher level Group, so that the light always points along the track (i.e. forward). You may need to separate out some objects to accomplish this.
The bottom of the track may look nicer because of the way the light is pointing. It may not be symmetrical along the track axis.
You should be able to put the light into a Group that contains the ball, but is higher than where the rolling rotation is being applied. If you don't have one, create one. That is, the Group is used to move the ball along the track, while a lower Group (or maybe even the sphere itself) is rotated based on the rolling action. This allows the light to move along with the ball, but is not rotated with it. However, you do need the rotation from the curved track to be applied to that higher level Group, so that the light always points along the track (i.e. forward). You may need to separate out some objects to accomplish this.
The bottom of the track may look nicer because of the way the light is pointing. It may not be symmetrical along the track axis.
Re: Animate the PI = 4 experiment
.
ballOne (or ballTwo) is a 3D object. sphereC is a mesh that is added to ballOne. ballOne (or. ballTwo) is added to the group, grp. grp is added to the scene. Have I screwed up wrong or right? Can we add point lights at the sphere’s north and south poles?
PI = 4 Experiment. Lights. At present, each sphere moves along with: 1) a point light – a tiny sphere at the center of the yellow spheres; 2) a point light helper - tight wireframe octahedron; 3) a spot light and 4) a spot light helper - the wireframe ‘headlight’ which indicates the extent and direction of the spot light beams. Along the curve, the beam is directed at a constant angle trackAngle + Math.PI/3. In the main image, the tracks are lit up by an ambient white light at the default intensity of 1. The ambient light for the two inset loops is 2.5.
After some effort at playing with the spotLight I found it made small difference through the curve. The pointLight is much more effective. The opposite is true along the straightaway, where compared to the pointLight, the headlight is more effective at illuminating the walls along the straight tracks.
Notice the 'bottom' of the torus's most distant side in the image at the top. I flipped the track torus and cylinders - top and bottom – and found I was able to reverse the colors from the image I posted last time. Akin to application of a reflective or on half of the inside walls, top or bottom. Seems like a property but i haven't looked.
.
Woe’s me to disagree, so I led with the image above. spotlight.target works fine. spotLight.position and spotLight.target are both advanced by using sphereC’s trackAngle position. Here’s most of the curved loop portion of the animate function (excluding the pi switch lines).You don't want to use the target property. That is used to make the light point at that target, but you don't have a target to follow.
- Code:
else if (( distNextC >= cTracSectK ) && ( distNextC < cTrackLengthK )) {
// pi switch stuff omited
var trackAngle = numerator/denominator;
sphereC.position.set( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ));
pointLightC.position.set( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ));
spotLightC.position.set( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ));
spotLightC.target.position.x = r*Math.sin( trackAngle + Math.PI/3 );
spotLightC.target.position.z = r*Math.cos( trackAngle + Math.PI/3 );
sphereC.rotation.y = trackAngle;
distTraveledC = distNextC;
curSectionC = nexSectionC;
};
ballOne (or ballTwo) is a 3D object. sphereC is a mesh that is added to ballOne. ballOne (or. ballTwo) is added to the group, grp. grp is added to the scene. Have I screwed up wrong or right? Can we add point lights at the sphere’s north and south poles?
PI = 4 Experiment. Lights. At present, each sphere moves along with: 1) a point light – a tiny sphere at the center of the yellow spheres; 2) a point light helper - tight wireframe octahedron; 3) a spot light and 4) a spot light helper - the wireframe ‘headlight’ which indicates the extent and direction of the spot light beams. Along the curve, the beam is directed at a constant angle trackAngle + Math.PI/3. In the main image, the tracks are lit up by an ambient white light at the default intensity of 1. The ambient light for the two inset loops is 2.5.
After some effort at playing with the spotLight I found it made small difference through the curve. The pointLight is much more effective. The opposite is true along the straightaway, where compared to the pointLight, the headlight is more effective at illuminating the walls along the straight tracks.
Notice the 'bottom' of the torus's most distant side in the image at the top. I flipped the track torus and cylinders - top and bottom – and found I was able to reverse the colors from the image I posted last time. Akin to application of a reflective or on half of the inside walls, top or bottom. Seems like a property but i haven't looked.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
.
Of course I had to try adding north and south pole point lights. The image shows the results. The red and blue pole pointLights remain at the poles for sphereS in the straight track at the top. Not so for the pole lights for the curved track sphere sphereC, the roll matches that of sphereS.
The pole lights for the curved path sphereC continue spinning with the initial z axis roll. The center of sphereC moves around the curved track as per the trackAngle. sphereC’s pole lights need one more rotation – the rotation of the spheres about its y axis, equal to the track angle.
Nevyn, I hope I haven't offended you. I earnestly wish to learn how to do these things more efficiently. As a rule, I do not ignore your directions, if anything, I’m routinely guilty of plain old misunderstanding.
.
Of course I had to try adding north and south pole point lights. The image shows the results. The red and blue pole pointLights remain at the poles for sphereS in the straight track at the top. Not so for the pole lights for the curved track sphere sphereC, the roll matches that of sphereS.
The pole lights for the curved path sphereC continue spinning with the initial z axis roll. The center of sphereC moves around the curved track as per the trackAngle. sphereC’s pole lights need one more rotation – the rotation of the spheres about its y axis, equal to the track angle.
Nevyn, I hope I haven't offended you. I earnestly wish to learn how to do these things more efficiently. As a rule, I do not ignore your directions, if anything, I’m routinely guilty of plain old misunderstanding.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
.
Attempting to replace the wireframe spheres with a new sphere material.
Both sphere’s pole point lights are now rolling correctly. I used an axis angle operation. Here’s the changes to the same animate frunction loop section I posted last Thursday.
You indicated there usually isn’t a good reason for a final wireframe object. Now seemed like a good time to try a transparent sphere; like I did with boids. I tried transparent Lambert and Phong spheres so as to be able to enjoy the rolling motion. Unfortunately, the spheres blink in and out of view – depending on the angle of view. When out, the center and two pole point lights are perfectly visible rolling along. Oh well, I certainly enjoyed the excersize in including them, I won’t feel obliged to keep them there. But I do want anyone to be able to get a good view of the rolling action and that requires more that a featureless surface.
.
Attempting to replace the wireframe spheres with a new sphere material.
Both sphere’s pole point lights are now rolling correctly. I used an axis angle operation. Here’s the changes to the same animate frunction loop section I posted last Thursday.
- Code:
// pi switch stuff omited
var trackAngle = numerator/denominator;
var sphereCenterPoint = new THREE.Vector3( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ) );
sphereC.position.set( sphereCenterPoint.x, sphereCenterPoint.y, sphereCenterPoint.z );
pointLightC.position.set( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ));
var sphereAxis = new THREE.Vector3( 0, 1, 0 );
var northRoll = new THREE.Vector3( ptLtPos*Math.sin( sRotation ), ptLtPos*Math.cos( sRotation ), 0 );
northRoll.applyAxisAngle( sphereAxis, trackAngle );
var southRoll = new THREE.Vector3( ptLtPos*Math.sin( sRotation + Math.PI ), ptLtPos*Math.cos( sRotation + Math.PI ), 0 );
southRoll.applyAxisAngle( sphereAxis, trackAngle );
var northVector = new THREE.Vector3( sphereC.position.x + northRoll.x, sphereC.position.y + northRoll.y, sphereC.position.z + northRoll.z );
var southVector = new THREE.Vector3( sphereC.position.x + southRoll.x, sphereC.position.y + southRoll.y , sphereC.position.z + southRoll.z );
pointLightCN.position.set( northVector.x, northVector.y, northVector.z );
pointLightCS.position.set( southVector.x, southVector.y, southVector.z );
spotLightC.position.set( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ));
spotLightC.target.position.x = r*Math.sin( trackAngle + Math.PI/3 );
spotLightC.target.position.z = r*Math.cos( trackAngle + Math.PI/3 );
sphereC.rotation.y = trackAngle;
distTraveledC = distNextC;
curSectionC = nexSectionC;
You indicated there usually isn’t a good reason for a final wireframe object. Now seemed like a good time to try a transparent sphere; like I did with boids. I tried transparent Lambert and Phong spheres so as to be able to enjoy the rolling motion. Unfortunately, the spheres blink in and out of view – depending on the angle of view. When out, the center and two pole point lights are perfectly visible rolling along. Oh well, I certainly enjoyed the excersize in including them, I won’t feel obliged to keep them there. But I do want anyone to be able to get a good view of the rolling action and that requires more that a featureless surface.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
.
As shown, the straightaway particle rolls only about it z-axis. In addition to the z-roll, the curved path particle must also rotate about its y axis.
You indicated I should change my object structure, I believe I’ve made progress. Here’s the latest changes to the section I posted last time.
The animate function now advances ballOne instead of sphereC. sphereC is still added to ballOne, the point lights and new set of three grommets are now also added to ballOne in the init function.
I haven’t attempted to move the spotlights yet. I also want to install rear direction spot lights and four more point lights. I suppose I can add a larger transparent sphere to remove any possible bumps and improve the final product’s visual appeal through some phong adjustment.
Hard to tell with just a single view, but I think the spheres look good and they show rotations well. Having no desire for some sphereical texture like a favorite celestial body or an eyeball, would I need to create a local server in order to do so? I would rather come up with geometric features. At first I tried making hemispheres and the like from spherical buffer geometry without any success whatsoever, and no idea why - save for the Muses. All the better to find a ‘grommet’ solution that looks quite distinctive and goes well with the curved track’s quartertrack markers – see what I mean?
.
As shown, the straightaway particle rolls only about it z-axis. In addition to the z-roll, the curved path particle must also rotate about its y axis.
You indicated I should change my object structure, I believe I’ve made progress. Here’s the latest changes to the section I posted last time.
- Code:
// pi switch stuff omited
var trackAngle = numerator/denominator;
var sphereCenterPoint = new THREE.Vector3( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ) );
ballOne.position.set( sphereCenterPoint.x, sphereCenterPoint.y, sphereCenterPoint.z );
ballOne.rotation.y = trackAngle;
spotLightC.position.set( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ));
spotLightC.target.position.x = r*Math.sin( trackAngle + Math.PI/3 );
spotLightC.target.position.z = r*Math.cos( trackAngle + Math.PI/3 );
distTraveledC = distNextC;
curSectionC = nexSectionC;
The animate function now advances ballOne instead of sphereC. sphereC is still added to ballOne, the point lights and new set of three grommets are now also added to ballOne in the init function.
I haven’t attempted to move the spotlights yet. I also want to install rear direction spot lights and four more point lights. I suppose I can add a larger transparent sphere to remove any possible bumps and improve the final product’s visual appeal through some phong adjustment.
Hard to tell with just a single view, but I think the spheres look good and they show rotations well. Having no desire for some sphereical texture like a favorite celestial body or an eyeball, would I need to create a local server in order to do so? I would rather come up with geometric features. At first I tried making hemispheres and the like from spherical buffer geometry without any success whatsoever, and no idea why - save for the Muses. All the better to find a ‘grommet’ solution that looks quite distinctive and goes well with the curved track’s quartertrack markers – see what I mean?
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Re: Animate the PI = 4 experiment
I feel like using the target property for the light is wrong. Yes, it works, but that doesn't mean it is the right way to get it to work. However, the alternative is complicated because it requires setting up the scene graph in the right way and then requires the rolling motion to be handled in a special way. Using the target property as you are does not really produce the strictly correct angling. The light is pointing towards the inside of the circle, like a car that is drifting instead of driving around the curve. However, that isn't a big issue.
The balls should not be transparent. Only the tubes because we need to see through them to see the balls.
In order to use textures, yes, you need to run it in a server with special permissions (which require some advanced web server administration), although if it is being served from the same place as the app, then those permissions are not needed. However, you can refer to the textures on my site because I have setup those permissions. It is fine if you don't want to use them, but they do make a really nice touch.
I am a bit concerned about statements like this:
Not because it is wrong, exactly, but it looks wrong. If I found this app, and looked over the code to see if it is valid, and found that statement, then I would assume the whole premise is wrong and PI does not equal 4. Why? Because that statement uses PI=3.14. Any time you are using trig functions, you are using 3.14.
Now, it isn't wrong, because it is the calculation of trackAngle that uses PI=4, and that value is setting the distance around the circle, but most people won't see that distinction. You would have to make that argument, assuming that you were even given the opportunity to argue it. Most would not give you that opportunity because they want this to be wrong. We are on the back foot on this one and don't need to be giving ammunition to the other side.
The main reason I don't like it, though, is because it is not based on motion. It is based on trigonometry. It might give you the right answer, but it doesn't do it in the right way. Remember every time your math teachers told you it isn't about getting the right answer, it is about how you got it? This is what they meant.
The math you are using is based on a circle. The ball moving around the track is not based on a circle. Effectively, what that math is doing is equivalent to the ball reaching the curve, shooting a tether to the center of the circle, and letting that tether pull it around the curve. The real ball, however, is pushed around the curve because it meets resistance to its intended path. One is from the inside and one is from the outside. They both achieve the same motion, but one represents reality while the other does not.
I can't figure out if this matters enough to worry about. I would do it based on motion because that represents the problem. That creates an app that is harder to refute because it operates in a more direct manner. However, visually, they create the same animation. I'm not even sure that the math would end up that different anyway. The same position needs to be calculated, the circle still needs to be taken into account, so they might end up very close anyway. I am more inclined to worry about getting it looking good and fit into a page for publishing.
The balls should not be transparent. Only the tubes because we need to see through them to see the balls.
In order to use textures, yes, you need to run it in a server with special permissions (which require some advanced web server administration), although if it is being served from the same place as the app, then those permissions are not needed. However, you can refer to the textures on my site because I have setup those permissions. It is fine if you don't want to use them, but they do make a really nice touch.
I am a bit concerned about statements like this:
- Code:
spotLightC.position.set( r*Math.sin( trackAngle ), 0, r*Math.cos( trackAngle ));
Not because it is wrong, exactly, but it looks wrong. If I found this app, and looked over the code to see if it is valid, and found that statement, then I would assume the whole premise is wrong and PI does not equal 4. Why? Because that statement uses PI=3.14. Any time you are using trig functions, you are using 3.14.
Now, it isn't wrong, because it is the calculation of trackAngle that uses PI=4, and that value is setting the distance around the circle, but most people won't see that distinction. You would have to make that argument, assuming that you were even given the opportunity to argue it. Most would not give you that opportunity because they want this to be wrong. We are on the back foot on this one and don't need to be giving ammunition to the other side.
The main reason I don't like it, though, is because it is not based on motion. It is based on trigonometry. It might give you the right answer, but it doesn't do it in the right way. Remember every time your math teachers told you it isn't about getting the right answer, it is about how you got it? This is what they meant.
The math you are using is based on a circle. The ball moving around the track is not based on a circle. Effectively, what that math is doing is equivalent to the ball reaching the curve, shooting a tether to the center of the circle, and letting that tether pull it around the curve. The real ball, however, is pushed around the curve because it meets resistance to its intended path. One is from the inside and one is from the outside. They both achieve the same motion, but one represents reality while the other does not.
I can't figure out if this matters enough to worry about. I would do it based on motion because that represents the problem. That creates an app that is harder to refute because it operates in a more direct manner. However, visually, they create the same animation. I'm not even sure that the math would end up that different anyway. The same position needs to be calculated, the circle still needs to be taken into account, so they might end up very close anyway. I am more inclined to worry about getting it looking good and fit into a page for publishing.
Re: Animate the PI = 4 experiment
.
Today’s images include low ambient and downward directional lighting, showing how nine separate lights within each sphere illuminates more than a 2*r portion of track (the circular track’s centerline diameter).
The spheres are traveling through ‘transparent tubes’ and so they are never observed ‘directly’. I suppose that might make a specific visual product more or less difficult to achieve. I just started learning the subject. Do you have any comments, suggestions or recommendations you require or would like to see? Please pardon my earlier texture comment, of course if you directed me to use textures I would gladly comply. Shaders might be an option, any thought about that?
I should mention, about the spacebar option, holding down to advance the motion, releasing to stop motion. I noticed that a single press and release of the spacebar counts as two frame advances. Works fine if you’re aware of it, till you need finer control such as changing the rolling increments on the control panel. I would expect we need some controls. You know the constraints and the big picture.
I’m running out of ideas and tasks, what’s next? Do you have site requirements?
Reading your most recent post - the app may look and work correctly; its objectionable because of its use of geometric pi? True, the application is simple, I though it was based on rate*tine=distance, it certainly isn't based on force equations. Geometric pi is a tool. We recognize the limits of the tool, not just reject the tool for subjective reasons. I'll try to understand your comment better.
*ballMesh contains: 2 concentric spheres (solid yellow and slightly larger transparent); three mutually orthogonal rings; and nine different colored lights. Six point lights at the ring intersections, and another point light and two spotlights (forward and backward directed) at the center.
Close to the 8*r marker, both particles are almost back in y-synch.
.
Today’s images include low ambient and downward directional lighting, showing how nine separate lights within each sphere illuminates more than a 2*r portion of track (the circular track’s centerline diameter).
The spheres are traveling through ‘transparent tubes’ and so they are never observed ‘directly’. I suppose that might make a specific visual product more or less difficult to achieve. I just started learning the subject. Do you have any comments, suggestions or recommendations you require or would like to see? Please pardon my earlier texture comment, of course if you directed me to use textures I would gladly comply. Shaders might be an option, any thought about that?
I made a change which may correct that a bit; the code line you quoted is gone. I created a new variable – ballMesh*. All the individual objects making up each sphere is first added to ballMesh. ballMesh is then added to the 3D objects ballOne and ballTwo. Eliminating those two spotlight positions in that animate loop section. That still leaves the spotlight targeting alongside advancing ballOne and ballTwo.I feel like using the target property for the light is wrong
I should mention, about the spacebar option, holding down to advance the motion, releasing to stop motion. I noticed that a single press and release of the spacebar counts as two frame advances. Works fine if you’re aware of it, till you need finer control such as changing the rolling increments on the control panel. I would expect we need some controls. You know the constraints and the big picture.
I’m running out of ideas and tasks, what’s next? Do you have site requirements?
Reading your most recent post - the app may look and work correctly; its objectionable because of its use of geometric pi? True, the application is simple, I though it was based on rate*tine=distance, it certainly isn't based on force equations. Geometric pi is a tool. We recognize the limits of the tool, not just reject the tool for subjective reasons. I'll try to understand your comment better.
*ballMesh contains: 2 concentric spheres (solid yellow and slightly larger transparent); three mutually orthogonal rings; and nine different colored lights. Six point lights at the ring intersections, and another point light and two spotlights (forward and backward directed) at the center.
Close to the 8*r marker, both particles are almost back in y-synch.
.
LongtimeAirman- Admin
- Posts : 2078
Join date : 2014-08-10
Page 2 of 8 • 1, 2, 3, 4, 5, 6, 7, 8
Similar topics
» PI NINE - Pi experiment with two edge track
» How about an Experiment to Simulate Attraction?
» The Event Horizon Telescope experiment
» Photonics experiment resolves quantum paradox
» Revisiting the Pound-Rebka experiment in light of Miles' new Gravity Paper and the Charge Field
» How about an Experiment to Simulate Attraction?
» The Event Horizon Telescope experiment
» Photonics experiment resolves quantum paradox
» Revisiting the Pound-Rebka experiment in light of Miles' new Gravity Paper and the Charge Field
Page 2 of 8
Permissions in this forum:
You cannot reply to topics in this forum