Published
Edited
Oct 24, 2020
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
frenetPoints = curve(views.sweep).computeFrenetFrames(conf.nsweep, conf.closed);
Insert cell
curvaSweepPoints
Insert cell
function getTranslations(){
let translacoes = []
for(let i = 0;i <= conf.nsweep;i++){
var m = new THREE.Matrix4()
let angle = THREE.Math.degToRad(conf.twist)*(i/conf.nsweep)
frenetPoints.binormals[i].applyAxisAngle(frenetPoints.tangents[i],angle)
frenetPoints.normals[i].applyAxisAngle(frenetPoints.tangents[i],angle)
var arrowHelperBi = new THREE.ArrowHelper(frenetPoints.binormals[i], curvaSweepPoints[i], 1, 0xff0000 )
var arrowHelperNor = new THREE.ArrowHelper(frenetPoints.normals[i], curvaSweepPoints[i], 1, 0x00ff00 )
frenetFrames[i*3+1] = arrowHelperBi
frenetFrames[i*3+2] = arrowHelperNor
m.set(frenetPoints.binormals[i].x,frenetPoints.normals[i].x,frenetPoints.tangents[i].x,curvaSweepPoints[i].x,
frenetPoints.binormals[i].y,frenetPoints.normals[i].y,frenetPoints.tangents[i].y,curvaSweepPoints[i].y,
frenetPoints.binormals[i].z,frenetPoints.normals[i].z,frenetPoints.tangents[i].z,curvaSweepPoints[i].z,
0,0,0,1
)
translacoes.push(m)
}
return translacoes
}
Insert cell
translacoes = getTranslations()
Insert cell
curvaSweepPoints = curve(views.sweep).getPoints(conf.nsweep)
Insert cell
function interpola(i){
let interPoints = []
for(let j = 0;j < views.start.length; j++){
let xA = views.start[j].x
let yA = views.start[j].y
let zA = views.start[j].z
xA *= i
yA *= i
zA *= i
let xB = views.finish[j].x
let yB = views.finish[j].y
let zB = views.finish[j].z
xB *= 1.0-i
yB *= 1.0-i
zB *= 1.0-i
let k = new THREE.Vector3(xB+xA,yB+yA,zB+zA)
interPoints.push(k)
}
return interPoints
}
Insert cell
function varre(){
let swept = []
for(let i = 0;i <= conf.nsweep;i++){
swept.push(curve(interpola(i/conf.nsweep)).getPoints(conf.nsection).map(p => { p.applyMatrix4(translacoes[i]);return p}))
}
return swept
}
Insert cell
sweptSurface = varre()
Insert cell
sweptSurface
Insert cell
function renderFrenet(frenetFrames){
frenetFrames.children = []
for(let i = 0;i <curvaSweepPoints.length;i++){
var arrowHelperBi = new THREE.ArrowHelper(frenetPoints.binormals[i], curvaSweepPoints[i], 1, 0xff0000 )
var arrowHelperNor = new THREE.ArrowHelper(frenetPoints.normals[i], curvaSweepPoints[i], 1, 0x00ff00 )
var arrowHelperTan = new THREE.ArrowHelper(frenetPoints.tangents[i], curvaSweepPoints[i], 1, 0x0000ff )
frenetFrames.add(arrowHelperTan)
frenetFrames.add(arrowHelperBi)
frenetFrames.add(arrowHelperNor)
}
}
Insert cell
//
// Simple trackball controls. Changes the surface rotation and the camera distance in
// response to mouse interactions in the 3D view
//
{
let mouse = null;
let canvas = renderer.domElement;
canvas.oncontextmenu = (e) => {
e.preventDefault();
e.stopPropagation()
}
canvas.onmousedown = (e) => {
mouse = new THREE.Vector3(e.offsetX,e.offsetY,0)
}
canvas.onmouseup = (e) => {

mouse = null
}
canvas.onmousemove = (e) => {

if (mouse) {
let newMouse = new THREE.Vector3(e.offsetX,e.offsetY,0);
if (e.buttons & 1) {
let axis = new THREE.Vector3(newMouse.y-mouse.y,newMouse.x-mouse.x,0);
let angle = axis.length()*Math.PI/180*0.5; // 1/2 degree
if (angle == 0) return;
axis.normalize();
let rot = new THREE.Quaternion().setFromAxisAngle(axis,angle);
surface.quaternion.premultiply(rot);
frenetFrames.quaternion.premultiply(rot);
}
else {
let scale = newMouse.y > mouse.y ? 0.98 : (newMouse.y < mouse.y ? 1.02 : 1);
camera.position.multiplyScalar(scale);
}
renderer.render(scene,camera)
mouse = newMouse
}
}
}
Insert cell
//
// Reevaluates the surface geometry. Called whenever the interface curves change
//
{
surface.geometry.dispose();
surface.geometry = surfaceGeometry (sweptSurface);
renderer.render(scene,camera)
}
Insert cell
//
// Toggles the wireframe / texture settings in the material
//
{
material.wireframe = !!conf.wireframe;
material.map = conf.texture ? checkerTexture : null;
material.needsUpdate = true;
conf.frenet ? renderFrenet(frenetFrames) : frenetFrames.children = [];
material.map = conf.closed ? textureMapp : material.map
}
Insert cell
Insert cell
renderer = new THREE.WebGLRenderer ({canvas, antialias: true})
Insert cell
camera = {
let camera = new THREE.PerspectiveCamera(70, 16/9, 0.1, 100);
camera.position.set (0,0,6)
return camera;
}
Insert cell
light = {
let lights = new THREE.Group();
let lightDir = new THREE.DirectionalLight (0xffffff, 1,);
lightDir.position.set(1,1,1);
let lightAmb = new THREE.AmbientLight (0x303030);
lights.add (lightAmb, lightDir)
return lights
}
Insert cell
imagem = await FileAttachment("donet.jpg").image()
Insert cell
imagemdois = await FileAttachment("store.png").image()
Insert cell
material = new THREE.MeshStandardMaterial({color:0xffffff,side:THREE.DoubleSide });
//new THREE.MeshStandardMaterial({color: 0xFFFFFF, side:THREE.DoubleSide })
Insert cell
surface = new THREE.Mesh (new THREE.Geometry(), material)
Insert cell
frenetFrames = new THREE.Group()
Insert cell
objects = new THREE.Group().add(surface,frenetFrames)
Insert cell
scene = {
let scene = new THREE.Scene();
let color = new THREE.Color(0xEEEEEE)
scene.background = conf.closed ? backgroundTexture : color
scene.add(objects)
scene.add(light)
return scene
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
checkerTexture = {
let texture = new THREE.Texture (checker);
texture.anisotropy = 4;
texture.minFilter = THREE.LinearFilter
texture.needsUpdate = true;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
return texture;
}
Insert cell
backgroundTexture = {
let texture = new THREE.Texture (imagemdois);
texture.anisotropy = 8;
texture.minFilter = THREE.LinearFilter
texture.needsUpdate = true;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
return texture;
}
Insert cell
textureMapp = {
let texture = new THREE.Texture (imagem);
texture.anisotropy = 8;
texture.minFilter = THREE.LinearFilter
texture.needsUpdate = true;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
return texture;
}
Insert cell
{
textureMapp.wrapS = THREE.RepeatWrapping;
textureMapp.wrapT = THREE.RepeatWrapping;
textureMapp.needsUpdate = true;
textureMapp.repeat.set( 2,2 );
}
Insert cell
Insert cell
//
// Returns a THREE.Geometry consisting of a mesh connecting polylines
//
function surfaceGeometry (polylines) {
let geometry = new THREE.Geometry();
let n = polylines[0].length;
let m = polylines.length;
let uvs = [];
let tex = (i,j) => new THREE.Vector2 (i/(m-1),j/(n-1));
geometry.faceVertexUvs = [uvs];
for (let poly of polylines)
for (let v of poly) geometry.vertices.push(v);
for (let i = 0; i+1 < m; i++) {
for (let j = 0; j+1 < n; j++) {
geometry.faces.push (new THREE.Face3(i*n+j, i*n+j+1, (i+1)*n+j),
new THREE.Face3((i+1)*n+j, i*n+j+1, (i+1)*n+j+1));
uvs.push ([tex(i, j), tex(i, j+1), tex(i+1, j)],
[tex(i+1, j), tex(i, j+1), tex(i+1, j+1)]);
}
}
geometry.computeFaceNormals();
geometry.computeVertexNormals();
return geometry
}
Insert cell
// Shortcut for creating a Vector3
Vec = (x,y,z=0) => new THREE.Vector3 (x,y,z)
Insert cell
//
// Returns a Matrix4 that maps a centered cube of size side to a rectangle of width w and height h.
// By default, isometric xy projection is used, but one can also choose yz or zx projection.
//
canvasTransform = function (side, w, h, projection = 'xy') {
let scale = Math.min(w,h)/side;
let angles = projection == 'xy' ? [0,0,0] : (projection == 'yz' ?
[-Math.PI/2,0,-Math.PI/2] :
[0,Math.PI/2,Math.PI/2]);
let rotation = new THREE.Euler(...angles);
let m = new THREE.Matrix4().makeRotationFromEuler(rotation);
return m.premultiply (new THREE.Matrix4().scale(Vec(scale,-scale,scale))).setPosition(w/2,h/2,0);
}
Insert cell
//
// Returns a catmull rom curve using the vertices of the polyline as control points
//
function curve (poly) {
return new THREE.CatmullRomCurve3(poly, conf.closed, 'catmullrom', conf.tension)
}
Insert cell
Insert cell
THREE = {
const THREE = window.THREE = await require('three@0.119.1');
await require('three@0.119.1/examples/js/controls/TrackballControls.js').catch(() => {});
return THREE
}
Insert cell
d3 = require("d3@5")
Insert cell
import {combo} from "@esperanc/aggregated-inputs"
Insert cell
import {checkbox,number} from "@jashkenas/inputs"
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