Javascript structure -> GL Line Structure -- what's going wrong?

pgio's picture

I've got this JavaScript patch wired directly to a GL Line Structure patch. I'm trying to create a simple 0-crossing torus knot (with a lot of turns). Do I have any right to expect some kind of output from this?

I've tried replacing the new Object reference in the main for loop with an Array but it doesn't seem to make any difference. I've checked toneburst's posts on the subject (thanks toneburst, there's probably some of your code down below) but I can't seem to construct the Structure correctly. Any input would be appreciated.

function (__structure Helix) main ()
{
   var result = new Object();
   result.Lines = new Array();
 
   for(i=0;i<Math.PI*2000;i++)
   {
   qt=19206*(i/1000)
     theta = i/1000;
     r = 6.3 + 4.5*Math.cos(qt);
     z = 4.5*Math.sin(qt);
     x = Math.cos(theta) * r;
     y = Math.sin(theta) * r;
     j=i*1000;
     result.Lines[j] = new Object();
        result.Lines[j].X = x;
        result.Lines[j].Y = y;
        result.Lines[j].Z = z;
   }
 
   return result;
}

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

cwright's picture
Re: Javascript structure -> GL Line Structure -- what's ...

pgio wrote:
Do I have any right to expect some kind of output from this?

No, you have no right. Your output structure is called Helix, yet you're doing all your assignments to result.Lines (not result.Helix).

Once you change Helix to Lines, or Lines to Helix (doesn't matter which), you'll be in business...

... except, structures aren't designed to handle that much data -- you'll be waiting all day for it to to finish, and render speed will suck.

pgio's picture
Re: Javascript structure -> GL Line Structure -- what's ...

Ain't no right cuz I got it wrong! Thanks cwright. Fixed (and scaled) the code actually works surprisingly well for the amount of detail being calculated. This is a port of a Processing sketch, and I've managed to get multiple torus knots to draw faster in Processing by storing them in precalculated arrays. Doesn't look like I can do that in QC. Attached a snap of four of them (two larger ones and two regular ones.)

PreviewAttachmentSize
Picture 3.png
Picture 3.png85.2 KB

toneburst's picture
Re: Javascript structure -> GL Line Structure -- what's ...

If you're going for solid 3D shapes, you'd probably be better using a GLSL vertex-displacement shader on a sphere mesh.

Just a thought.

a|x http://machinesdontcare.wordpress.com

pgio's picture
Re: Javascript structure -> GL Line Structure -- what's ...

Thanks for the thought. This is actually an obscure model of the shape of an electron as a looped string. GLSL vertex-shaders are beyond me for the moment, so I thought this parametric approach was the best. You make cool stuff BTW!

cwright's picture
Re: Javascript structure -> GL Line Structure -- what's ...

pgio wrote:
Doesn't look like I can do that in QC. Attached a snap of four of them (two larger ones and two regular ones.)

You can do arrays in QC (just use [0], [1], and [2] instead of .X, .Y, and .Z), but they're still pretty slow -- lots of unnecessary overhead presently. I'm guessing this'll be much better in future versions of QC though ;)

Here's the code I used:

var result = new Object();
result.Lines = new Array();
 
function (__structure Lines) main ()
{
   var i = 0;
   for(i=0;i<Math.PI*2000;i++)
   {
      theta = i/1000;
      qt=19206*theta;
      r = 6.3 + 4.5*Math.cos(qt);
      z = 4.5*Math.sin(qt);
      x = Math.cos(theta) * r;
      y = Math.sin(theta) * r;
      result.Lines[i] = new Array();
      result.Lines[i][0] = x*0.1;
      result.Lines[i][1] = y*0.1;
      result.Lines[i][2] = z*0.1;
   }
   return result;
}

This draws the same thing, but it's a bit snappier.

toneburst's picture
Re: Javascript structure -> GL Line Structure -- what's ...

pgio wrote:
You make cool stuff BTW!

Thanks!

a|x

gtoledo3's picture
Re: Javascript structure -> GL Line Structure -- what's ...

I have a question...

I've seen some people's javascripts that don't use Math.PI, but will write out "3.14159265358979323846".

Is that for any particular advantage? It seems pointless, no?

cwright's picture
Re: Javascript structure -> GL Line Structure -- what's ...

It depends on the JS interpreter -- theoretically, "3.1515926535897..." will be flagged as a constant value, and will always be inline. It's possible that a crappy JS interpreter will actually query the Math object for its PI value, which could have a bit more overhead.

But stepping out of that for a second, if you're optimizing javascript to that extent, you really need to use a better language ;) I don't know for certain, but I think the computational cost of both is equal in WebKit.

cwright's picture
Re: Javascript structure -> GL Line Structure -- what's ...

cwright wrote:
It depends on the JS interpreter -- theoretically, "3.1515926535897..." will be flagged as a constant value, and will always be inline. It's possible that a crappy JS interpreter will actually query the Math object for its PI value, which could have a bit more overhead.

So, it looks like I'll have to eat my hat here: I made a quick little profiling script to see which was faster. Looks like 3.1415926... beats Math.PI by a tiny margin.

Here's the script -- I'd be interested to know what other people get (it'll take about 10 seconds to run, so QC will be unresponsive during that time).

var result = new Object();
function (__string outputNumber) main (__number inputNumber[2])
{
   var blah = 0;
   then1 = new Date();
   for(i=0;i<2000000;++i)
      blah += Math.PI * inputNumber[1];
   then2 = new Date();
   for(i=0;i<2000000;++i)
      blah += 3.141592653587 * inputNumber[2];
   then3 = new Date();
   base = then1.getHours()*60*60000 + then1.getMinutes()*60000 + then1.getSeconds()*1000 + then1.getMilliseconds();
   first = then2.getHours()*60*60000 + then2.getMinutes()*60000 + then2.getSeconds()*1000 + then2.getMilliseconds();
   second = then3.getHours()*60*60000 + then3.getMinutes()*60000 + then3.getSeconds()*1000 + then3.getMilliseconds();
   result.outputNumber = "base timestamp:" + base + "\nFirst:" + (first-base) + "\nSecond:" + (second-first);
   return result;
}

For me, First: is 3493 (3.493 seconds), while Second: is 3332 (3.332 seconds). I'm in the middle of a large backup though, so that may skew the results.

pgio's picture
Re: Javascript structure -> GL Line Structure -- what's ...

Thanks. I adopted the Array suggestion (and substituted the multiplication for division, and upped the detail a lot from my first post.) What I actually meant though was writing all the values to an array (like the current code does to a __structure) but then using that array to draw multiple copies without recalculating. As it is I need a JavaScript object for every torus knot I want to draw, right?

yanomano's picture
Re: Javascript structure -> GL Line Structure -- what's ...

first : 3059 Second: 2213 outch ;)

cybero's picture
Re: Javascript structure -> GL Line Structure -- what's ...

First 2026

Second 1921

gtoledo3's picture
Re: Javascript structure -> GL Line Structure -- what's ...

Cool then.... I've been using non-PI, just out of my mental abstraction of what must be going on, but totally without having tested timing. My thought was "well, every time it sees "math:PI" something has to go looking for what that value actually is (wearing my non-technical hat). Lucked out!

3350 -1st

2962 -2nd

cybero's picture
Re: Javascript structure -> GL Line Structure -- what's ...

made it tough for the numeric PI :-) ~ - set it to 3.141592653589793

First came 2123 Second 2022

cybero's picture
Re: Javascript structure -> GL Line Structure -- what's ...

My, I must be having a good night train thing going because I did think of switching the running order on the script from

blah += Math.PI * inputNumber[1];
    then2 = new Date();
    for(i=0;i<2000000;++i)
        blah += 3.141592653587 * inputNumber[2];

to

for(i=0;i<2000000;++i)
        blah += 3.141592653589793 * inputNumber[1];
    then2 = new Date();
    for(i=0;i<2000000;++i)
        blah += Math.PI * inputNumber[2];

so the numeric declaration of PI - long form no less - is processed first.

the results are

First - 2182

Second - 2089

Must be just a structural / performance 'feature' of the JavaScript interpreter ~

gtoledo3's picture
Re: Javascript structure -> GL Line Structure -- what's ...

What happens if you run it a few times?

One time out of the 12 I tested I got the 2nd to go slower (with the first example), but I was also shaking the editor window with my mouse. I did note that each run wasn't the same and some had greater discrepancy than others.

gtoledo3's picture
Re: Javascript structure -> GL Line Structure -- what's ...

...and FOR the record.

When I put in "cool" variable, it is WAY more awesome than "blah" variable. 9 times out of 10. I'm pretty sure it helps things run faster too.

cybero's picture
Re: Javascript structure -> GL Line Structure -- what's ...

A Tortoise & the Hare situation on the algorithmic front :-)

I did get one instance of the first being fastest, when I reopened the test script composition.

cybero's picture
Re: Javascript structure -> GL Line Structure -- what's ...

& when I set the code to run both as multiples of 3.141592653587 or both as multiples of Math.PI - First is slightly slower than Second to come to a result.

cwright's picture
Re: Javascript structure -> GL Line Structure -- what's ...

You could generate one, and then use the scale patch (from GLTools) + 3D Transform (built-in patch) to position/resize tori however you'd like. I don't know if it would benefit speed much, but it would definitely use less memory. :/

cwright's picture
Re: Javascript structure -> GL Line Structure -- what's ...

Interesting -- perhaps it's the optimizer getting better with time -- in that case, what happens if there are 3 or more loops?

cwright's picture
Re: Javascript structure -> GL Line Structure -- what's ...

gtoledo3 wrote:
When I put in "cool" variable, it is WAY more awesome than "blah" variable.

This one time, I used "awesome" as a variable name. It made everyone who saw the composition go blind from overexposure to pure awesomeness. ;)

pgio's picture
Re: Javascript structure -> GL Line Structure -- what's ...

Yeah, I figured out later just to publish the Lines input on the GL Line Structure to its parent 3D Transformation, copy that, and put the JavaScript patch up at that level. Now I've got as many torii as I want.

gtoledo3's picture
Re: Javascript structure -> GL Line Structure -- what's ...

Wow.

Ok. My mind literally skipped a brainwave on that. Awesome as a variable name? I don't even think that's legal in every state.

If it read like an unedited/tidied up email of mine it would look like

"var really awesome = really 0 really1 = really really new Date..."

Really.

So, no one ever hack into my email and use "really" as a search term, b/c it's going to pull up every email I've ever written.

Eh, I feel like bad drive topic OT man.

gtoledo3's picture
Re: Javascript structure -> GL Line Structure -- what's ...

This is the fascinating stuff to me. Really.

Anyways, I'm not even kidding. These quirks of QC are the things that I love it when they come to light. I'm interested to set up a further test now.

The whole Math.PI vs numeric is one thing that I've thought about way too much without having done a simple test like this.

I have a feeling that feeding different values of different decimal length might also change factors, but I will reserve that judgement for when I have solid info. I did note that patching in patch time or the same random to both inputs seemed to make the difference between timing less on average (geez, I'm basing this on 10 or so go arounds, which isn't that scientific).

Now, what I want to see is what Math.PI puts out, decimal length wise, or if it shifts back and forth in length or what.

offonoll's picture
Re: Javascript structure -> GL Line Structure -- what's ...

It's been a while already but here are my numbers:

First: 1690

Second: 1566

seeing the other people's numbers and realising that I am using SL, it's been improving the process speed. Nice!