Fractal Orbit

  • 58 Replies
  • 26852 Views
*

ivan.moony

  • Trusty Member
  • ************
  • Bishop
  • *
  • 1722
    • mind-child
Re: Fractal Orbit
« Reply #30 on: July 28, 2018, 11:55:01 am »
Here is a source code for static part of the project. It renders the orbit inside browser. I didn't catch a time to finish dynamic rotation stuff, but if anyone wants to build up upon the static part, they are very welcome.

orbital.html:
Code
<!DOCTYPE html>
<!--?xml version="1.0"?-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Orbital</title>
    <style type="text/css" media="screen">
        html, body, div, svg
        {
          overflow: hidden;
          height: 100%;
          width: 100%;
          margin-top:0px;
          margin-left:0px;
    }
    </style>
    <body>
        <div id="intro">
        <svg><!-- viewBox="0 0 400 400" transform='scale(1, 1)'-->
        </svg>
        </div>
        <script src="orbital.js"></script>
        <script>
            orbital(document.getElementsByTagName('svg')[0]);
        </script>
    </body>
</html>

orbital.js:
Code
function orbital (svg) {
    "use strict";

    var ratio = 0.5;//575;
    var minRadius = 0.5;
    var branchCount = 42;
    var pixelPrecision = 1 / 32;
    var fill1 = "rgb(255, 255, 150)";//"lightgray";
    var stroke1 = "gray";
    var fill2 = stroke1;
    var stroke2 = fill1;
    var svgns = "http://www.w3.org/2000/svg";

    function insertGroup () {
        var g;
        g = document.createElementNS(svgns, "g");
        g.setAttribute('id', 'group');
        g.setAttribute('shape-rendering', 'inherit');
        g.setAttribute('pointer-events', 'all');
        return g;
    }
   
    function insertCircle (x, y, r, fill, stroke) {
        var el = document.createElementNS(svgns, 'ellipse');
        el.setAttribute('cx', x * squashX);
        el.setAttribute('cy', y * squashY);
        el.setAttribute('rx', r * squashX);
        el.setAttribute('ry', r * squashY);
        el.setAttribute('fill', fill);
        el.setAttribute('stroke-width',  1);
        el.setAttribute('stroke', stroke);
        return el;
    }
   
    function insertRect (x, y, width, height, fill, stroke) {
        var rect = document.createElementNS(svgns, 'rect');
        rect.setAttribute('x', x);
        rect.setAttribute('y', y);
        rect.setAttribute('height', height);
        rect.setAttribute('width', width);
        rect.setAttribute('fill', fill);
        rect.setAttribute('stroke-width',  1);
        rect.setAttribute('stroke', stroke);
        return rect;
    }
   
    function node() {
        var children = (function () {
            return {
               alphaOffset: Math.PI,
               itemOffset: 0,
               items: (function (itemCount) {
                    var i, items;
                   
                    items = [];
                    for (i = 0; i < itemCount; i++)
                        items.push (i);
                   
                    return items;
               })(branchCount),
               
               getX: function (index) {
                   return (rLarge + rSmall) * Math.cos (-Math.PI / 2 - index * alpha);
               },

               getY: function (index) {
                   return (rLarge + rSmall) * Math.sin (-Math.PI / 2 - index * alpha);
               }
           };
        })();
           
        var render = function (minRadius, x1, y1, r1, alpha0, rec) {
            function getCircle (alpha) {
                var beta = alpha0 + alpha - Math.PI / 2;
               
                var ra = 0;
                var xa = x0 + r0 * Math.cos (beta);
                var ya = y0 + r0 * Math.sin (beta);
               
                var rb = 2 * r1;
                var xb = x0 + (r0 + rb) * Math.cos (beta);
                var yb = y0 + (r0 + rb) * Math.sin (beta);

                var dr = (rb - ra) / 2;
                var dx = (xb - xa) / 2;
                var dy = (yb - ya) / 2;
               
                ra += dr;
                xa += dx;
                ya += dy;

                var j;
                do {
                    dx /= 2;
                    dy /= 2;
                    dr /= 2;
                    var d = Math.sqrt (Math.pow ((xa - x1), 2) + Math.pow ((ya - y1), 2));
                    if (Math.abs (ra - r1) <= d) {
                        xa -= dx;
                        ya -= dy;
                        ra -= dr;
                    } else {
                        xa += dx;
                        ya += dy;
                        ra += dr;
                    }
                } while (dr > pixelPrecision);

                return {
                    x: (r0 + ra) * Math.cos (beta),
                    y: (r0 + ra) * Math.sin (beta),
                    r: ra,
                    alpha: alpha
                };
            }
           
            function getNeighbor (c1) {
                var alpha = c1.alpha / 2;
                var dalpha = alpha;
                var j;
                var datmp = 2 * Math.pow (2 * r1, 2);
                var da = Math.acos ((datmp - Math.pow (pixelPrecision, 2)) / datmp);
                do {
                    var c2 = getCircle (alpha);
                    dalpha /= 2;
                    var d = Math.sqrt (Math.pow ((c1.x - c2.x), 2) + Math.pow ((c1.y - c2.y), 2));
                    if ((c1.r + c2.r) >= d) {
                        alpha -= dalpha;
                    } else {
                        alpha += dalpha;
                    }
                } while (dalpha > da);

                return c2;
            }

            var r0 = r1 * ratio;
            var x0 = x1 + (r1 - r0) * Math.cos (alpha0 - Math.PI / 2);
            var y0 = y1 + (r1 - r0) * Math.sin (alpha0 - Math.PI / 2);

            if (r0 > minRadius) {
                var g = svg;
                g.appendChild (insertCircle (x0, y0, r0, fill1, stroke1));

                var i;
                var alpha = 4 * Math.PI / 2 - 0.3941;
   
                var c1 = getCircle (alpha);
                for (i = 0; i < branchCount; i++) {
                    if (c1.r > minRadius)
                        render (minRadius, x0 + c1.x, y0 + c1.y, c1.r, alpha0 + alpha - Math.PI, rec);
                   
                    c1 = getNeighbor (c1);
                    alpha = c1.alpha;
                }
            }
        };
       
        return {
            children: children,
            render: render
        };
    }
   
    var ww = window.innerWidth;
    var hh = window.innerHeight;
    var rr, squashX, squashY;
   
    if (ww > hh) {
        rr = hh / 2;
        squashX = ww / hh;
        squashY = 1;
       
    } else {
        rr = ww / 2;
        squashX = 1;
        squashY = hh / ww;
       
    }

    var r1 = rr;
    var x1 = ww / squashX - rr;
    var y1 = hh / squashY - rr;

    var n = node();

    var i = 8;
    var repeat = function () {
        if (i >= minRadius) {
            var s = svg.cloneNode(false);
            svg.parentNode.replaceChild(s, svg);
            svg = s;
            svg.appendChild(insertRect (0, 0, ww, hh, fill2, stroke2));
            n.render (i, x1, y1, r1, 0, 1);
            setTimeout (repeat, 0);
        }
        i/=2;
    };
    repeat();
}
« Last Edit: July 28, 2018, 06:33:25 pm by ivan.moony »

*

ivan.moony

  • Trusty Member
  • ************
  • Bishop
  • *
  • 1722
    • mind-child
Re: Fractal Orbit
« Reply #31 on: October 08, 2018, 05:48:02 pm »
Just added some dynamics. The project is now on Github, but it's still in highly experimental stage. You can test it here, though you'll need some electro-muscle to run it in a browser. Click around and drag around. Please report bugs if stumbled upon.
« Last Edit: October 08, 2018, 08:14:05 pm by ivan.moony »

*

ivan.moony

  • Trusty Member
  • ************
  • Bishop
  • *
  • 1722
    • mind-child
Re: Fractal Orbit
« Reply #32 on: July 03, 2019, 12:54:26 pm »
In the last three days (and a change) I worked out a bit the interaction with fractal orbit. I eliminated clicking and implemented navigation using only mouse dragging. Maybe it's an overkill to drag items to and from the third level and deeper, so it might be a good idea to restrict the interaction just to first and second level items, but I'm still not sure about this.

Anyway, you can test the new version here. Maybe you'll like it. If not, I'm open for suggestions, of course.

*

Zero

  • Eve
  • ***********
  • 1287
Re: Fractal Orbit
« Reply #33 on: July 03, 2019, 01:02:34 pm »
I like it, well done!

I suggest adding mousewheel support :)

*

Freddy

  • Administrator
  • **********************
  • Colossus
  • *
  • 6855
  • Mostly Harmless
Re: Fractal Orbit
« Reply #34 on: July 03, 2019, 01:06:25 pm »
Nice  8)

*

ivan.moony

  • Trusty Member
  • ************
  • Bishop
  • *
  • 1722
    • mind-child
Re: Fractal Orbit
« Reply #35 on: July 04, 2019, 04:30:04 pm »
I suggest adding mousewheel support :)

Maybe, I'm not sure... Something is going to be hosted inside those circles, and maybe that something should accept mouse wheel events. Maybe it should depend on the content, leaving the wheel rotating option on explicit demand when populating the UI.

*

ivan.moony

  • Trusty Member
  • ************
  • Bishop
  • *
  • 1722
    • mind-child
Re: Fractal Orbit
« Reply #36 on: July 09, 2019, 07:58:00 pm »
just thinking at loud...

*

ivan.moony

  • Trusty Member
  • ************
  • Bishop
  • *
  • 1722
    • mind-child
Re: Fractal Orbit
« Reply #37 on: September 12, 2019, 11:09:38 am »
Ever been wondering how good the Javascript internal optimization can be?

I've been playing with fish eye effect to eliminate the need for scrollbars in visualizing image panes.

Fish eye pattern is precalculated to map on pixels of actual image. Each pixel magnification is also stored in fish eye map. The further the pixel is from center, the more pixels it covers on original bitmap.

The actual bitmap is halfed with antialiasing. Then it's halfed again. And again... until it's one pixel width and height. These maps are alo cached in advance.

Then, when rendering fish eye, regarding the pixel magnification, the correct halfed bitmap is referred. This way it should be guaranteed not to lose a single pixel when rendering on screen.

I wasn't counting on Javascript speed, I thought it would be necessary to go Asm.js or Webassembly, but it turned out that pure Javascript may be fast enough.

Test it here. Drag ovals around to navigate the tree, or drag the topmost oval pane to scroll the content. Note that it is pure HTML + Javascript, no Webassembly, no Asm.js. The bitmap size is 3000 × 3000 pixels.

Can I ask a question if anyone cares? Does anyone have a tablet around here? I'd like to hear how fast the orbit performs on those devices. On my Intel Celeron it is sometimes at snappy pace, but bearable in average. Anyway, this is the worst case scenario, to have an infinite amount of ovals. I suppose, in a real use, the visible oval amount would be halfed.
« Last Edit: September 12, 2019, 11:39:29 am by ivan.moony »

*

Korrelan

  • Trusty Member
  • ***********
  • Eve
  • *
  • 1454
  • Look into my eyes! WOAH!
    • YouTube
Re: Fractal Orbit
« Reply #38 on: September 12, 2019, 05:09:41 pm »
Celeron? WTF... Cool.

Its all looking very cool, have you considered an application? Perhaps a demo using a file directory structure?

 :)
It thunk... therefore it is!...    /    Project Page    /    KorrTecx Website

*

ivan.moony

  • Trusty Member
  • ************
  • Bishop
  • *
  • 1722
    • mind-child
Re: Fractal Orbit
« Reply #39 on: September 12, 2019, 06:27:09 pm »
I like slow computers to be forced to optimize things when programming. Therefore, Celeron.

Application would be personal knowledge base for a start (maybe even content management system, but it's a drifting away from the original idea). Then I plan to mix in a theorem prover. And at last, online interface for uploading formal knowledge content, unifying scientific fields in my case.

I tested it on Firefox and it's cool. But I just tested it on Chromium too, and it's sluggish. I have to optimize it for that platform too. It is about freshly introduced `getImageData` function into browsers. I have to think about how to avoid it.
« Last Edit: September 12, 2019, 11:11:30 pm by ivan.moony »

*

ivan.moony

  • Trusty Member
  • ************
  • Bishop
  • *
  • 1722
    • mind-child
Re: Fractal Orbit
« Reply #40 on: September 12, 2019, 11:08:56 pm »
Ok, I did some changes to speed up appearance on Chromium. I replaced `getImageData` with `createImageData` where I could, and things got a bit nearer to Firefox. But even Celeron + Linux 64bit + Firefox is still faster than i3 + Windows7 32bit + Chromium. I guess that intensive array access is better handled in Firefox. This is the power of optimization I'm talking about. The slower the computer is, the more I care about clean and fast code. But I'm still impressed for overall speed of Javascript, even on Chromium. Good job, browser developer guys.

During the search for a faster method I accidentally improved the rendering algorithm a bit and now orbiting animation appearance looks a bit cleaner than initially. The link for testing is the same.
« Last Edit: September 12, 2019, 11:35:57 pm by ivan.moony »

*

ivan.moony

  • Trusty Member
  • ************
  • Bishop
  • *
  • 1722
    • mind-child
Re: Fractal Orbit
« Reply #41 on: September 13, 2019, 03:54:39 pm »
After the last touch... these are the moments worth of all the trouble... now it's faster in Chromium than in Firefox, and in Firefox it is a bit faster than before.  :weee:

I'm telling you, things would work out even on ten times slower computers. Just, after some point, it makes no sense to optimize it any further because computers are really fast today.

The link is the same.

*

Korrelan

  • Trusty Member
  • ***********
  • Eve
  • *
  • 1454
  • Look into my eyes! WOAH!
    • YouTube
Re: Fractal Orbit
« Reply #42 on: September 13, 2019, 04:44:53 pm »
Might just be my setup but it seems to be slower, and I can't rotate at all, lol.

It's also allocating 450MB of RAM in the chrome browser... ouch!

Some point of reference would be cool, either a node number or perhaps colour the nodes.

 :)

ED.. Ignore me it's working, I wasn't scribing the correct path, there is a delay before the node highlighting and the rotation begins though lol.

 ;D
It thunk... therefore it is!...    /    Project Page    /    KorrTecx Website

*

ivan.moony

  • Trusty Member
  • ************
  • Bishop
  • *
  • 1722
    • mind-child
Re: Fractal Orbit
« Reply #43 on: September 13, 2019, 08:18:06 pm »
Korr, thanks for the valuable feedback.

Memory allocating on Chromium takes about 300KB in my case. On Firefox it is about 1MB in the cloud, and about 120MB when running from local disk. I can't explain this.

But this delay was a bug. Algorithm renders whole screen with high quality on mouse move, and mouse has to pass 3 pixels with mouse button before detecting a rotation. So there was a few (at most three) slow extra high-quality frame renders before stepping into fast low-quality rotation, which caused the delay. I believe this should be fixed now. If not, please tell.

The link is the same.

*

Freddy

  • Administrator
  • **********************
  • Colossus
  • *
  • 6855
  • Mostly Harmless
Re: Fractal Orbit
« Reply #44 on: September 13, 2019, 08:38:09 pm »
It's working very smoothly here in Chrome for me :)

 


Say good-bye to GPUs...
by MikeB (AI News )
March 23, 2024, 09:23:52 am
OpenAI Speech-to-Speech Reasoning Demo
by MikeB (AI News )
March 15, 2024, 08:14:02 am
Google Bard report
by ivan.moony (AI News )
February 14, 2024, 04:42:23 pm
Elon Musk's xAI Grok Chatbot
by MikeB (AI News )
December 11, 2023, 06:26:33 am
Nvidia Hype
by 8pla.net (AI News )
December 06, 2023, 10:04:52 pm
How will the OpenAI CEO being Fired affect ChatGPT?
by 8pla.net (AI News )
December 06, 2023, 09:54:25 pm
Independent AI sovereignties
by WriterOfMinds (AI News )
November 08, 2023, 04:51:21 am
LLaMA2 Meta's chatbot released
by 8pla.net (AI News )
October 18, 2023, 11:41:21 pm

Users Online

276 Guests, 0 Users

Most Online Today: 335. Most Online Ever: 2369 (November 21, 2020, 04:08:13 pm)

Articles