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

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more