Published
Edited
May 18, 2019
Importers
Insert cell
Insert cell
Insert cell
Insert cell
getDefaultShape = {
//
// Strut prism, seen from one end (ntl,ntr,nbr,nbl), the far side of the nearer ball.
// This is the even parity orientation.
//
// ntl-----------ntr
// |\ A /|
// | \ / |
// | ftl---ftr |
// |D | | B|
// | | | |
// | fbl---fbr |
// | / \ |
// |/ C \|
// nbl-----------nbr
//
const ftl = 0
const ftr = 1
const fbl = 2
const fbr = 3
const ntl = 4
const ntr = 5
const nbl = 6
const nbr = 7

const polygons = [
[ ntl, ntr, ftr, ftl ], // A
[ ftr, ntr, nbr, fbr ], // B
[ fbl, fbr, nbr, nbl ], // C
[ ntl, ftl, fbl, nbl ], // D
[ ftl, ftr, fbr, fbl ], // far cap
[ ntl, nbl, nbr, ntr ], // near cap
]
const tip = [ ntl, ntr, nbl, nbr ]
const x = 1.0

return function getDefaultShape( orbit, scale=[1,,10] )
{
const prototype = [[1,0,1]] .concat( orbit )
const eight = grmul( [8], scale )
const five = grmul( [5], scale )
const four = grmul( [4], scale )

const [y,z] = orbit .map( grfloat )

var yellow = [ four, four, four ]
// find the corner of the octant
var first, second, third
var firstNeg, secondNeg, thirdNeg
var blue, green
var swapParity = false
// TODO: clean this up; not all these cases are possible, since
// the orbit is canonicalized. There are probably only two choices,
// the first two. X should always be the greatest.
if ( x >= y ) {
if ( y >= z ) {
swapParity = true
blue = [ eight, [], [] ]
green = [ five, five, [] ]
} else if ( x >= z ) {
blue = [ eight, [], [] ]
green = [ five, [], five ]
} else {
swapParity = true
blue = [ [], eight, [] ]
green = [ five, [], five ]
}
} else {
if ( x >= z ) {
blue = [ [], eight, [] ]
green = [ five, five, [] ]
} else if ( y >= z ) {
swapParity = true
blue = [ [], eight, [] ]
green = [ [], five, five ]
} else {
blue = [ [], [], eight ]
green = [ [], five, five ]
}
}

const centroid = scalarmul( [1,,3], vectoradd( vectoradd( blue, green ), yellow ) )

const trianglePlane = planeFromPoints( blue, green, yellow )
const strutCenterline = [ [[],[],[]], prototype ]
const endCenter = linePlaneIntersection( strutCenterline, trianglePlane )

const ftl_offset = vectorsub( swapParity? green : yellow, centroid )
const fbl_offset = vectorsub( swapParity? yellow : green, centroid )
const ftl_v = vectoradd( endCenter, ftl_offset )
const fbl_v = vectoradd( endCenter, fbl_offset )
const fbr_v = vectorsub( endCenter, ftl_offset )
const ftr_v = vectorsub( endCenter, fbl_offset )

const nbr_v = ftl_v .map( grneg )
const ntr_v = fbl_v .map( grneg )
const ntl_v = fbr_v .map( grneg )
const nbl_v = ftr_v .map( grneg )

return {
prototype,
vertices: [ ftl_v, ftr_v, fbl_v, fbr_v, ntl_v, ntr_v, nbl_v, nbr_v ],
polygons,
tip,
waist: []
}
}
}
Insert cell
planeFromPoints = function( v1, v2, v3 )
{
const e1 = vectorsub( v1, v2 )
const e2 = vectorsub( v1, v3 )
const normal = wedge( e1, e2 )
return [ v1, normal ]
}
Insert cell
linePlaneIntersection = function( line, plane )
{
const [ lineStart, lineDirection ] = line
const [ planeCenter, planeNormal ] = plane
const denom = dot( planeNormal, lineDirection )
if ( denom[ 0 ] == 0 && denom[ 1 ] == 0 )
return undefined

const p1p3 = vectorsub( planeCenter, lineStart )
const numerator = dot( planeNormal, p1p3 )
const u = grdiv( numerator, denom )
return vectoradd( lineStart, scalarmul( u, lineDirection ) )
}

Insert cell
function colorWord( name ) {
return html`<span style="background:#cccccc;color:${name};">${name}</span>`
}
Insert cell
Insert cell
import {createStrutGeometry} from '@vorth/observable-vzome-rendering'
Insert cell
import {grfloat, grneg, grsum, grdiv, grmul, wedge, dot, vectorsub, vectoradd, scalarmul } from '@jrus/zome-arithmetic'
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more