Tinkercad > Shape Generator > biSphere_180306 > v0.1, v0.2, v0.3, v0.4 > [半径]と[Distance]を持つ2球の形状

ブラウザ動作するAutoDeskのTinkercad。

Shape Generatorが気になる今日のこのごろ.

### biSphere_180306 @ Shape Generator

```main.js
// Convenience Declarations For Dependencies.
// 'Core' Is Configured In Libraries Section.
// Some of these may not be used by this example.
var Conversions = Core.Conversions;
var Debug = Core.Debug;
var Path2D = Core.Path2D;
var Point2D = Core.Point2D;
var Point3D = Core.Point3D;
var Matrix2D = Core.Matrix2D;
var Matrix3D = Core.Matrix3D;
var Mesh3D = Core.Mesh3D;
var Plugin = Core.Plugin;
var Tess = Core.Tess;
var Sketch2D = Core.Sketch2D;
var Solid = Core.Solid;
var Vector2D = Core.Vector2D;
var Vector3D = Core.Vector3D;

//
// v0.2 Mar. 06, 2018
//   - mesh.triangle() uses [vrt1], [vrt2], [vrt3]
// v0.1 Mar. 06, 2018
//   - branched from [Shape Generator] > [Sphere]

// Template Code:
params = [
    { "id": "r", "displayName": "Radius", "type": "length", "rangeMin": 1.0, "rangeMax": 100.0, "default": 10.0 }
];

function process(params) {
    var r = params["r"];
    var ndivs = Tess.circleDivisions(r);
    var tau = 0.8506508084;
    var one = 0.5257311121;
    var lod = 0;

    while(ndivs > 6){
        lod++;
        ndivs /= 2;
    }

    Debug.log(Tess.circleDivisions(r) + " " + lod);

    var v = [
        [ tau, one, 0.0 ],
        [-tau, one, 0.0 ],
        [-tau,-one, 0.0 ],
        [ tau,-one, 0.0 ],
        [ one, 0.0, tau ],
        [ one, 0.0,-tau ],
        [-one, 0.0,-tau ],
        [-one, 0.0, tau ],
        [ 0.0, tau, one ],
        [ 0.0,-tau, one ],
        [ 0.0,-tau,-one ],
        [ 0.0, tau,-one ]
    ];
    
    var tris = [
        [ v[4], v[8], v[7] ],
        [ v[4], v[7], v[9] ],
        [ v[5], v[6],v[11] ],
        [ v[5],v[10], v[6] ],
        [ v[0], v[4], v[3] ],
        [ v[0], v[3], v[5] ],
        [ v[2], v[7], v[1] ],
        [ v[2], v[1], v[6] ],
        [ v[8], v[0],v[11] ],
        [ v[8],v[11], v[1] ],
        [ v[9],v[10], v[3] ],
        [ v[9], v[2],v[10] ],
        [ v[8], v[4], v[0] ],
        [v[11], v[0], v[5] ],
        [ v[4], v[9], v[3] ],
        [ v[5], v[3],v[10] ],
        [ v[7], v[8], v[1] ],
        [ v[6], v[1],v[11] ], 
        [ v[7], v[2], v[9] ],
        [ v[6],v[10], v[2] ]
    ];
    
    function norm(a) {
        var l = Math.sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
        return [ a[0]/l, a[1]/l, a[2]/l ];
    }

    function sum(a, b) {
        return [ (a[0]+b[0]), (a[1]+b[1]), (a[2]+b[2]) ];
    }

    function xf(a, s) {
        return [ a[0]*s, a[1]*s, a[2]*s + s ];
    }
    
    for (var i = 0; i < lod; i++) {
        var ntris = [];
        for(var j = 0; j < tris.length; j++) {
            var ma = norm(sum(tris[j][0], tris[j][1]));
            var mb = norm(sum(tris[j][1], tris[j][2]));
            var mc = norm(sum(tris[j][2], tris[j][0]));
 
            ntris.push([tris[j][0], ma, mc]);
            ntris.push([tris[j][1], mb, ma]);
            ntris.push([tris[j][2], mc, mb]);
            ntris.push([ma, mb, mc]);
        }
        tris = ntris;
    }

    var mesh = new Mesh3D();
    for (var oi = 0; oi < 2; oi++) { // oi: outer index
        for (var i = 0; i < tris.length; i++) {
            var vrt1 = tris[i][0];
            var vrt2 = tris[i][1];
            var vrt3 = tris[i][2];
            var xf1 = xf(vrt1,r);
            var xf2 = xf(vrt2,r);
            var xf3 = xf(vrt3,r);
            if (oi == 0) {
                xf1[1] += 2 * r;
                xf2[1] += 2 * r;
                xf3[1] += 2 * r;
            }
            mesh.triangle(xf1, xf2, xf3);
        }
    }
 
    var solid = Solid.make(mesh);

    return solid;
}
```

### Public デザイン @ Tinkercad

以下のPublicデザインで閲覧可能。
https://www.tinkercad.com/things/atujtMwlN3R-bisphere180306

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b3942743-9bcf-2f1a-8594-4f33032e2b65.png)


### 備考

N=1024のBallistic cluster-cluster aggregateなどにする場合、1つの球の分解能は粗い方がいいだろう。

パラメータで距離を定義するか。


### code v0.3

- パラメータ: Distanceを追加

```main.js
// Convenience Declarations For Dependencies.
// 'Core' Is Configured In Libraries Section.
// Some of these may not be used by this example.
var Conversions = Core.Conversions;
var Debug = Core.Debug;
var Path2D = Core.Path2D;
var Point2D = Core.Point2D;
var Point3D = Core.Point3D;
var Matrix2D = Core.Matrix2D;
var Matrix3D = Core.Matrix3D;
var Mesh3D = Core.Mesh3D;
var Plugin = Core.Plugin;
var Tess = Core.Tess;
var Sketch2D = Core.Sketch2D;
var Solid = Core.Solid;
var Vector2D = Core.Vector2D;
var Vector3D = Core.Vector3D;

// v0.3 Mar. 06, 2018
//   - add parameter [dist]
// v0.2 Mar. 06, 2018
//   - mesh.triangle() uses [vrt1], [vrt2], [vrt3]
// v0.1 Mar. 06, 2018
//   - branched from [Shape Generator] > [Sphere]

// Template Code:
params = [
    { "id": "r", "displayName": "Radius", "type": "length", "rangeMin": 1.0, "rangeMax": 100.0, "default": 10.0 },
    { "id": "dist", "displayName": "Distance", "type": "length", "rangeMin": 1.0, "rangeMax": 500.0, "default": 20.0 }
];

function process(params) {
    var r = params["r"];
    var dist = params["dist"];
    var ndivs = Tess.circleDivisions(r);
    var tau = 0.8506508084;
    var one = 0.5257311121;
    var lod = 0;

    while(ndivs > 6){
        lod++;
        ndivs /= 2;
    }

    Debug.log(Tess.circleDivisions(r) + " " + lod);

    var v = [
        [ tau, one, 0.0 ],
        [-tau, one, 0.0 ],
        [-tau,-one, 0.0 ],
        [ tau,-one, 0.0 ],
        [ one, 0.0, tau ],
        [ one, 0.0,-tau ],
        [-one, 0.0,-tau ],
        [-one, 0.0, tau ],
        [ 0.0, tau, one ],
        [ 0.0,-tau, one ],
        [ 0.0,-tau,-one ],
        [ 0.0, tau,-one ]
    ];
    
    var tris = [
        [ v[4], v[8], v[7] ],
        [ v[4], v[7], v[9] ],
        [ v[5], v[6],v[11] ],
        [ v[5],v[10], v[6] ],
        [ v[0], v[4], v[3] ],
        [ v[0], v[3], v[5] ],
        [ v[2], v[7], v[1] ],
        [ v[2], v[1], v[6] ],
        [ v[8], v[0],v[11] ],
        [ v[8],v[11], v[1] ],
        [ v[9],v[10], v[3] ],
        [ v[9], v[2],v[10] ],
        [ v[8], v[4], v[0] ],
        [v[11], v[0], v[5] ],
        [ v[4], v[9], v[3] ],
        [ v[5], v[3],v[10] ],
        [ v[7], v[8], v[1] ],
        [ v[6], v[1],v[11] ], 
        [ v[7], v[2], v[9] ],
        [ v[6],v[10], v[2] ]
    ];
    
    function norm(a) {
        var l = Math.sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
        return [ a[0]/l, a[1]/l, a[2]/l ];
    }

    function sum(a, b) {
        return [ (a[0]+b[0]), (a[1]+b[1]), (a[2]+b[2]) ];
    }

    function xf(a, s) {
        return [ a[0]*s, a[1]*s, a[2]*s + s ];
    }
    
    for (var i = 0; i < lod; i++) {
        var ntris = [];
        for(var j = 0; j < tris.length; j++) {
            var ma = norm(sum(tris[j][0], tris[j][1]));
            var mb = norm(sum(tris[j][1], tris[j][2]));
            var mc = norm(sum(tris[j][2], tris[j][0]));
 
            ntris.push([tris[j][0], ma, mc]);
            ntris.push([tris[j][1], mb, ma]);
            ntris.push([tris[j][2], mc, mb]);
            ntris.push([ma, mb, mc]);
        }
        tris = ntris;
    }

    var mesh = new Mesh3D();
    for (var oi = 0; oi < 2; oi++) { // oi: outer index
        for (var i = 0; i < tris.length; i++) {
            var vrt1 = tris[i][0];
            var vrt2 = tris[i][1];
            var vrt3 = tris[i][2];
            var xf1 = xf(vrt1,r);
            var xf2 = xf(vrt2,r);
            var xf3 = xf(vrt3,r);
            if (oi == 0) {
                xf1[1] += dist;
                xf2[1] += dist;
                xf3[1] += dist;
            }
            mesh.triangle(xf1, xf2, xf3);
        }
    }
 
    var solid = Solid.make(mesh);

    return solid;
}
```

距離を変更できるようになった。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b41ca71c-9f91-2259-c76c-5310a689b054.png)


### code v0.4

- positions[]を追加
    - 半径=1.0となる定義
- 球の位置をpositionsで指定できる

```main.js
// Convenience Declarations For Dependencies.
// 'Core' Is Configured In Libraries Section.
// Some of these may not be used by this example.
var Conversions = Core.Conversions;
var Debug = Core.Debug;
var Path2D = Core.Path2D;
var Point2D = Core.Point2D;
var Point3D = Core.Point3D;
var Matrix2D = Core.Matrix2D;
var Matrix3D = Core.Matrix3D;
var Mesh3D = Core.Mesh3D;
var Plugin = Core.Plugin;
var Tess = Core.Tess;
var Sketch2D = Core.Sketch2D;
var Solid = Core.Solid;
var Vector2D = Core.Vector2D;
var Vector3D = Core.Vector3D;

// v0.4 Mar. 07, 2018
//   - add positions[] to locate each sphere
// v0.3 Mar. 06, 2018
//   - add parameter [dist]
// v0.2 Mar. 06, 2018
//   - mesh.triangle() uses [vrt1], [vrt2], [vrt3]
// v0.1 Mar. 06, 2018
//   - branched from [Shape Generator] > [Sphere]

// Template Code:
params = [
    { "id": "r", "displayName": "Radius", "type": "length", "rangeMin": 1.0, "rangeMax": 100.0, "default": 10.0 },
    { "id": "dist", "displayName": "Distance", "type": "length", "rangeMin": 1.0, "rangeMax": 500.0, "default": 20.0 }
];

function process(params) {
    var r = params["r"];
    var dist = params["dist"];
    var ndivs = Tess.circleDivisions(r);
    var tau = 0.8506508084;
    var one = 0.5257311121;
    var lod = 0;

    while(ndivs > 6){
        lod++;
        ndivs /= 2;
    }

    Debug.log(Tess.circleDivisions(r) + " " + lod);

    var v = [
        [ tau, one, 0.0 ],
        [-tau, one, 0.0 ],
        [-tau,-one, 0.0 ],
        [ tau,-one, 0.0 ],
        [ one, 0.0, tau ],
        [ one, 0.0,-tau ],
        [-one, 0.0,-tau ],
        [-one, 0.0, tau ],
        [ 0.0, tau, one ],
        [ 0.0,-tau, one ],
        [ 0.0,-tau,-one ],
        [ 0.0, tau,-one ]
    ];
    
    var tris = [
        [ v[4], v[8], v[7] ],
        [ v[4], v[7], v[9] ],
        [ v[5], v[6],v[11] ],
        [ v[5],v[10], v[6] ],
        [ v[0], v[4], v[3] ],
        [ v[0], v[3], v[5] ],
        [ v[2], v[7], v[1] ],
        [ v[2], v[1], v[6] ],
        [ v[8], v[0],v[11] ],
        [ v[8],v[11], v[1] ],
        [ v[9],v[10], v[3] ],
        [ v[9], v[2],v[10] ],
        [ v[8], v[4], v[0] ],
        [v[11], v[0], v[5] ],
        [ v[4], v[9], v[3] ],
        [ v[5], v[3],v[10] ],
        [ v[7], v[8], v[1] ],
        [ v[6], v[1],v[11] ], 
        [ v[7], v[2], v[9] ],
        [ v[6],v[10], v[2] ]
    ];
  
    // defined in radius unit
    //    for touching bisphere, set [2]
    var positions = [
      [0, 0, 0],
      [0, 2, 0]
    ];
    
    function norm(a) {
        var l = Math.sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
        return [ a[0]/l, a[1]/l, a[2]/l ];
    }

    function sum(a, b) {
        return [ (a[0]+b[0]), (a[1]+b[1]), (a[2]+b[2]) ];
    }

    function xf(a, s) {
        return [ a[0]*s, a[1]*s, a[2]*s + s ];
    }
    
    for (var i = 0; i < lod; i++) {
        var ntris = [];
        for(var j = 0; j < tris.length; j++) {
            var ma = norm(sum(tris[j][0], tris[j][1]));
            var mb = norm(sum(tris[j][1], tris[j][2]));
            var mc = norm(sum(tris[j][2], tris[j][0]));
 
            ntris.push([tris[j][0], ma, mc]);
            ntris.push([tris[j][1], mb, ma]);
            ntris.push([tris[j][2], mc, mb]);
            ntris.push([ma, mb, mc]);
        }
        tris = ntris;
    }

    var mesh = new Mesh3D();
    for (var oi = 0; oi < 2; oi++) { // oi: outer index
        for (var i = 0; i < tris.length; i++) {
            var vrt1 = tris[i][0];
            var vrt2 = tris[i][1];
            var vrt3 = tris[i][2];
            var xf1 = xf(vrt1,r);
            var xf2 = xf(vrt2,r);
            var xf3 = xf(vrt3,r);
            for (var pi = 0; pi < 3; pi++) { // pi: position index
                xf1[pi] += positions[oi][pi] * dist / 2; // 2: for positions is defined in radisu unit
                xf2[pi] += positions[oi][pi] * dist / 2;
                xf3[pi] += positions[oi][pi] * dist / 2;
            }
            mesh.triangle(xf1, xf2, xf3);
        }
    }
 
    var solid = Solid.make(mesh);

    return solid;
}
```