Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| playground:test_3js [2020/04/23 12:33] – hnagel | playground:test_3js [2020/08/20 10:17] (current) – hnagel | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | <code perl> | ||
| + | > cube(3)-> | ||
| + | </ | ||
| + | < | ||
| + | <!-- | ||
| + | polymake for knusper | ||
| + | Thu Aug 20 14:10:19 2020 | ||
| + | unnamed | ||
| + | --> | ||
| + | |||
| < | < | ||
| - | <div name=" | ||
| - | padding: 0.4em; | ||
| - | -webkit-box-flex: | ||
| - | -moz-box-flex: | ||
| - | box-flex: 1; | ||
| - | flex: 1; | ||
| - | max-width: calc(100% - 14ex);"> | ||
| < | < | ||
| + | <meta charset=utf-8> | ||
| < | < | ||
| < | < | ||
| Line 14: | Line 18: | ||
| // COMMON_CODE_BLOCK_BEGIN | // COMMON_CODE_BLOCK_BEGIN | ||
| */ | */ | ||
| - | | + | html {overflow: scroll;} |
| - | body { font-family: | + | |
| | | ||
| | | ||
| - | | ||
| | | ||
| | | ||
| - | | + | |
| | | ||
| - | | + | |
| - | | + | |
| | | ||
| - | | + | |
| - | | + | |
| - | .resetButton{margin-top: 20px;} | + | button{margin-left: 0; margin-top: 10px} |
| - | | + | |
| | | ||
| - | | + | |
| - | .transparency{display: none;} | + | # |
| - | .labelsCheckbox{margin-top: 10px;} | + | .threejs_container |
| - | + | .settings{max-height: | |
| | | ||
| | | ||
| Line 42: | Line 42: | ||
| | | ||
| | | ||
| - | | + | |
| + | | ||
| | | ||
| } | } | ||
| Line 129: | Line 130: | ||
| </ | </ | ||
| </ | </ | ||
| - | |||
| < | < | ||
| + | < | ||
| <div id=' | <div id=' | ||
| <div class=group id=' | <div class=group id=' | ||
| Line 144: | Line 144: | ||
| < | < | ||
| < | < | ||
| - | < | + | < |
| </ | </ | ||
| Line 155: | Line 155: | ||
| <div class=group id=' | <div class=group id=' | ||
| < | < | ||
| + | <div class=indented> | ||
| + | < | ||
| + | </ | ||
| + | <div class=suboption> | ||
| <div class=indented> | <div class=indented> | ||
| < | < | ||
| - | < | ||
| </ | </ | ||
| </ | </ | ||
| Line 174: | Line 177: | ||
| </ | </ | ||
| - | <img id=' | + | <img id=' |
| - | <img id=' | + | <img id=' |
| - | <div id="model39814440028"></ | + | <div id="model47529851256"></ |
| - | + | </ | |
| - | < | + | |
| - | requirejs.config({ | + | requirejs.config({ |
| - | paths: { | + | paths: { |
| - | three: '/ | + | three: '/ |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | WEBGL: '/ |
| - | | + | }, |
| - | | + | shim: { |
| - | shim: { | + | ' |
| - | ' | + | ' |
| - | | + | 'WEBGL': { deps: [ ' |
| - | | + | ' |
| - | | + | ' |
| - | ' | + | } |
| - | { | + | }); |
| - | deps: [ ' | + | |
| - | exports: ' | + | |
| - | }, | + | window.THREE = THREE; |
| - | | + | require([' |
| - | | + | THREE.TrackballControls |
| - | | + | THREE.Projector |
| - | | + | THREE.SVGRenderer |
| - | | + | THREE.WEBGL = WEBGL; |
| - | 'CanvasRenderer': | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | ' | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | ' | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | } | + | |
| - | }); | + | |
| - | require([' | + | |
| - | window.THREE = THREE; | + | |
| - | require([' | + | |
| - | THREE.SVGRenderer | + | |
| - | THREE.CanvasRenderer | + | |
| - | THREE.Projector | + | |
| - | THREE.TrackballControls | + | |
| // COMMON_CODE_BLOCK_BEGIN | // COMMON_CODE_BLOCK_BEGIN | ||
| - | var foldable = false; | ||
| - | var container = document.getElementById( ' | ||
| - | var renderer = Detector.webgl? | ||
| - | var svgRenderer = new THREE.SVGRenderer({antialias: | ||
| - | var box = document.getElementsByName( ' | ||
| - | var notebook = document.getElementById( ' | ||
| - | var width = box.clientWidth - 25; | + | const intervalLength |
| - | var height = 500; //this needs sth more reasonable | + | const explodableModel |
| - | //var height | + | const modelContains = { points: false, pointlabels: |
| - | renderer.setSize(width, height); | + | const foldables = []; |
| - | | + | |
| - | | + | |
| - | svgRenderer.setClearColor(0xFFFFFF, | + | |
| - | | + | var three = document.getElementById(" |
| + | var scene = new THREE.Scene(); | ||
| - | var scene = new THREE.Scene(); | + | var camera |
| - | var camera | + | camera.position.set(0, 0, 5); |
| + | camera.lookAt(0, 0, 0); | ||
| + | camera.up.set(0, | ||
| - | var renderid; | + | var renderer = new THREE.WebGLRenderer( { antialias: true } ); |
| + | var svgRenderer = new THREE.SVGRenderer({antialias: | ||
| + | renderer.setPixelRatio( window.devicePixelRatio ); | ||
| + | renderer.setClearColor(0xFFFFFF, | ||
| + | svgRenderer.setClearColor(0xFFFFFF, | ||
| + | three.appendChild(renderer.domElement); | ||
| - | | + | var control = new THREE.TrackballControls(camera, three); |
| - | camera.lookAt(0, 0, 0); | + | control.zoomSpeed = 0.2; |
| - | camera.up.set(0, 1, 0); | + | control.rotateSpeed = 4; |
| - | // class to allow move points together with labels and spheres | + | function onWindowResize() { |
| - | | + | var width = three.clientWidth; |
| - | this.vector = new THREE.Vector3(x, | + | var height = three.clientHeight; |
| - | this.sprite = null; | + | renderer.setSize( width, height ); |
| - | this.sphere = null; | + | svgRenderer.setSize( width, height ); |
| - | | + | camera.aspect = width / height; |
| - | | + | camera.updateProjectionMatrix(); |
| - | this.sprite = textSprite( label ); | + | } |
| + | |||
| + | onWindowResize(); | ||
| + | window.addEventListener(' | ||
| + | |||
| + | // class to allow move points together with labels and spheres | ||
| + | var PMPoint = function (x,y,z) { | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | PMPoint.prototype.addLabel | ||
| + | | ||
| + | | ||
| + | } | ||
| + | PMPoint.prototype.addSphere = function(spheremesh) { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | PMPoint.prototype.set = function(x, | ||
| + | | ||
| + | if (this.sprite) { | ||
| this.sprite.position.copy(this.vector); | this.sprite.position.copy(this.vector); | ||
| } | } | ||
| - | PMPoint.prototype.makesphere = function(radius, | + | if (this.sphere) |
| - | | + | |
| this.sphere.position.copy(this.vector); | this.sphere.position.copy(this.vector); | ||
| } | } | ||
| + | } | ||
| + | PMPoint.prototype.radius = function() { | ||
| + | if (this.sphere) { | ||
| + | return this.sphere.geometry.parameters.radius; | ||
| + | } else { | ||
| + | return 0; | ||
| + | } | ||
| + | }; | ||
| + | // select the target node | ||
| + | var target = document.querySelector('# | ||
| - | | + | // create an observer instance |
| - | this.vector.setX(x); | + | var observer |
| - | if (this.sprite) { | + | mutations.forEach(function(mutation) { |
| - | this.sprite.position.setX(x); | + | if (mutation.removedNodes && mutation.removedNodes.length > 0) { |
| + | cancelAnimationFrame(renderId); | ||
| + | | ||
| + | | ||
| } | } | ||
| - | | + | }); |
| - | this.sphere.position.setX(x); | + | }); |
| + | |||
| + | // configuration of the observer: | ||
| + | var config = { childList: true, characterData: | ||
| + | |||
| + | // pass in the target node, as well as the observer options | ||
| + | while (target) { | ||
| + | if (target.className==" | ||
| + | observer.observe(target, | ||
| + | break; | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | |||
| + | // COMMON_CODE_BLOCK_END | ||
| + | |||
| + | var obj0 = new THREE.Object3D(); | ||
| + | obj0.name = " | ||
| + | obj0.userData.explodable = 1; | ||
| + | obj0.userData.points = []; | ||
| + | obj0.userData.points.push(new PMPoint(-1, -1, -1)); | ||
| + | obj0.userData.points.push(new PMPoint(1, -1, -1)); | ||
| + | obj0.userData.points.push(new PMPoint(-1, 1, -1)); | ||
| + | obj0.userData.points.push(new PMPoint(1, 1, -1)); | ||
| + | obj0.userData.points.push(new PMPoint(-1, -1, 1)); | ||
| + | obj0.userData.points.push(new PMPoint(1, -1, 1)); | ||
| + | obj0.userData.points.push(new PMPoint(-1, 1, 1)); | ||
| + | obj0.userData.points.push(new PMPoint(1, 1, 1)); | ||
| + | |||
| + | obj0.userData.pointradii = 0.02; | ||
| + | < | ||
| + | obj0.userData.pointmaterial = new THREE.MeshBasicMaterial( { color: 0xFF0000, side: THREE.DoubleSide, | ||
| + | obj0.userData.pointlabels = [" | ||
| + | obj0.userData.edgeindices = [0, 1, 0, 2, 1, 3, 2, 3, 0, 4, 1, 5, 4, 5, 2, 6, 4, 6, 3, 7, 5, 7, 6, 7]; | ||
| + | < | ||
| + | obj0.userData.edgematerial = new THREE.LineBasicMaterial( { color: 0x000000, depthTest: true, linewidth: 1.5, transparent: | ||
| + | obj0.userData.facets = [[0, 4, 6, 2], [7, 5, 1, 3], [5, 4, 0, 1], [2, 6, 7, 3], [0, 2, 3, 1], [6, 4, 5, 7]]; | ||
| + | < | ||
| + | obj0.userData.facetmaterial = new THREE.MeshBasicMaterial( { color: 0x77EC9E, depthFunc: THREE.LessDepth, | ||
| + | init_object(obj0); | ||
| + | scene.add(obj0); | ||
| + | // COMMON_CODE_BLOCK_BEGIN | ||
| + | function textSpriteMaterial(message, | ||
| + | if ( parameters === undefined ) parameters = {}; | ||
| + | var fontface = " | ||
| + | var fontsize = parameters.hasOwnProperty(" | ||
| + | fontsize = fontsize*10; | ||
| + | var lines = message.split(' | ||
| + | var size = 512; | ||
| + | for(var i = 0; i< | ||
| + | var tmp = lines[i].length; | ||
| + | while(tmp*fontsize > size){ | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | |||
| + | var canvas = document.createElement(' | ||
| + | canvas.width = size; | ||
| + | canvas.height = size; | ||
| + | var context = canvas.getContext(' | ||
| + | context.fillStyle = " | ||
| + | context.fill(); | ||
| + | context.font = fontsize + "px " + fontface; | ||
| + | |||
| + | // text color | ||
| + | context.fillStyle = " | ||
| + | | ||
| + | context.fillText(lines[i], | ||
| + | } | ||
| + | |||
| + | // canvas contents will be used for a texture | ||
| + | var texture = new THREE.Texture(canvas); | ||
| + | texture.needsUpdate = true; | ||
| + | |||
| + | var spriteMaterial = new THREE.SpriteMaterial({map: | ||
| + | return spriteMaterial; | ||
| + | } | ||
| + | |||
| + | |||
| + | // ---------------------- INITIALIZING OBJECTS-------------------------------------- | ||
| + | // --------------------------------------------------------------------------------- | ||
| + | |||
| + | function init_object(obj) { | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_points(obj); | ||
| + | modelContains.points = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_pointlabels(obj); | ||
| + | modelContains.pointlabels = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_lines(obj); | ||
| + | modelContains.lines = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_edgelabels(obj); | ||
| + | modelContains.edgelabels = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_arrowheads(obj); | ||
| + | modelContains.arrowheads = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_faces(obj); | ||
| + | modelContains.faces = true; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function init_points(obj) { | ||
| + | var pointgroup = new THREE.Group(); | ||
| + | | ||
| + | var points = obj.userData.points; | ||
| + | var radii = obj.userData.pointradii; | ||
| + | var materials = obj.userData.pointmaterial; | ||
| + | var geometry, | ||
| + | if (!Array.isArray(radii)) { | ||
| + | geometry = new THREE.SphereBufferGeometry(radii); | ||
| + | } | ||
| + | if (!Array.isArray(materials)) { | ||
| + | material = materials; | ||
| + | } | ||
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | if (Array.isArray(radii)) { | ||
| + | if (radii[i] == 0) { | ||
| + | continue; | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | if (Array.isArray(materials)) { | ||
| + | | ||
| + | } | ||
| + | var sphere | ||
| + | point.addSphere(sphere); | ||
| + | pointgroup.add(sphere); | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | |||
| + | function init_pointlabels(obj) { | ||
| + | var points = obj.userData.points; | ||
| + | var labels = obj.userData.pointlabels; | ||
| + | var pointlabels = new THREE.Group(); | ||
| + | | ||
| + | if (Array.isArray(labels)) { | ||
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | var spriteMaterial = textSpriteMaterial( labels[i] ); | ||
| + | var sprite = new THREE.Sprite(spriteMaterial); | ||
| + | | ||
| + | | ||
| } | } | ||
| - | }; | + | |
| - | PMPoint.prototype.setY | + | var spriteMaterial |
| - | | + | |
| - | if (this.sprite) | + | var point = points[i]; |
| - | this.sprite.position.setY(y); | + | var sprite = new THREE.Sprite(spriteMaterial); |
| + | point.addLabel(sprite); | ||
| + | pointlabels.add(sprite); | ||
| } | } | ||
| - | if (this.sphere) { | + | } |
| - | this.sphere.position.setY(y); | + | obj.add(pointlabels); |
| + | } | ||
| + | |||
| + | function init_lines(obj) { | ||
| + | var edgeindices = obj.userData.edgeindices; | ||
| + | var points = obj.userData.points; | ||
| + | var materials = obj.userData.edgematerial; | ||
| + | var geometry = new THREE.BufferGeometry(); | ||
| + | var bufarr = new Float32Array( obj.userData.edgeindices.length * 3 ); | ||
| + | var bufattr = new THREE.Float32BufferAttribute( bufarr, 3 ); | ||
| + | var geometry = new THREE.BufferGeometry(); | ||
| + | | ||
| + | if (Array.isArray(materials)) { | ||
| + | for (var i=0; i< | ||
| + | | ||
| } | } | ||
| - | }; | + | } |
| - | PMPoint.prototype.setZ = function(z) { | + | var lines = new THREE.LineSegments(geometry, |
| - | this.vector.setZ(z); | + | lines.name = " |
| - | if (this.sprite) { | + | |
| - | this.sprite.position.setZ(z); | + | |
| + | } | ||
| + | |||
| + | function | ||
| + | var points = obj.userData.points; | ||
| + | var edgeindices = obj.userData.edgeindices; | ||
| + | var labels = obj.userData.edgelabels; | ||
| + | var edgelabels = new THREE.Group(); | ||
| + | edgelabels.name = " | ||
| + | if (Array.isArray(labels)) { | ||
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | var spriteMaterial = textSpriteMaterial( labels[i] ); | ||
| + | var sprite = new THREE.Sprite(spriteMaterial); | ||
| + | sprite.position.copy(new THREE.Vector3().addVectors(points[edgeindices[i]].vector, | ||
| + | | ||
| } | } | ||
| - | if (this.sphere) { | + | } else { |
| - | this.sphere.position.setZ(z); | + | var spriteMaterial = textSpriteMaterial( labels ); |
| + | for (var i=0; i<points.length; i++) { | ||
| + | var point = points[i]; | ||
| + | var sprite = new THREE.Sprite(spriteMaterial); | ||
| + | | ||
| + | | ||
| } | } | ||
| - | }; | + | } |
| - | PMPoint.prototype.set = function(x,y,z) { | + | obj.add(edgelabels); |
| - | this.vector.set(x,y,z); | + | } |
| - | if (this.sprite) { | + | |
| - | this.sprite.position.set(x,y,z); | + | function init_arrowheads(obj) { |
| + | var arrowheads = new THREE.Group(); | ||
| + | arrowheads.name | ||
| + | var arrowstyle = obj.userData.arrowstyle; | ||
| + | var edgeindices = obj.userData.edgeindices; | ||
| + | var edgematerials = obj.userData.edgematerial; | ||
| + | var points = obj.userData.points; | ||
| + | var material; | ||
| + | if (!Array.isArray(edgematerials)) { | ||
| + | | ||
| + | } | ||
| + | |||
| + | for (var i=0; i< | ||
| + | var start = points[edgeindices[i]]; | ||
| + | var end = points[edgeindices[i+1]]; | ||
| + | var dist = start.vector.distanceTo( end.vector ) - start.radius() - end.radius(); | ||
| + | if (dist <= 0) { | ||
| + | continue; | ||
| + | } | ||
| + | var dir = new THREE.Vector3().subVectors(end.vector, | ||
| + | dir.normalize(); | ||
| + | var axis = new THREE.Vector3().set(dir.z,0, | ||
| + | axis.normalize(); | ||
| + | var radians = Math.acos( dir.y ); | ||
| + | var radius = dist/25; | ||
| + | var height = dist/5; | ||
| + | var geometry = new THREE.ConeBufferGeometry(radius,height); | ||
| + | var position = new THREE.Vector3().addVectors(start.vector, | ||
| + | | ||
| + | | ||
| + | } | ||
| + | var cone = new THREE.Mesh( geometry, material ); | ||
| + | cone.quaternion.setFromAxisAngle(axis, | ||
| + | cone.position.copy(position);; | ||
| + | arrowheads.add(cone); | ||
| + | } | ||
| + | obj.add(arrowheads); | ||
| + | } | ||
| + | |||
| + | function init_faces(obj) { | ||
| + | var points = obj.userData.points; | ||
| + | var facets = obj.userData.facets; | ||
| + | | ||
| + | for (var i=0; i< | ||
| + | facet = facets[i]; | ||
| + | for (var t=0; t< | ||
| + | | ||
| } | } | ||
| - | if (this.sphere) { | + | } |
| - | this.sphere.position.set(x,y,z); | + | var bufarr = new Float32Array( obj.userData.triangleindices.length * 3 ); |
| - | } | + | var bufattr = new THREE.Float32BufferAttribute(bufarr,3); |
| - | }; | + | |
| - | PMPoint.prototype.add = function(o) { | + | var materials = obj.userData.facetmaterial; |
| - | if (this.sprite) { | + | var geometry = new THREE.BufferGeometry(); |
| - | o.add(this.sprite); | + | |
| - | | + | |
| - | | + | var tricount = 0; |
| - | o.add(this.sphere); | + | |
| + | | ||
| + | facet = facets[i]; | ||
| + | | ||
| + | | ||
| } | } | ||
| - | }; | + | } |
| + | var mesh = new THREE.Mesh(geometry, | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | // // | ||
| - | var controls | + | function updateFacesPosition(obj) { |
| - | controls.zoomSpeed | + | var points |
| - | controls.rotateSpeed | + | var indices = obj.userData.triangleindices; |
| + | var faces = obj.getObjectByName(" | ||
| + | var ba = faces.geometry.getAttribute(" | ||
| + | for (var i=0; i< | ||
| + | ba.setXYZ(i, points[indices[i]].vector.x, | ||
| + | } | ||
| + | | ||
| + | |||
| + | } | ||
| - | var all_objects | + | function updateEdgesPosition(obj) { |
| - | | + | var points |
| - | // select the target node | + | |
| - | | + | var lines = obj.getObjectByName(" |
| + | | ||
| + | for (var i=0; i< | ||
| + | ba.setXYZ(i, | ||
| + | } | ||
| + | | ||
| + | } | ||
| - | // create an observer instance | ||
| - | var observer = new MutationObserver(function(mutations) { | ||
| - | mutations.forEach(function(mutation) { | ||
| - | if (mutation.removedNodes && mutation.removedNodes.length > 0) { | ||
| - | cancelAnimationFrame(renderId); | ||
| - | observer.disconnect(); | ||
| - | console.log(" | ||
| - | } | ||
| - | }); | ||
| - | }); | ||
| - | // configuration of the observer: | ||
| - | var config = { childList: true, characterData: | ||
| - | // pass in the target node, as well as the observer options | + | var xRotationEnabled = false; |
| - | while (target) { | + | var yRotationEnabled = false; |
| - | if (target.className=="output") { | + | var zRotationEnabled = false; |
| - | observer.observe(target, | + | var rotationSpeedFactor = 1; |
| - | break; | + | var settingsShown = false; |
| + | var labelsShown = true; | ||
| + | var intervals = []; | ||
| + | var timeouts = []; | ||
| + | var explodingSpeed = 0.05; | ||
| + | var explodeScale = 0; | ||
| + | var XMLS = new XMLSerializer(); | ||
| + | var svgElement; | ||
| + | var renderId; | ||
| + | |||
| + | var render = function () { | ||
| + | |||
| + | renderId = requestAnimationFrame(render); | ||
| + | |||
| + | // comment | ||
| + | // explode(updateFactor()); | ||
| + | |||
| + | var phi = 0.02 * rotationSpeedFactor; | ||
| + | |||
| + | if (xRotationEnabled) { | ||
| + | | ||
| + | } | ||
| + | | ||
| + | scene.rotation.y += phi; | ||
| + | } | ||
| + | if (zRotationEnabled) { | ||
| + | scene.rotation.z += phi; | ||
| + | } | ||
| + | |||
| + | control.update(); | ||
| + | renderer.render(scene, | ||
| + | }; | ||
| + | |||
| + | if ( THREE.WEBGL.isWebGLAvailable() ) { | ||
| + | render(); | ||
| + | } else { | ||
| + | var warning = WEBGL.getWebGLErrorMessage(); | ||
| + | three.appendChild( warning ); | ||
| + | } | ||
| + | |||
| + | function changeTransparency() { | ||
| + | var opacity = 1-Number(event.currentTarget.value); | ||
| + | for (var i=0; i< | ||
| + | child = scene.children[i]; | ||
| + | if ( child.userData.hasOwnProperty("facetmaterial") ) { | ||
| + | if (Array.isArray(child.userData.facetmaterial)) { | ||
| + | for (var j=0; j< | ||
| + | child.userData.facetmaterial[j].opacity = opacity; | ||
| + | } | ||
| + | } else { | ||
| + | child.userData.facetmaterial.opacity = opacity; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function changeRotationX(event){ | ||
| + | xRotationEnabled = event.currentTarget.checked; | ||
| + | } | ||
| + | |||
| + | function changeRotationY(event){ | ||
| + | yRotationEnabled = event.currentTarget.checked; | ||
| + | } | ||
| + | |||
| + | function changeRotationZ(event){ | ||
| + | zRotationEnabled = event.currentTarget.checked; | ||
| + | } | ||
| + | |||
| + | |||
| + | function changeRotationSpeedFactor(event){ | ||
| + | rotationSpeedFactor = Number(event.currentTarget.value); | ||
| + | } | ||
| + | |||
| + | function resetScene(){ | ||
| + | scene.rotation.set(0, | ||
| + | camera.position.set(0, | ||
| + | camera.up.set(0, | ||
| + | } | ||
| + | |||
| + | function showSettings(event){ | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | settingsShown = true; | ||
| + | } | ||
| + | |||
| + | function hideSettings(event){ | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | settingsShown = false; | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | var pos = 150* Math.PI; | ||
| + | |||
| + | function updateFactor() { | ||
| + | pos++; | ||
| + | return Math.sin(.01*pos)+1; | ||
| + | } | ||
| + | |||
| + | // ------------------------ FOLDING ------------------------------------------------ | ||
| + | // --------------------------------------------------------------------------------- | ||
| + | // rotate point p around axis defined by points p1 and p2 by given angle | ||
| + | function rotate(p, p1, p2, angle ){ | ||
| + | angle = -angle; | ||
| + | var x = p.x, y = p.y, z = p.z, | ||
| + | a = p1.x, b = p1.y, c = p1.z, | ||
| + | u = p2.x-p1.x, v = p2.y-p1.y, w = p2.z-p1.z; | ||
| + | var result = []; | ||
| + | var L = u*u + v*v + w*w; | ||
| + | var sqrt = Math.sqrt; | ||
| + | var cos = Math.cos; | ||
| + | var sin = Math.sin; | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | } | ||
| + | |||
| + | var fold = function(event){ | ||
| + | var obj = foldables[Number(event.currentTarget.name)]; | ||
| + | var foldvalue = Number(event.currentTarget.value); | ||
| + | var scale = foldvalue - obj.userData.oldscale; | ||
| + | |||
| + | for (var j=0; j< | ||
| + | rotateVertices(obj, | ||
| + | } | ||
| + | update(obj); | ||
| + | obj.userData.oldscale += scale; | ||
| + | lookAtBarycenter(obj); | ||
| + | } | ||
| + | |||
| + | function lookAtBarycenter(obj){ | ||
| + | control.target | ||
| + | } | ||
| + | |||
| + | function barycenter(obj) { | ||
| + | var center = new THREE.Vector3(0,0,0); | ||
| + | var points = obj.userData.points; | ||
| + | for (var i=0; i< | ||
| + | center.add(points[i].vector); | ||
| + | } | ||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | function rotateVertices(obj, | ||
| + | var axes = obj.userData.axes; | ||
| + | var subtrees = obj.userData.subtrees; | ||
| + | var points = obj.userData.points; | ||
| + | var angles = obj.userData.angles; | ||
| + | if (edge < axes.length){ | ||
| + | for (var j=0; j< | ||
| + | var rotP = rotate(points[subtrees[edge][j]].vector, | ||
| + | | ||
| } | } | ||
| - | target = target.parentNode; | ||
| } | } | ||
| + | } | ||
| + | |||
| + | function update(obj) { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | if (foldables.length) { | ||
| + | var settings = document.getElementById(' | ||
| + | var foldDiv = document.createElement(' | ||
| + | foldDiv.id = ' | ||
| + | var title = document.createElement(' | ||
| + | title.innerHTML = ' | ||
| + | foldDiv.appendChild(title); | ||
| + | foldDiv.className = ' | ||
| + | for (var i=0; i< | ||
| + | var range = document.createElement(' | ||
| + | range.type = ' | ||
| + | range.min = 0; | ||
| + | range.max = 1; | ||
| + | range.value = 0; | ||
| + | range.step = 0.001; | ||
| + | range.name = String(i); | ||
| + | range.oninput = fold; | ||
| + | foldDiv.appendChild(range); | ||
| + | } | ||
| + | lookAtBarycenter(foldables[0]); | ||
| + | settings.insertBefore(foldDiv, | ||
| + | } | ||
| + | |||
| + | | ||
| + | // ---------------------- EXPLOSION ------------------------------------------------ | ||
| + | // --------------------------------------------------------------------------------- | ||
| + | |||
| + | if (explodableModel) { | ||
| + | for (var i=0; i< | ||
| + | obj = scene.children[i]; | ||
| + | if ( obj.userData.explodable ) { | ||
| + | computeCentroid(obj); | ||
| + | } | ||
| + | } | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | } | ||
| + | |||
| + | function computeCentroid(obj) { | ||
| + | centroid = new THREE.Vector3(); | ||
| + | obj.userData.points.forEach(function(pmpoint) { | ||
| + | centroid.add(pmpoint.vector); | ||
| + | }); | ||
| + | centroid.divideScalar(obj.userData.points.length); | ||
| + | obj.userData.centroid = centroid; | ||
| + | } | ||
| + | |||
| + | function explode(factor) { | ||
| + | for (var i=0; i< | ||
| + | var obj = scene.children[i]; | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | var c = obj.userData.centroid; | ||
| + | obj.position.set(c.x*factor, | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function triggerExplode(event){ | ||
| + | explodeScale = Number(event.currentTarget.value); | ||
| + | explode(explodeScale); | ||
| + | } | ||
| + | |||
| + | function setExplodingSpeed(event){ | ||
| + | explodingSpeed = Number(event.currentTarget.value); | ||
| + | } | ||
| + | |||
| + | function triggerAutomaticExplode(event){ | ||
| + | if (event.currentTarget.checked){ | ||
| + | startExploding(); | ||
| + | } else { | ||
| + | clearIntervals(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function startExploding(){ | ||
| + | intervals.push(setInterval(explodingInterval, | ||
| + | } | ||
| + | |||
| + | |||
| + | function explodingInterval(){ | ||
| + | explodeScale += explodingSpeed; | ||
| + | if (explodeScale <= 6){ | ||
| + | explode(explodeScale); | ||
| + | } | ||
| + | else{ | ||
| + | explode(6); | ||
| + | explodeScale = 6; | ||
| + | clearIntervals(); | ||
| + | timeouts.push(setTimeout(startUnexploding, | ||
| + | } | ||
| + | document.getElementById(' | ||
| + | } | ||
| + | |||
| + | |||
| + | function startUnexploding(){ | ||
| + | intervals.push(setInterval(unexplodingInterval, | ||
| + | } | ||
| + | |||
| + | function unexplodingInterval(){ | ||
| + | explodeScale -= explodingSpeed; | ||
| + | if (explodeScale >= 0){ | ||
| + | explode(explodeScale); | ||
| + | } | ||
| + | else { | ||
| + | explode(0); | ||
| + | explodeScale = 0; | ||
| + | clearIntervals(); | ||
| + | timeouts.push(setTimeout(startExploding, | ||
| + | } | ||
| + | document.getElementById(' | ||
| + | } | ||
| + | |||
| + | function clearIntervals(){ | ||
| + | intervals.forEach(function(interval){ | ||
| + | clearInterval(interval); | ||
| + | }); | ||
| + | intervals = []; | ||
| + | timeouts.forEach(function(timeout){ | ||
| + | clearTimeout(timeout); | ||
| + | }); | ||
| + | timeouts = []; | ||
| + | } | ||
| + | |||
| + | // ---------------------- DISPLAY -------------------------------------------------- | ||
| + | // --------------------------------------------------------------------------------- | ||
| + | |||
| + | const objectTypeInnerHTMLs = { points: " | ||
| + | const objectTypeVisible = {}; | ||
| + | Object.assign(objectTypeVisible, | ||
| + | const sortedObjectTypeKeys = Object.keys(objectTypeInnerHTMLs).sort(); | ||
| + | const shownObjectTypesList = document.getElementById(' | ||
| + | |||
| + | function setVisibility(bool, | ||
| + | for (var i=0; i< | ||
| + | var obj = scene.children[i].getObjectByName(objname); | ||
| + | if (obj) { | ||
| + | obj.visible = bool; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function toggleObjectTypeVisibility(event){ | ||
| + | var name = event.currentTarget.name; | ||
| + | var checked = event.currentTarget.checked; | ||
| + | objectTypeVisible[name] = checked; | ||
| + | setVisibility(checked, | ||
| + | } | ||
| + | |||
| + | for (var i=0; i< | ||
| + | var key = sortedObjectTypeKeys[i]; | ||
| + | if (modelContains[key]) { | ||
| + | var objTypeNode = document.createElement(' | ||
| + | objTypeNode.innerHTML = objectTypeInnerHTMLs[key] + '< | ||
| + | var checkbox = document.createElement(' | ||
| + | checkbox.type = ' | ||
| + | checkbox.checked = true; | ||
| + | checkbox.name = key; | ||
| + | checkbox.onchange = toggleObjectTypeVisibility; | ||
| + | shownObjectTypesList.appendChild(checkbox); | ||
| + | shownObjectTypesList.appendChild(objTypeNode); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // ------------------------------------------------------ | ||
| + | |||
| + | function toggleObjectVisibility(event){ | ||
| + | var nr = Number(event.currentTarget.name); | ||
| + | scene.children[nr].visible = event.currentTarget.checked; | ||
| + | } | ||
| + | |||
| + | // append checkboxes for displaying or hiding objects | ||
| + | var shownObjectsList = document.getElementById(' | ||
| + | for (var i=0; i< | ||
| + | obj = scene.children[i]; | ||
| + | var objNode = document.createElement(' | ||
| + | objNode.innerHTML = obj.name + '< | ||
| + | var checkbox = document.createElement(' | ||
| + | checkbox.type = ' | ||
| + | checkbox.checked = true; | ||
| + | checkbox.name = String(i); | ||
| + | checkbox.onchange = toggleObjectVisibility; | ||
| + | shownObjectsList.appendChild(checkbox); | ||
| + | shownObjectsList.appendChild(objNode); | ||
| + | } | ||
| + | |||
| + | // ---------------------- SVG ------------------------------------------------------ | ||
| + | // --------------------------------------------------------------------------------- | ||
| + | |||
| + | function takeSvgScreenshot() { | ||
| + | if (objectTypeVisible[" | ||
| + | setVisibility(false," | ||
| + | } | ||
| + | if (objectTypeVisible[" | ||
| + | setVisibility(false," | ||
| + | } | ||
| + | svgRenderer.render(scene, | ||
| + | svgElement = XMLS.serializeToString(svgRenderer.domElement); | ||
| + | | ||
| + | if (objectTypeVisible[" | ||
| + | setVisibility(true," | ||
| + | } | ||
| + | if (objectTypeVisible[" | ||
| + | setVisibility(true," | ||
| + | } | ||
| + | |||
| + | if (document.getElementById(' | ||
| + | //show in new tab | ||
| + | var myWindow = window.open("","" | ||
| + | myWindow.document.body.innerHTML = svgElement; | ||
| + | } else{ | ||
| + | // download svg file | ||
| + | download(" | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function download(filename, | ||
| + | var element = document.createElement(' | ||
| + | element.setAttribute(' | ||
| + | element.setAttribute(' | ||
| + | |||
| + | element.style.display = ' | ||
| + | document.body.appendChild(element); | ||
| + | |||
| + | element.click(); | ||
| + | |||
| + | document.body.removeChild(element); | ||
| + | } | ||
| + | |||
| + | |||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | |||
| + | |||
| + | // ------------------ SHORTCUTS -------------------------------------------- | ||
| + | // ------------------------------------------------------------------------- | ||
| + | |||
| + | /** | ||
| + | * http:// | ||
| + | * Version : 2.01.B | ||
| + | * By Binny V A | ||
| + | * License : BSD | ||
| + | */ | ||
| + | shortcut = { | ||
| + | ' | ||
| + | ' | ||
| + | //Provide a set of default options | ||
| + | var default_options = { | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | } | ||
| + | if(!opt) opt = default_options; | ||
| + | else { | ||
| + | for(var dfo in default_options) { | ||
| + | if(typeof opt[dfo] == ' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | var ele = opt.target; | ||
| + | if(typeof opt.target == ' | ||
| + | var ths = this; | ||
| + | shortcut_combination = shortcut_combination.toLowerCase(); | ||
| + | |||
| + | //The function to be called at keypress | ||
| + | var func = function(e) { | ||
| + | e = e || window.event; | ||
| + | |||
| + | if(opt[' | ||
| + | var element; | ||
| + | if(e.target) element=e.target; | ||
| + | else if(e.srcElement) element=e.srcElement; | ||
| + | if(element.nodeType==3) element=element.parentNode; | ||
| + | |||
| + | if(element.tagName == ' | ||
| + | } | ||
| + | |||
| + | //Find Which key is pressed | ||
| + | if (e.keyCode) code = e.keyCode; | ||
| + | else if (e.which) code = e.which; | ||
| + | var character = String.fromCharCode(code).toLowerCase(); | ||
| + | |||
| + | if(code == 188) character=","; | ||
| + | if(code == 190) character=" | ||
| + | |||
| + | var keys = shortcut_combination.split(" | ||
| + | //Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked | ||
| + | var kp = 0; | ||
| + | |||
| + | //Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken | ||
| + | var shift_nums = { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ";":":", | ||
| + | "'":" | ||
| + | ",":"<", | ||
| + | " | ||
| + | "/":"?", | ||
| + | " | ||
| + | } | ||
| + | // | ||
| + | var special_keys = { | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | } | ||
| + | |||
| + | var modifiers = { | ||
| + | shift: { wanted: | ||
| + | ctrl : { wanted: | ||
| + | alt | ||
| + | meta : { wanted: | ||
| + | }; | ||
| + | | ||
| + | if(e.ctrlKey) modifiers.ctrl.pressed = true; | ||
| + | if(e.shiftKey) modifiers.shift.pressed = true; | ||
| + | if(e.altKey) modifiers.alt.pressed = true; | ||
| + | if(e.metaKey) | ||
| + | | ||
| + | for(var i=0; k=keys[i], | ||
| + | // | ||
| + | if(k == ' | ||
| + | kp++; | ||
| + | modifiers.ctrl.wanted = true; | ||
| + | |||
| + | } else if(k == ' | ||
| + | kp++; | ||
| + | modifiers.shift.wanted = true; | ||
| + | |||
| + | } else if(k == ' | ||
| + | kp++; | ||
| + | modifiers.alt.wanted = true; | ||
| + | } else if(k == ' | ||
| + | kp++; | ||
| + | modifiers.meta.wanted = true; | ||
| + | } else if(k.length > 1) { //If it is a special key | ||
| + | if(special_keys[k] == code) kp++; | ||
| + | |||
| + | } else if(opt[' | ||
| + | if(opt[' | ||
| + | |||
| + | } else { //The special keys did not match | ||
| + | if(character == k) kp++; | ||
| + | else { | ||
| + | if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase | ||
| + | character = shift_nums[character]; | ||
| + | if(character == k) kp++; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | if(kp == keys.length && | ||
| + | modifiers.ctrl.pressed == modifiers.ctrl.wanted && | ||
| + | modifiers.shift.pressed == modifiers.shift.wanted && | ||
| + | modifiers.alt.pressed == modifiers.alt.wanted && | ||
| + | modifiers.meta.pressed == modifiers.meta.wanted) { | ||
| + | callback(e); | ||
| + | |||
| + | if(!opt[' | ||
| + | // | ||
| + | e.cancelBubble = true; | ||
| + | e.returnValue = false; | ||
| + | |||
| + | // | ||
| + | if (e.stopPropagation) { | ||
| + | e.stopPropagation(); | ||
| + | e.preventDefault(); | ||
| + | } | ||
| + | return false; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | this.all_shortcuts[shortcut_combination] = { | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | }; | ||
| + | //Attach the function with the event | ||
| + | if(ele.addEventListener) ele.addEventListener(opt[' | ||
| + | else if(ele.attachEvent) ele.attachEvent(' | ||
| + | else ele[' | ||
| + | }, | ||
| + | |||
| + | //Remove the shortcut - just specify the shortcut and I will remove the binding | ||
| + | ' | ||
| + | shortcut_combination = shortcut_combination.toLowerCase(); | ||
| + | var binding = this.all_shortcuts[shortcut_combination]; | ||
| + | delete(this.all_shortcuts[shortcut_combination]) | ||
| + | if(!binding) return; | ||
| + | var type = binding[' | ||
| + | var ele = binding[' | ||
| + | var callback = binding[' | ||
| + | |||
| + | if(ele.detachEvent) ele.detachEvent(' | ||
| + | else if(ele.removeEventListener) ele.removeEventListener(type, | ||
| + | else ele[' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | shortcut.add(" | ||
| + | var event = new Event(' | ||
| + | if (settingsShown){ | ||
| + | document.getElementById(' | ||
| + | } else { | ||
| + | document.getElementById(' | ||
| + | } | ||
| + | }); | ||
| + | |||
| // COMMON_CODE_BLOCK_END | // COMMON_CODE_BLOCK_END | ||
| - | var objectnames = [" | + | });}); |
| - | var obj = new THREE.Object3D(); | + | </ |
| - | var allpoints = []; | + | </ |
| - | allpoints.push(new PMPoint(0, 0, 0)); | + | </ |
| - | allpoints.push(new PMPoint(1, 0, 0)); | + | </ |
| - | allpoints.push(new PMPoint(0, 1, 0)); | + | <code perl> |
| - | allpoints.push(new PMPoint(0, 0, 1)); | + | > fan:: |
| + | </ | ||
| + | < | ||
| + | <!-- | ||
| + | polymake for knusper | ||
| + | Thu Aug 20 14:10:19 2020 | ||
| + | planar_net_ | ||
| + | --> | ||
| - | < | ||
| - | var points_material = new THREE.MeshBasicMaterial ( {color: 0xFF0000, } ); | ||
| - | | + | < |
| - | points_material.transparent = true; | + | < |
| + | <meta charset=utf-8> | ||
| + | < | ||
| + | < | ||
| + | /* | ||
| + | // COMMON_CODE_BLOCK_BEGIN | ||
| + | */ | ||
| + | html {overflow: scroll;} | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | .group{padding-bottom: | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | # | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | box-shadow: 0px 0px 0px #000000; | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | } | ||
| + | /* | ||
| + | // COMMON_CODE_BLOCK_END | ||
| + | */ | ||
| + | </ | ||
| + | </ | ||
| + | < | ||
| + | < | ||
| + | <div id=' | ||
| + | <div class=group id=' | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | |||
| + | <div class=group id=' | ||
| + | < | ||
| + | <div class=indented> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| - | <!-- POINTS --> | + | <div class=suboption> |
| - | allpoints[0].makesphere(0.02, | + | < |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | for (index = 0; index < allpoints.length; ++index) { | + | </ |
| - | | + | |
| + | |||
| + | <div class=group id=' | ||
| + | < | ||
| + | <div class=indented> | ||
| + | < | ||
| + | </ | ||
| + | <div class=suboption> | ||
| + | <div class=indented> | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | |||
| + | <div class=group id=' | ||
| + | < | ||
| + | <div class=indented> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | </ | ||
| + | <img id=' | ||
| + | <img id=' | ||
| + | <div id=" | ||
| + | </ | ||
| + | < | ||
| + | requirejs.config({ | ||
| + | paths: { | ||
| + | three: '/ | ||
| + | TrackballControls: | ||
| + | Projector: '/ | ||
| + | SVGRenderer: | ||
| + | WEBGL: '/ | ||
| + | }, | ||
| + | shim: { | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | require([' | ||
| + | window.THREE = THREE; | ||
| + | require([' | ||
| + | THREE.TrackballControls = TrackballControls; | ||
| + | THREE.Projector = Projector; | ||
| + | THREE.SVGRenderer = SVGRenderer; | ||
| + | THREE.WEBGL = WEBGL; | ||
| + | |||
| + | // COMMON_CODE_BLOCK_BEGIN | ||
| + | |||
| + | const intervalLength = 25; // for automatic animations | ||
| + | const explodableModel = false; | ||
| + | const modelContains = { points: false, pointlabels: | ||
| + | const foldables = []; | ||
| + | |||
| + | var three = document.getElementById(" | ||
| + | var scene = new THREE.Scene(); | ||
| + | |||
| + | var camera = new THREE.PerspectiveCamera(75, | ||
| + | camera.position.set(0, | ||
| + | camera.lookAt(0, | ||
| + | camera.up.set(0, | ||
| + | |||
| + | var renderer = new THREE.WebGLRenderer( { antialias: true } ); | ||
| + | var svgRenderer = new THREE.SVGRenderer({antialias: | ||
| + | renderer.setPixelRatio( window.devicePixelRatio ); | ||
| + | renderer.setClearColor(0xFFFFFF, | ||
| + | svgRenderer.setClearColor(0xFFFFFF, | ||
| + | three.appendChild(renderer.domElement); | ||
| + | |||
| + | var control = new THREE.TrackballControls(camera, | ||
| + | control.zoomSpeed = 0.2; | ||
| + | control.rotateSpeed = 4; | ||
| + | |||
| + | function onWindowResize() { | ||
| + | var width = three.clientWidth; | ||
| + | var height = three.clientHeight; | ||
| + | renderer.setSize( width, height ); | ||
| + | svgRenderer.setSize( width, height ); | ||
| + | camera.aspect = width / height; | ||
| + | camera.updateProjectionMatrix(); | ||
| + | } | ||
| + | |||
| + | onWindowResize(); | ||
| + | window.addEventListener(' | ||
| + | |||
| + | // class to allow move points together with labels and spheres | ||
| + | var PMPoint = function (x,y,z) { | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | PMPoint.prototype.addLabel = function(labelsprite) { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | PMPoint.prototype.addSphere = function(spheremesh) { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | PMPoint.prototype.set = function(x, | ||
| + | | ||
| + | if (this.sprite) { | ||
| + | | ||
| } | } | ||
| - | | + | if (this.sphere) { |
| + | this.sphere.position.copy(this.vector); | ||
| + | } | ||
| + | } | ||
| + | PMPoint.prototype.radius = function() { | ||
| + | if (this.sphere) { | ||
| + | return this.sphere.geometry.parameters.radius; | ||
| + | } else { | ||
| + | return 0; | ||
| + | } | ||
| + | }; | ||
| + | // select the target node | ||
| + | var target | ||
| - | < | + | // create an observer instance |
| - | faces.vertices.push(allpoints[0].vector); | + | var observer = new MutationObserver(function(mutations) { |
| - | faces.vertices.push(allpoints[1].vector); | + | mutations.forEach(function(mutation) { |
| - | faces.vertices.push(allpoints[2].vector); | + | if (mutation.removedNodes && mutation.removedNodes.length > 0) { |
| - | faces.vertices.push(allpoints[3].vector); | + | |
| + | observer.disconnect(); | ||
| + | console.log(" | ||
| + | } | ||
| + | }); | ||
| + | }); | ||
| - | | + | // configuration of the observer: |
| + | var config = { childList: true, characterData: | ||
| + | // pass in the target node, as well as the observer options | ||
| + | while (target) { | ||
| + | if (target.className==" | ||
| + | observer.observe(target, | ||
| + | break; | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | |||
| + | // COMMON_CODE_BLOCK_END | ||
| + | |||
| + | var obj0 = new THREE.Object3D(); | ||
| + | obj0.name = " | ||
| + | obj0.userData.explodable = 1; | ||
| + | obj0.userData.points = []; | ||
| + | obj0.userData.points.push(new PMPoint(0, 0, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(2, 0, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(2, 2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(0, 2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(0, -2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(2, -2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(2, 4, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(0, 4, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(-2, 2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(-2, 0, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(4, 0, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(4, 2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(0, -4, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(2, -4, 0)); | ||
| + | |||
| + | obj0.userData.pointradii = 0.02; | ||
| + | < | ||
| + | obj0.userData.pointmaterial = new THREE.MeshBasicMaterial( { color: 0xFF0000, side: THREE.DoubleSide, | ||
| + | obj0.userData.pointlabels = [" | ||
| + | obj0.userData.edgeindices = [0, 1, 1, 2, 0, 3, 2, 3, 0, 4, 1, 5, 4, 5, 2, 6, 3, 7, 6, 7, 3, 8, 0, 9, 8, 9, 1, 10, 2, 11, 10, 11, 4, 12, 5, 13, 12, 13]; | ||
| + | < | ||
| + | obj0.userData.edgematerial = new THREE.LineBasicMaterial( { color: 0x000000, depthTest: true, linewidth: 1.5, transparent: | ||
| + | obj0.userData.facets = [[0, 1, 2, 3], [13, 5, 4, 12], [5, 1, 0, 4], [3, 2, 6, 7], [0, 3, 8, 9], [2, 1, 10, 11]]; | ||
| < | < | ||
| - | var faces_material | + | obj0.userData.facetmaterial |
| + | obj0.userData.axes = [[5,4], | ||
| + | [2,1], | ||
| + | [0,3], | ||
| + | [3,2], | ||
| + | [1,0]]; | ||
| - | | + | obj0.userData.angles |
| - | faces_material.transparent = true; | + | 1.5707963267949, |
| + | 1.5707963267949, | ||
| + | 1.5707963267949, | ||
| + | 1.5707963267949]; | ||
| - | < | + | obj0.userData.subtrees = [[12,13], |
| - | faces.faces.push(new THREE.Face3(2, 3, 1, undefined, undefined, 0)); | + | [10,11], |
| + | [8,9], | ||
| + | [6,7], | ||
| + | [4,5,12,13]]; | ||
| - | faces.faces.push(new THREE.Face3(0, 3, 2, undefined, undefined, 0)); | + | obj0.userData.polytoperoot = [[-1,-1,-1], |
| + | [-1,0,0], | ||
| + | [0,2,0]]; | ||
| - | faces.faces.push(new THREE.Face3(1, 3, 0, undefined, undefined, 0)); | + | obj0.userData.oldscale = 0; |
| + | foldables.push(obj0); | ||
| + | init_object(obj0); | ||
| + | scene.add(obj0); | ||
| + | // COMMON_CODE_BLOCK_BEGIN | ||
| + | function textSpriteMaterial(message, parameters) { | ||
| + | if ( parameters === undefined ) parameters = {}; | ||
| + | var fontface = " | ||
| + | var fontsize = parameters.hasOwnProperty(" | ||
| + | fontsize = fontsize*10; | ||
| + | var lines = message.split(' | ||
| + | var size = 512; | ||
| + | for(var i = 0; i< | ||
| + | var tmp = lines[i].length; | ||
| + | while(tmp*fontsize > size){ | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | |||
| + | var canvas = document.createElement(' | ||
| + | canvas.width = size; | ||
| + | canvas.height = size; | ||
| + | var context = canvas.getContext(' | ||
| + | context.fillStyle = " | ||
| + | context.fill(); | ||
| + | context.font = fontsize + "px " + fontface; | ||
| + | |||
| + | // text color | ||
| + | context.fillStyle = "rgba(0, 0, 0, 1.0)"; | ||
| + | | ||
| + | context.fillText(lines[i], | ||
| + | } | ||
| + | |||
| + | // canvas contents will be used for a texture | ||
| + | var texture = new THREE.Texture(canvas); | ||
| + | texture.needsUpdate = true; | ||
| + | |||
| + | var spriteMaterial = new THREE.SpriteMaterial({map: | ||
| + | return spriteMaterial; | ||
| + | } | ||
| - | | ||
| + | // ---------------------- INITIALIZING OBJECTS-------------------------------------- | ||
| + | // --------------------------------------------------------------------------------- | ||
| - | faces.computeFaceNormals(); | + | function init_object(obj) { |
| - | faces.computeVertexNormals(); | + | if (obj.userData.hasOwnProperty(" |
| + | init_points(obj); | ||
| + | | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_pointlabels(obj); | ||
| + | modelContains.pointlabels = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_lines(obj); | ||
| + | modelContains.lines = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_edgelabels(obj); | ||
| + | modelContains.edgelabels = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_arrowheads(obj); | ||
| + | modelContains.arrowheads = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_faces(obj); | ||
| + | modelContains.faces = true; | ||
| + | } | ||
| + | } | ||
| - | | + | function init_points(obj) { |
| - | | + | var pointgroup = new THREE.Group(); |
| + | | ||
| + | var points = obj.userData.points; | ||
| + | var radii = obj.userData.pointradii; | ||
| + | var materials = obj.userData.pointmaterial; | ||
| + | var geometry, | ||
| + | if (!Array.isArray(radii)) { | ||
| + | geometry = new THREE.SphereBufferGeometry(radii); | ||
| + | } | ||
| + | if (!Array.isArray(materials)) { | ||
| + | material = materials; | ||
| + | } | ||
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | if (Array.isArray(radii)) { | ||
| + | if (radii[i] == 0) { | ||
| + | continue; | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | if (Array.isArray(materials)) { | ||
| + | | ||
| + | } | ||
| + | | ||
| + | point.addSphere(sphere); | ||
| + | pointgroup.add(sphere); | ||
| + | } | ||
| + | | ||
| + | } | ||
| - | < | + | function init_pointlabels(obj) { |
| - | | + | |
| + | var labels = obj.userData.pointlabels; | ||
| + | var pointlabels | ||
| + | | ||
| + | if (Array.isArray(labels)) | ||
| + | for (var i=0; i<points.length; i++) { | ||
| + | var point = points[i]; | ||
| + | var spriteMaterial = textSpriteMaterial( labels[i] ); | ||
| + | var sprite = new THREE.Sprite(spriteMaterial); | ||
| + | | ||
| + | | ||
| + | | ||
| + | } else { | ||
| + | var spriteMaterial = textSpriteMaterial( labels | ||
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | var sprite = new THREE.Sprite(spriteMaterial); | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | } | ||
| - | | + | function init_lines(obj) { |
| - | line_material.transparent | + | var edgeindices = obj.userData.edgeindices; |
| + | var points | ||
| + | var materials = obj.userData.edgematerial; | ||
| + | var geometry = new THREE.BufferGeometry(); | ||
| + | var bufarr = new Float32Array( obj.userData.edgeindices.length * 3 ); | ||
| + | var bufattr | ||
| + | var geometry = new THREE.BufferGeometry(); | ||
| + | | ||
| + | if (Array.isArray(materials)) { | ||
| + | for (var i=0; i< | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | var lines = new THREE.LineSegments(geometry, | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| - | < | + | function init_edgelabels(obj) { |
| - | | + | var points = obj.userData.points; |
| - | line.vertices.push(allpoints[2].vector); | + | var edgeindices = obj.userData.edgeindices; |
| - | line.vertices.push(allpoints[3].vector); | + | var labels = obj.userData.edgelabels; |
| - | line.vertices.push(allpoints[1].vector); | + | |
| - | line.vertices.push(allpoints[2].vector); | + | edgelabels.name = " |
| - | | + | if (Array.isArray(labels)) { |
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | var spriteMaterial = textSpriteMaterial( labels[i] ); | ||
| + | var sprite = new THREE.Sprite(spriteMaterial); | ||
| + | sprite.position.copy(new THREE.Vector3().addVectors(points[edgeindices[i]].vector, | ||
| + | edgelabels.add(sprite); | ||
| + | } | ||
| + | } else { | ||
| + | var spriteMaterial = textSpriteMaterial( labels ); | ||
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | var sprite = new THREE.Sprite(spriteMaterial); | ||
| + | sprite.position.copy(new THREE.Vector3().addVectors(points[edgeindices[i]].vector, | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | } | ||
| - | | + | function init_arrowheads(obj) { |
| - | line.vertices.push(allpoints[0].vector); | + | |
| - | line.vertices.push(allpoints[3].vector); | + | |
| - | line.vertices.push(allpoints[2].vector); | + | var arrowstyle = obj.userData.arrowstyle; |
| - | line.vertices.push(allpoints[0].vector); | + | var edgeindices = obj.userData.edgeindices; |
| - | obj.add(new THREE.Line(line, line_material)); | + | var edgematerials = obj.userData.edgematerial; |
| + | var points = obj.userData.points; | ||
| + | var material; | ||
| + | if (!Array.isArray(edgematerials)) { | ||
| + | material = new THREE.MeshBasicMaterial( {color: edgematerials.color} | ||
| + | } | ||
| - | var line = new THREE.Geometry(); | + | for (var i=0; i< |
| - | line.vertices.push(allpoints[1].vector); | + | var start = points[edgeindices[i]]; |
| - | line.vertices.push(allpoints[3].vector); | + | var end = points[edgeindices[i+1]]; |
| - | line.vertices.push(allpoints[0].vector); | + | var dist = start.vector.distanceTo( end.vector ) - start.radius() - end.radius(); |
| - | line.vertices.push(allpoints[1].vector); | + | if (dist <= 0) { |
| - | | + | continue; |
| + | } | ||
| + | var dir = new THREE.Vector3().subVectors(end.vector, | ||
| + | dir.normalize(); | ||
| + | var axis = new THREE.Vector3().set(dir.z, | ||
| + | axis.normalize(); | ||
| + | var radians = Math.acos( dir.y ); | ||
| + | var radius = dist/25; | ||
| + | var height = dist/5; | ||
| + | var geometry = new THREE.ConeBufferGeometry(radius, | ||
| + | var position = new THREE.Vector3().addVectors(start.vector, | ||
| + | if (Array.isArray(edgematerials)) { | ||
| + | material = new THREE.MeshBasicMaterial( {color: edgematerials[i].color} | ||
| + | } | ||
| + | var cone = new THREE.Mesh( geometry, material ); | ||
| + | cone.quaternion.setFromAxisAngle(axis, | ||
| + | cone.position.copy(position);; | ||
| + | arrowheads.add(cone); | ||
| + | } | ||
| + | obj.add(arrowheads); | ||
| + | } | ||
| + | |||
| + | function init_faces(obj) { | ||
| + | var points = obj.userData.points; | ||
| + | var facets = obj.userData.facets; | ||
| + | | ||
| + | for (var i=0; i< | ||
| + | facet = facets[i]; | ||
| + | for (var t=0; t< | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | var bufarr = new Float32Array( obj.userData.triangleindices.length * 3 ); | ||
| + | var bufattr = new THREE.Float32BufferAttribute(bufarr, | ||
| + | |||
| + | var materials = obj.userData.facetmaterial; | ||
| + | var geometry = new THREE.BufferGeometry(); | ||
| + | | ||
| + | if (Array.isArray(materials)) { | ||
| + | var tricount = 0; | ||
| + | var facet; | ||
| + | for (var i=0; i< | ||
| + | facet = facets[i]; | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | var mesh = new THREE.Mesh(geometry, | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | // // | ||
| + | |||
| + | |||
| + | function updateFacesPosition(obj) { | ||
| + | var points = obj.userData.points; | ||
| + | var indices = obj.userData.triangleindices; | ||
| + | var faces = obj.getObjectByName(" | ||
| + | var ba = faces.geometry.getAttribute(" | ||
| + | for (var i=0; i< | ||
| + | ba.setXYZ(i, points[indices[i]].vector.x, | ||
| + | } | ||
| + | | ||
| + | |||
| + | } | ||
| + | |||
| + | function updateEdgesPosition(obj) { | ||
| + | var points = obj.userData.points; | ||
| + | var indices = obj.userData.edgeindices; | ||
| + | var lines = obj.getObjectByName(" | ||
| + | var ba = lines.geometry.getAttribute(" | ||
| + | for (var i=0; i< | ||
| + | ba.setXYZ(i, | ||
| + | } | ||
| + | | ||
| + | } | ||
| - | var line = new THREE.Geometry(); | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | // COMMON_CODE_BLOCK_BEGIN | ||
| var xRotationEnabled = false; | var xRotationEnabled = false; | ||
| var yRotationEnabled = false; | var yRotationEnabled = false; | ||
| Line 462: | Line 1892: | ||
| var renderId; | var renderId; | ||
| - | var render = function () { | + | var render = function () { |
| - | renderId = requestAnimationFrame(render); | + | renderId = requestAnimationFrame(render); |
| - | // comment in for automatic explosion | + | // comment in for automatic explosion |
| - | // explode(updateFactor()); | + | // |
| - | var phi = 0.02 * rotationSpeedFactor; | + | |
| - | if (xRotationEnabled){ | + | |
| - | scene.rotation.x += phi; | + | scene.rotation.x += phi; |
| - | } | + | } |
| - | if(yRotationEnabled){ | + | if (yRotationEnabled) { |
| - | scene.rotation.y += phi; | + | scene.rotation.y += phi; |
| - | } | + | } |
| - | if(zRotationEnabled){ | + | if (zRotationEnabled) { |
| - | scene.rotation.z += phi; | + | scene.rotation.z += phi; |
| - | } | + | } |
| - | controls.update(); | + | control.update(); |
| - | renderer.render(scene, | + | renderer.render(scene, |
| - | }; | + | }; |
| + | if ( THREE.WEBGL.isWebGLAvailable() ) { | ||
| render(); | render(); | ||
| + | } else { | ||
| + | var warning = WEBGL.getWebGLErrorMessage(); | ||
| + | three.appendChild( warning ); | ||
| + | } | ||
| + | | ||
| + | function changeTransparency() { | ||
| + | var opacity = 1-Number(event.currentTarget.value); | ||
| + | for (var i=0; i< | ||
| + | child = scene.children[i]; | ||
| + | if ( child.userData.hasOwnProperty(" | ||
| + | if (Array.isArray(child.userData.facetmaterial)) { | ||
| + | for (var j=0; j< | ||
| + | child.userData.facetmaterial[j].opacity = opacity; | ||
| + | } | ||
| + | } else { | ||
| + | child.userData.facetmaterial.opacity = opacity; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| - | function | + | function |
| - | centroid | + | |
| - | geom.vertices.forEach(function(v) { | + | } |
| - | centroid.add(v); | + | |
| - | }); | + | |
| - | centroid.divideScalar(geom.vertices.length); | + | |
| - | return centroid; | + | |
| - | } | + | |
| - | function | + | function |
| - | var opacity | + | |
| - | for (var i=0; i< | + | } |
| - | for (var j=0; j< | + | |
| - | if (all_objects[i].children[j].material.type == " | + | |
| - | for (var k=0; k< | + | |
| - | all_objects[i].children[j].material.materials[k].opacity = opacity; | + | |
| - | all_objects[i].children[j].material.materials[k].depthWrite = opacity < 0.5 ? false : true; | + | |
| - | all_objects[i].children[j].material.materials[k].depthTest = opacity < 0.5 ? false : true; | + | |
| - | } | + | |
| - | } else if (all_objects[i].children[j].material.transparent && | + | |
| - | | + | |
| - | | + | |
| - | all_objects[i].children[j].material.opacity = opacity; | + | |
| - | all_objects[i].children[j].material.depthWrite = opacity < 0.5 ? false : true; | + | |
| - | all_objects[i].children[j].material.depthTest = opacity < 0.5 ? false : true; | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | function | + | function |
| - | xRotationEnabled | + | |
| - | } | + | } |
| - | function changeRotationY(event){ | ||
| - | yRotationEnabled = event.currentTarget.checked; | ||
| - | } | ||
| - | function | + | function |
| - | zRotationEnabled | + | |
| - | } | + | } |
| + | function resetScene(){ | ||
| + | scene.rotation.set(0, | ||
| + | camera.position.set(0, | ||
| + | camera.up.set(0, | ||
| + | } | ||
| - | function | + | function |
| - | rotationSpeedFactor | + | |
| - | } | + | document.getElementById(' |
| + | document.getElementById(' | ||
| + | settingsShown = true; | ||
| + | } | ||
| - | function | + | function |
| - | scene.rotation.set(0,0,0); | + | |
| - | camera.position.set(0,0,5); | + | |
| - | camera.up.set(0,1,0); | + | |
| - | } | + | settingsShown = false; |
| + | } | ||
| - | function showSettings(event){ | ||
| - | event.currentTarget.style.display = ' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | settingsShown = true; | ||
| - | } | ||
| - | function hideSettings(event){ | ||
| - | event.currentTarget.style.display = ' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | settingsShown = false; | ||
| - | } | ||
| + | var pos = 150* Math.PI; | ||
| + | function updateFactor() { | ||
| + | pos++; | ||
| + | return Math.sin(.01*pos)+1; | ||
| + | } | ||
| - | var pos = 150* Math.PI; | + | // ------------------------ FOLDING ------------------------------------------------ |
| + | // --------------------------------------------------------------------------------- | ||
| + | // rotate point p around axis defined by points p1 and p2 by given angle | ||
| + | function rotate(p, p1, p2, angle ){ | ||
| + | angle = -angle; | ||
| + | var x = p.x, y = p.y, z = p.z, | ||
| + | a = p1.x, b = p1.y, c = p1.z, | ||
| + | u = p2.x-p1.x, v = p2.y-p1.y, w = p2.z-p1.z; | ||
| + | var result = []; | ||
| + | var L = u*u + v*v + w*w; | ||
| + | var sqrt = Math.sqrt; | ||
| + | var cos = Math.cos; | ||
| + | var sin = Math.sin; | ||
| - | function updateFactor() { | + | |
| - | pos++; | + | result[1] = ((b*(u*u+w*w)-v*(a*u+c*w-u*x-v*y-w*z))*(1-cos(angle))+L*y*cos(angle)+sqrt(L)*(c*u-a*w+w*x-u*z)*sin(angle))/ |
| - | return Math.sin(.01*pos)+1; | + | result[2] = ((c*(u*u+v*v)-w*(a*u+b*v-u*x-v*y-w*z))*(1-cos(angle))+L*z*cos(angle)+sqrt(L)*(-b*u+a*v-v*x+u*y)*sin(angle))/ |
| - | } | + | |
| - | function makelabel(message, | + | |
| - | var spritey = textSprite( message, params ); | + | } |
| - | spritey.position.set(x, | + | |
| - | obj.add(spritey); | + | |
| - | } | + | |
| - | function | + | var fold = function(event){ |
| - | { | + | var obj = foldables[Number(event.currentTarget.name)]; |
| - | if ( parameters === undefined | + | var foldvalue |
| + | var scale = foldvalue - obj.userData.oldscale; | ||
| - | var fontface | + | for (var j=0; j< |
| + | rotateVertices(obj, | ||
| + | } | ||
| + | update(obj); | ||
| + | obj.userData.oldscale += scale; | ||
| + | lookAtBarycenter(obj); | ||
| + | } | ||
| - | var fontsize = parameters.hasOwnProperty(" | + | function lookAtBarycenter(obj){ |
| - | parameters[" | + | |
| - | fontsize | + | } |
| - | var canvas | + | function barycenter(obj) { |
| - | var size = 1024; | + | var center |
| - | canvas.width | + | |
| - | canvas.height = size; | + | for (var i=0; i<points.length; i++){ |
| - | var context = canvas.getContext(' | + | |
| - | context.font = fontsize + "px " + fontface; | + | } |
| + | | ||
| + | | ||
| + | } | ||
| - | // text color | + | function rotateVertices(obj, |
| - | context.fillStyle | + | var axes = obj.userData.axes; |
| + | var subtrees | ||
| + | var points = obj.userData.points; | ||
| + | var angles = obj.userData.angles; | ||
| + | | ||
| + | for (var j=0; j< | ||
| + | var rotP = rotate(points[subtrees[edge][j]].vector, points[axes[edge][0]].vector,points[axes[edge][1]].vector, scale * (Math.PI - angles[edge])); | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | } | ||
| - | context.fillText(message, size/2, size/2); | + | function update(obj) { |
| + | | ||
| + | | ||
| + | } | ||
| - | // canvas contents will be used for a texture | + | if (foldables.length) { |
| - | var texture | + | var settings = document.getElementById(' |
| - | texture.needsUpdate | + | var foldDiv = document.createElement(' |
| + | foldDiv.id = ' | ||
| + | var title = document.createElement(' | ||
| + | title.innerHTML = ' | ||
| + | foldDiv.appendChild(title); | ||
| + | foldDiv.className = ' | ||
| + | | ||
| + | var range = document.createElement(' | ||
| + | range.type = ' | ||
| + | range.min = 0; | ||
| + | range.max = 1; | ||
| + | range.value = 0; | ||
| + | range.step = 0.001; | ||
| + | range.name = String(i); | ||
| + | range.oninput = fold; | ||
| + | foldDiv.appendChild(range); | ||
| + | } | ||
| + | lookAtBarycenter(foldables[0]); | ||
| + | settings.insertBefore(foldDiv, | ||
| + | } | ||
| - | var spriteMaterial = new THREE.SpriteMaterial( | + | |
| - | {map: texture, useScreenCoordinates: | + | // ---------------------- EXPLOSION ------------------------------------------------ |
| - | var sprite = new THREE.Sprite(spriteMaterial); | + | // --------------------------------------------------------------------------------- |
| - | return sprite; | + | |
| - | } | + | |
| - | function takeSvgScreenshot(){ | + | if (explodableModel) { |
| - | if (labelsShown){ | + | for (var i=0; i< |
| - | hideLabels(); | + | obj = scene.children[i]; |
| - | } | + | |
| - | svgRenderer.render(scene, | + | |
| - | svgElement = XMLS.serializeToString(svgRenderer.domElement); | + | } |
| - | + | } | |
| - | if (labelsShown){ | + | document.getElementById(' |
| - | displayLabels(); | + | |
| - | } | + | |
| + | } | ||
| - | if (document.getElementById(' | + | function computeCentroid(obj) { |
| - | //show in new tab | + | |
| - | var myWindow | + | obj.userData.points.forEach(function(pmpoint) |
| - | myWindow.document.body.innerHTML = svgElement; | + | |
| - | } else{ | + | }); |
| - | // download svg file | + | centroid.divideScalar(obj.userData.points.length); |
| - | download(" | + | |
| - | } | + | } |
| - | } | + | |
| - | + | ||
| - | function | + | function |
| - | var nr = Number(event.currentTarget.name); | + | for (var i=0; i<scene.children.length; i++) { |
| - | all_objects[nr].visible | + | var obj = scene.children[i]; |
| - | } | + | if (obj.userData.hasOwnProperty(" |
| + | var c = obj.userData.centroid; | ||
| + | obj.position.set(c.x*factor, | ||
| + | } | ||
| + | } | ||
| + | } | ||
| - | function | + | function |
| - | for (var j=0; j< | + | |
| - | var child = obj.children[j]; | + | |
| - | if (child.material===undefined && child) { | + | } |
| - | displayOrHideOptionsRecursive( child ); | + | |
| - | } else { | + | |
| - | if (child.material.type == " | + | |
| - | for (var k=0; k< | + | |
| - | if | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | child.material.materials[k].opacity; | + | |
| - | return; | + | |
| - | } | + | |
| - | } | + | |
| - | } else if ( child.material.transparent && | + | |
| - | child.material.type == " | + | |
| - | child.geometry.type == " | + | |
| - | document.getElementById(' | + | |
| - | return; | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | function | + | function |
| - | for (var i=0; i< | + | |
| - | var obj = all_objects[i]; | + | } |
| - | displayOrHideOptionsRecursive( obj ); | + | |
| - | } | + | |
| - | } | + | |
| - | displayOrHideOptions() | + | function triggerAutomaticExplode(event){ |
| + | if (event.currentTarget.checked){ | ||
| + | startExploding(); | ||
| + | } else { | ||
| + | clearIntervals(); | ||
| + | } | ||
| + | } | ||
| + | function startExploding(){ | ||
| + | intervals.push(setInterval(explodingInterval, | ||
| + | } | ||
| + | function explodingInterval(){ | ||
| + | explodeScale += explodingSpeed; | ||
| + | if (explodeScale <= 6){ | ||
| + | explode(explodeScale); | ||
| + | } | ||
| + | else{ | ||
| + | explode(6); | ||
| + | explodeScale = 6; | ||
| + | clearIntervals(); | ||
| + | timeouts.push(setTimeout(startUnexploding, | ||
| + | } | ||
| + | document.getElementById(' | ||
| + | } | ||
| - | // ---------------------- EXPLOSION ------------------------------------------------ | ||
| - | // --------------------------------------------------------------------------------- | ||
| - | function | + | function |
| - | var obj, c; | + | |
| - | var c0 = centroids[0]; | + | } |
| - | for (var i = 0; i< | + | |
| - | c = centroids[i]; | + | |
| - | obj = all_objects[all_objects.length - centroids.length + i]; | + | |
| - | obj.position.set(c.x*factor, c.y*factor, c.z*factor); | + | |
| - | } | + | |
| - | } | + | |
| - | function | + | function |
| - | explodeScale = Number(event.currentTarget.value); | + | explodeScale |
| - | explode(explodeScale); | + | if (explodeScale >= 0){ |
| - | } | + | explode(explodeScale); |
| + | } | ||
| + | else { | ||
| + | | ||
| + | | ||
| + | clearIntervals(); | ||
| + | timeouts.push(setTimeout(startExploding, | ||
| + | } | ||
| + | document.getElementById(' | ||
| + | } | ||
| - | function | + | function |
| - | explodingSpeed = Number(event.currentTarget.value); | + | |
| - | } | + | clearInterval(interval); |
| + | }); | ||
| + | intervals = []; | ||
| + | timeouts.forEach(function(timeout){ | ||
| + | clearTimeout(timeout); | ||
| + | }); | ||
| + | timeouts = []; | ||
| + | } | ||
| - | function triggerAutomaticExplode(event){ | + | // ---------------------- DISPLAY -------------------------------------------------- |
| - | if (event.currentTarget.checked){ | + | // --------------------------------------------------------------------------------- |
| - | startExploding(); | + | |
| - | } else { | + | |
| - | clearIntervals(); | + | |
| - | } | + | |
| - | } | + | |
| - | function startExploding(){ | + | const objectTypeInnerHTMLs = { points: " |
| - | intervals.push(setInterval(explodingInterval, 25)); | + | const objectTypeVisible = {}; |
| - | } | + | Object.assign(objectTypeVisible,modelContains); |
| + | const sortedObjectTypeKeys = Object.keys(objectTypeInnerHTMLs).sort(); | ||
| + | const shownObjectTypesList = document.getElementById(' | ||
| + | function setVisibility(bool, | ||
| + | for (var i=0; i< | ||
| + | var obj = scene.children[i].getObjectByName(objname); | ||
| + | if (obj) { | ||
| + | obj.visible = bool; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| - | function | + | function |
| - | explodeScale += explodingSpeed; | + | var name = event.currentTarget.name; |
| - | if (explodeScale <= 6){ | + | var checked |
| - | explode(explodeScale); | + | |
| - | } | + | |
| - | else{ | + | } |
| - | explode(6); | + | |
| - | explodeScale | + | |
| - | clearIntervals(); | + | |
| - | timeouts.push(setTimeout(startUnexploding, 3000)); | + | |
| - | } | + | |
| - | document.getElementById(' | + | |
| - | } | + | |
| + | for (var i=0; i< | ||
| + | var key = sortedObjectTypeKeys[i]; | ||
| + | if (modelContains[key]) { | ||
| + | var objTypeNode = document.createElement(' | ||
| + | objTypeNode.innerHTML = objectTypeInnerHTMLs[key] + '< | ||
| + | var checkbox = document.createElement(' | ||
| + | checkbox.type = ' | ||
| + | checkbox.checked = true; | ||
| + | checkbox.name = key; | ||
| + | checkbox.onchange = toggleObjectTypeVisibility; | ||
| + | shownObjectTypesList.appendChild(checkbox); | ||
| + | shownObjectTypesList.appendChild(objTypeNode); | ||
| + | } | ||
| + | } | ||
| - | function startUnexploding(){ | + | // ------------------------------------------------------ |
| - | intervals.push(setInterval(unexplodingInterval, | + | |
| - | } | + | |
| - | function | + | function |
| - | explodeScale -= explodingSpeed; | + | var nr = Number(event.currentTarget.name); |
| - | if (explodeScale >= 0){ | + | scene.children[nr].visible |
| - | explode(explodeScale); | + | } |
| - | } | + | |
| - | else { | + | |
| - | explode(0); | + | |
| - | explodeScale = 0; | + | |
| - | clearIntervals(); | + | |
| - | timeouts.push(setTimeout(startExploding, | + | |
| - | } | + | |
| - | document.getElementById(' | + | |
| - | } | + | |
| - | function clearIntervals(){ | + | // append checkboxes for displaying or hiding objects |
| - | intervals.forEach(function(interval){ | + | var shownObjectsList = document.getElementById(' |
| - | clearInterval(interval); | + | for (var i=0; i< |
| - | }); | + | |
| - | intervals | + | var objNode = document.createElement(' |
| - | timeouts.forEach(function(timeout){ | + | |
| - | clearTimeout(timeout); | + | var checkbox = document.createElement(' |
| - | }); | + | |
| - | timeouts | + | checkbox.checked = true; |
| - | } | + | checkbox.name = String(i); |
| + | | ||
| + | shownObjectsList.appendChild(checkbox); | ||
| + | shownObjectsList.appendChild(objNode); | ||
| + | } | ||
| - | + | // ---------------------- SVG ------------------------------------------------------ | |
| + | // --------------------------------------------------------------------------------- | ||
| - | // append checkboxes for displaying or hiding objects | + | function takeSvgScreenshot() { |
| - | var shownObjectsList = document.getElementById(' | + | |
| - | for (var i=0; i< | + | |
| - | var objNode = document.createElement(' | + | } |
| - | objNode.innerHTML = objectnames[i] + '< | + | if (objectTypeVisible[" |
| - | var checkbox = document.createElement(' | + | |
| - | checkbox.type = ' | + | } |
| - | checkbox.checked = true; | + | |
| - | checkbox.name | + | |
| - | checkbox.onchange = showOrHideObject; | + | |
| - | shownObjectsList.appendChild(checkbox); | + | |
| - | shownObjectsList.appendChild(objNode); | + | setVisibility(true," |
| - | } | + | } |
| + | if (objectTypeVisible[" | ||
| + | setVisibility(true," | ||
| + | } | ||
| - | function displayLabels(){ | + | if (document.getElementById(' |
| - | for (var i=0; i< | + | // |
| - | for (var j=0; j< | + | |
| - | var child = all_objects[i].children[j]; | + | |
| - | if (child.type == ' | + | } else{ |
| - | child.visible = true; | + | // download svg file |
| - | } | + | |
| - | } | + | } |
| - | } | + | } |
| - | } | + | |
| - | function | + | function |
| - | for (var i=0; i< | + | var element |
| - | for (var j=0; j< | + | |
| - | var child = all_objects[i].children[j]; | + | |
| - | if | + | |
| - | child.visible = false; | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | function displayOrHideLabels(event){ | + | element.style.display |
| - | if (event.currentTarget.checked){ | + | |
| - | displayLabels(); | + | |
| - | labelsShown | + | |
| - | } else { | + | |
| - | hideLabels(); | + | |
| - | labelsShown = false; | + | |
| - | } | + | |
| - | } | + | |
| - | function download(filename, | + | element.click(); |
| - | var element = document.createElement(' | + | |
| - | element.setAttribute(' | + | |
| - | element.setAttribute(' | + | |
| - | element.style.display = ' | + | document.body.removeChild(element); |
| - | document.body.appendChild(element); | + | } |
| - | element.click(); | ||
| - | | + | document.getElementById(' |
| - | } | + | document.getElementById(' |
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| - | var tempobj; | ||
| - | tempobj = document.getElementById(' | ||
| - | if (tempobj) { | ||
| - | | ||
| - | | ||
| - | | ||
| - | } | ||
| - | tempobj = document.getElementById(' | ||
| - | if (tempobj) { | ||
| - | | ||
| - | } | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | document.getElementById(' | ||
| - | |||
| - | |||
| // ------------------ SHORTCUTS -------------------------------------------- | // ------------------ SHORTCUTS -------------------------------------------- | ||
| Line 1062: | Line 2521: | ||
| var event = new Event(' | var event = new Event(' | ||
| if (settingsShown){ | if (settingsShown){ | ||
| - | document.getElementById(' | + | document.getElementById(' |
| - | } else{ | + | } else { |
| - | document.getElementById(' | + | document.getElementById(' |
| } | } | ||
| }); | }); | ||
| - | if (foldable) moveToBaryCenter(); | ||
| + | // COMMON_CODE_BLOCK_END | ||
| });}); | });}); | ||
| - | // COMMON_CODE_BLOCK_END | + | </script> |
| - | </script> | + | </body> |
| + | </html> | ||
| + | </HTML> | ||
| - | </ | ||
| - | </ | ||
| - | </ | ||