Jump to content

SOLVED: Path in the shape of Infinity Symbol?


JackFalcon
 Share

Recommended Posts

Hello,

    Does anyone know how to create a path or lines, in a closed loop, in the shape of an Infinity Symbol?

    I am pretty sure I saw one in the playground, but cannot find it now.

     For example: Gerono OR Bernoulli:

https://gamedev.stackexchange.com/questions/43691/how-can-i-move-an-object-in-an-infinity-or-figure-8-trajectory 

     The Parameterization is said to be with the following equation:

x = cos(t);
y = sin(2*t) / 2;

      I ran into a few errors trying to populate it on the first quick attempt....

 Any advice on how to populate Gerono parameterization into the following track (editPoints)?

var track = BABYLON.MeshBuilder.CreateLines('track', {points: editPoints}, scene);

 

Link to comment
Share on other sites

@JohnK and @bulisor ... elegant!

Gerono and Bernoulli? Wow... extra-credit. Can't wait to learn... 

Attempted algorithm missing this part: 

t < 2 * Math.PI; t += Math.PI / 36

Oh! Oh, wow... gets it now, thanks!

Far better than "lets draw infinity" attempt (with editable paths).

image.thumb.png.b9fc618f440511d75cc2cc0c365b9a39.png

Path-Editing holds secondary use ... 

JohnK, playground (PBTs) in progress... 

... afalcon on a vector.

[thanks again].

Link to comment
Share on other sites

Intriguing extension...to this awesome math.

How to govern the speed of the animated cube?

Guesses to follow.... :). #1 increase number of points, OR drag the frame-rate... but there has to be a better way. 

What is the most elegant and performant way to govern the speed of the animated box?

After that, solutions available on Motion-Path ORIENTATION (using LookAt) and ROLL on curve. 

Thx: 

@JohnK & @bulisor 

 

Link to comment
Share on other sites

TWEEN between curve points...?  

<testing>

Looks deeper into those PATH points...

image.thumb.png.c533d7da6c40ad7c42a030f1a23622e6.png

A nice function for adding editable points to each curve vertex:


            /**********************************SHOW-EDIT-NODES*****************************/
            // Example:  showEditNodes(points,{type:'box', size:0.25})
            var showEditNodes = function (points, config){
                var numNodes = points.length;
                var editType = config.type || "box";
                var editSize = config.size || 1;
                var editNode;
                var greenMat = new BABYLON.StandardMaterial("green1", scene);
                greenMat.diffuseColor = new BABYLON.Color3(0, 1, 0);
                var redMat = new BABYLON.StandardMaterial("red1", scene);
                redMat.diffuseColor = new BABYLON.Color3(1, 0, 0);
                var blueMat = new BABYLON.StandardMaterial("blue1", scene);
                blueMat.diffuseColor = new BABYLON.Color3(0, 0, 1);

                for (var i=0; i < numNodes; i++){
                    if(editType==='box'){
                        editNode = BABYLON.Mesh.CreateBox("cube" + i, 0.25, scene);
                    }else if(editType==='sphere'){
                        // Parameters: name, subdivs, size, scene
                        editNode = BABYLON.Mesh.CreateSphere("editNode"+i, 1, 0.75, scene);
                    }
                    //position-editNodes.
                    editNode.position = points[i];
                    //init-edit-state-.
                    editNode.actionManager = new BABYLON.ActionManager(scene);
                    editNode.editMode = "none";
                    editNode.vectorIndex = i;

                    editNode.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, function (evt) {
                        var eNode = evt.meshUnderPointer;
                        if(eNode.editMode === 'none' ){
                            eNode.material = greenMat;
                            eNode.editMode='green'
                            selectedEditNodes.push(eNode);
                        }else if(eNode.editMode === 'green' ){
                            eNode.material = blueMat;
                            eNode.editMode='blue'
                        }else  if(eNode.editMode === 'blue' ){
                            eNode.material = redMat;
                            eNode.editMode='red'
                        }else  if(eNode.editMode === 'red' ){
                            eNode.material = null;
                            eNode.editMode='none'
                        }
                        if(eNode.editMode!="none"){
                            displayMeshAxis(eNode, false)
                        } else {
                            displayMeshAxis(eNode, true)
                            var remove = selectedEditNodes.indexOf(eNode)
                            //selectedEditNodes.splice(remove,1)
                        }

                    }));

                }
            }

Happy to provide displayMeshAxis and the events that edit nodes if you'd like... 

Link to comment
Share on other sites

SPEED Study...

Thinking about a FrameGovernor... for Christmas.

Going to use it for ... rays. Not so good for animating movements (while it does slow things down, so tried it):

                var index = 0;
                var biFrameGovernor = 0;
                scene.registerBeforeRender(function () {
                    biFrameGovernor++;
                    if(!(biFrameGovernor % 2)){ //animate on even only.
                        zapbotMesh1.position = points[index];
                        index = (index == points.length-1)?0:index+1;
                    }
                });

Slowed it down ... and it does not approximate time well. :)

Which is where Interpolation is good.

Because it adds precise time....(ish).

My brain still does not get interpolateAllThingsMethod() could someone explain?

So ... necessity to use TWEEN. 

I like it. Can that not be taboo pls? Thx!

Anyway we will see if it even works...

 

 

Link to comment
Share on other sites

IT WORKED:

                /******************************RECURSIVE-TRACK-TWEEN****************************************/
                //    <!--TWEENJS-->
                //    <script src="../../../lib/tweenjs/Tween.js"></script>
                //    <script src="../../../lib/tweenjs/RequestAnimationFrame.js"></script>
                /**************************************-------------****************************************/

                /******************************RECURSIVE-TRACK-TWEEN****************************************/
                var trackIndex = 1;
                var pathTargetOrb = BABYLON.Mesh.CreateSphere("sphere", 14, 1, scene);
                pathTargetOrb.position= new BABYLON.Vector3(pathTargetOrb.position.x, pathTargetOrb.position.y, pathTargetOrb.position.z);
                var speedGovernor = 100;
                var recursiveTrackTween = function() { 
                    var targetPoint = points[trackIndex]
                    var currentPoint = { x:pathTargetOrb.position.x, y: pathTargetOrb.position.y, z:pathTargetOrb.position.z };
                    var pathTween = new TWEEN.Tween( currentPoint ).to( { x: targetPoint.x, y: targetPoint.y, z:targetPoint.z }, speedGovernor ).onUpdate( function() {
                        pathTargetOrb.position.x=this.x;
                        pathTargetOrb.position.z=this.z;
                        pathTargetOrb.position.y=this.y;
                    }).onComplete(function() {
                        trackIndex = (trackIndex < points.length-2) ? trackIndex+1 : 0; //loop the track.  3 magic number because extra nodes in infinity loop...
                        recursiveTrackTween();
                    });
                    pathTween.start();
                }
                recursiveTrackTween();
                /******************************RECURSIVE-TRACK-TWEEN****************************************/

This makes for a buttery smooth 60fps orbit around the infinity symbol points[] curve path... at any speed --> just adjust the speedGovernor! :)

aFalcon is terrible at playgrounds... sorry!

Link to comment
Share on other sites

Hi @Arte that code above ... the EditNodes function... is what I've been (also) working on for you. :)

There was a difference when applying to your playground...

Above is for editing a Curve, also converted from Ribbon, but has not been applied to MeshBuilder (yet)... :)

It is really fun (easy) to use... quad-state click-editor!

Tons of potential!

Sorry I seem to have problems with playgrounds. :blink:

L8r.

 

Link to comment
Share on other sites

Mr. G! @MarianG Yes I love playgrounds as well... 

Planning sprint of writing documentation with playground based tutorials.

 

CURRENT-EXAMPLES (eventually for playground & doc):

Fake-Physics of a character orbiting the Infinity Path (you helped with, thank you):

#1 PATH-ORIENTATION, then #2 ROLL.

PATH-ORIENTATION:

SOLUTION: lookAt next index vertex in the path...

            var pathTargetOrb;
            var recursiveTrackTween;
            var createInfinityLoops = function(){

                //track Gerono
                var points = [];

                for(var t = 0; t < 2 * Math.PI; t += Math.PI / 36) {
                    scale = 80 / ( 3 - Math.cos(2 * t));
                    points.push(new BABYLON.Vector3(scale * Math.cos(t), 0, scale * Math.sin(2 * t)/2));
                }

                points.push(points[0]);

                var trackG = BABYLON.MeshBuilder.CreateLines('trackG', {points: points}, scene); 
                trackG.position.y = -1.2;

                //track Bernoulli
                var points = [];
                var pathSubdivisions = 180;

                // for(var t = 0; t < 2 * Math.PI; t += Math.PI / 36) {
                for(var t = 0; t < 2 * Math.PI; t += Math.PI / pathSubdivisions) { //subdivisions! less is faster more jumpy, more is slower and smoother.
                    scale = 50 / ( 3 - Math.cos(2 * t));
                    points.push(new BABYLON.Vector3(scale * Math.cos(t), 3, scale * Math.sin(2 * t)/2));
                }

                points.push(points[0]);

                var track = BABYLON.MeshBuilder.CreateLines('track', {points: points}, scene);
                var abox = BABYLON.Mesh.CreateBox("box", 6.0, scene);

                //SHOW-VERTICES-ON-PATH-.
                // showEditNodes(points,{type:'box', size:0.25})

                /******************************RECURSIVE-TRACK-TWEEN****************************************/
                var trackIndex = 1;
                pathTargetOrb = BABYLON.Mesh.CreateSphere("sphere", 14, 1, scene);
                pathTargetOrb.position= new BABYLON.Vector3(pathTargetOrb.position.x, pathTargetOrb.position.y, pathTargetOrb.position.z);
                var speedGovernor = 10; //this needs to be balanced with path-subdivisions - to get a smooth and fast speed!
                recursiveTrackTween = function() { 
                    //ANIMATE-ZAPBOT-.
                    var zapTargetPoint = points[trackIndex]
                    var zapCurrentPoint = { x:abox.position.x, y: abox.position.y, z:abox.position.z };
                    var pathTween = new TWEEN.Tween( zapCurrentPoint ).to( { x: zapTargetPoint.x, y: zapTargetPoint.y, z:zapTargetPoint.z }, speedGovernor ).onUpdate( function() {
                        abox.position.x=this.x;
                        abox.position.z=this.z;
                    }).onComplete(function() {
                        trackIndex = (trackIndex < points.length-2) ? trackIndex+1 : 0; //loop the track.  2 magic number because extra nodes in infinity loop...
                        abox.lookAt(points[trackIndex+1]); //<--ORIENTATION: to PATH.
                        recursiveTrackTween();
                    });
                    pathTween.start();
                }
                /******************************RECURSIVE-TRACK-TWEEN****************************************/
            }

(playground eventual).

 

Also --> this includes a neat optimization for SPEED STUDY:

- 1) check out the first part named pathSubdivisions. It is how many vertices subdivide the entire symbol.

       This is important because: less is FASTER (but more jumpy around curve with on lookAt), and more subdivisions is SLOWER (and more smooth, turning corners)!

- 2) the speed then can be adjusted to match the smoothness with the speedGovernor.

 

#2 ROLL on curve (calculate angle among points...)

 

QUESTION: What is the best way to detect angle on 3 points?

RE-STATED: How to take 3 points from Infinity Path and detect if it is convex or concave?

<looking>

...

 

 

Link to comment
Share on other sites

#2 - How to Detect Convex and Concave on a Path?

UPDATE:  detecting angle was not enough because left angle was the same as right angle. Needed something different -> found this:

image.thumb.png.011ddc0e878117aaac37cde1cfc5618e.png 

Above is a clockwise test of the mathematical function.

It might work...

:)

 

Link to comment
Share on other sites

SUCCESS! It worked...

Detecting Motion Path Convex and Concave Curves and then adding ROLL rotation as the character Corners:

                /******************************RECURSIVE-MOTION-PATH-TWEEN****************************************/
                var trackIndex = 1;
                pathTargetOrb = BABYLON.Mesh.CreateSphere("sphere", 14, 1, scene);
                pathTargetOrb.position= new BABYLON.Vector3(pathTargetOrb.position.x, pathTargetOrb.position.y, pathTargetOrb.position.z);
                var speedGovernor = 10; //this needs to be balanced with path-subdivisions - to get a smooth and fast speed!
                recursiveTrackTween = function() { 
                    //ANIMATE-ZAPBOT-.
                    var zapTargetPoint = points[trackIndex]
                    var zapCurrentPoint = { x:zapbotMesh1.position.x, y: zapbotMesh1.position.y, z:zapbotMesh1.position.z };
                    var pathTween = new TWEEN.Tween( zapCurrentPoint ).to( { x: zapTargetPoint.x, y: zapTargetPoint.y, z:zapTargetPoint.z }, speedGovernor ).onUpdate( function() {
                        zapbotMesh1.position.x=this.x;
                        zapbotMesh1.position.z=this.z;
                    }).onComplete(function() {
                        trackIndex = (trackIndex < points.length-2) ? trackIndex+1 : 0; //loop the track.  2 magic number because extra nodes in infinity loop...
                        //ORIENTATION: to PATH.
                        zapbotMesh1.lookAt(points[trackIndex+1]); 
                        //ROLL: tilt cornering.
                        var tilt = convexConcave(points[trackIndex],points[trackIndex+1])
                        if(tilt < 3.14 && tilt > 3.130){ //Right turn.
                            zapbotMesh1.rotation.z = 0.1;
                        } else if (tilt < 3.130 && tilt > 2){ //Right turn.
                            zapbotMesh1.rotation.z = 0.2;
                        } else if (tilt > -3.14 && tilt < -3.130){ //Left turn.
                            zapbotMesh1.rotation.z = -0.1;
                        } else if (tilt > -3.130 && tilt < -2){ //Left turn.
                            zapbotMesh1.rotation.z = -0.2;
                        } else {
                            zapbotMesh1.rotation.z = 0;
                        }
                        recursiveTrackTween();
                    });
                    pathTween.start();
                }
                /******************************RECURSIVE-MOTION-PATH-TWEEN****************************************/

                // convex > 0, concave < 0, backward = 0, fwd = -3.14
                function convexConcave (nextV, currentV) {
                    return ((Math.atan2(nextV.x, nextV.z) - Math.atan2(currentV.x, currentV.z) + Math.PI * 2) % (Math.PI * 2)) - Math.PI;
                }

The convexConcave method detects which way the character is turning, and applies (gradual) ROLL rotation.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...