Fractal Orbit

  • 31 Replies
  • 7601 Views
*

ivan.moony

  • Trusty Member
  • **********
  • Millennium Man
  • *
  • 1204
    • Some of my projects
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: [Select]
<!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: [Select]
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 »
Dream big. The bigger the dream is, the more beautiful place the world becomes.

*

ivan.moony

  • Trusty Member
  • **********
  • Millennium Man
  • *
  • 1204
    • Some of my projects
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 »
Dream big. The bigger the dream is, the more beautiful place the world becomes.

 


Users Online

25 Guests, 0 Users

Most Online Today: 41. Most Online Ever: 340 (March 26, 2019, 09:47:57 pm)

Articles