Circle-Packings/.ipynb_checkpoints/Homework-checkpoint.ipynb

558 lines
3.4 MiB
Text
Raw Normal View History

2021-03-12 18:07:17 -08:00
{
"cells": [
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"<iframe srcdoc=\"<!DOCTYPE html>\n",
"<html>\n",
"<head>\n",
"<title></title>\n",
"<meta charset=&quot;utf-8&quot;>\n",
"<meta name=viewport content=&quot;width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0&quot;>\n",
"<style>\n",
"\n",
" body { margin: 0px; overflow: hidden; }\n",
"\n",
" #menu-container { position: absolute; bottom: 30px; right: 40px; cursor: default; }\n",
"\n",
" #menu-message { position: absolute; bottom: 0px; right: 0px; white-space: nowrap;\n",
" display: none; background-color: #F5F5F5; padding: 10px; }\n",
"\n",
" #menu-content { position: absolute; bottom: 0px; right: 0px;\n",
" display: none; background-color: #F5F5F5; border-bottom: 1px solid black;\n",
" border-right: 1px solid black; border-left: 1px solid black; }\n",
"\n",
" #menu-content div { border-top: 1px solid black; padding: 10px; white-space: nowrap; }\n",
"\n",
" #menu-content div:hover { background-color: #FEFEFE;; }\n",
"\n",
"</style>\n",
"\n",
"</head>\n",
"\n",
"<body>\n",
"\n",
"<script src=&quot;/nbextensions/threejs/build/three.min.js&quot;></script>\n",
"<script>\n",
" if ( !window.THREE ) document.write(' \\\n",
"<script src=&quot;https://cdn.jsdelivr.net/gh/sagemath/threejs-sage@r124/build/three.min.js&quot;><\\/script> \\\n",
" ');\n",
"</script>\n",
" \n",
"<script>\n",
"\n",
" var scene = new THREE.Scene();\n",
"\n",
" var renderer = new THREE.WebGLRenderer( { antialias: true, preserveDrawingBuffer: true } );\n",
" renderer.setPixelRatio( window.devicePixelRatio );\n",
" renderer.setSize( window.innerWidth, window.innerHeight );\n",
" renderer.setClearColor( 0xffffff, 1 );\n",
" document.body.appendChild( renderer.domElement );\n",
"\n",
" var options = {&quot;animate&quot;: false, &quot;animationControls&quot;: true, &quot;aspectRatio&quot;: [1.0, 1.0, 1.0], &quot;autoPlay&quot;: true, &quot;axes&quot;: false, &quot;axesLabels&quot;: [&quot;x&quot;, &quot;y&quot;, &quot;z&quot;], &quot;decimals&quot;: 2, &quot;delay&quot;: 20, &quot;frame&quot;: true, &quot;loop&quot;: true, &quot;projection&quot;: &quot;perspective&quot;, &quot;viewpoint&quot;: false};\n",
" var animate = options.animate;\n",
"\n",
" var b = [{&quot;x&quot;:-3.0, &quot;y&quot;:-3.0, &quot;z&quot;:-3.0}, {&quot;x&quot;:3.0, &quot;y&quot;:3.0, &quot;z&quot;:3.0}]; // bounds\n",
"\n",
" if ( b[0].x === b[1].x ) {\n",
" b[0].x -= 1;\n",
" b[1].x += 1;\n",
" }\n",
" if ( b[0].y === b[1].y ) {\n",
" b[0].y -= 1;\n",
" b[1].y += 1;\n",
" }\n",
" if ( b[0].z === b[1].z ) {\n",
" b[0].z -= 1;\n",
" b[1].z += 1;\n",
" }\n",
"\n",
" var rRange = Math.sqrt( Math.pow( b[1].x - b[0].x, 2 )\n",
" + Math.pow( b[1].y - b[0].y, 2 ) );\n",
" var xRange = b[1].x - b[0].x;\n",
" var yRange = b[1].y - b[0].y;\n",
" var zRange = b[1].z - b[0].z;\n",
"\n",
" var ar = options.aspectRatio;\n",
" var a = [ ar[0], ar[1], ar[2] ]; // aspect multipliers\n",
" var autoAspect = 2.5;\n",
" if ( zRange > autoAspect * rRange && a[2] === 1 ) a[2] = autoAspect * rRange / zRange;\n",
"\n",
" // Distance from (xMid,yMid,zMid) to any corner of the bounding box, after applying aspectRatio\n",
" var midToCorner = Math.sqrt( a[0]*a[0]*xRange*xRange + a[1]*a[1]*yRange*yRange + a[2]*a[2]*zRange*zRange ) / 2;\n",
"\n",
" var xMid = ( b[0].x + b[1].x ) / 2;\n",
" var yMid = ( b[0].y + b[1].y ) / 2;\n",
" var zMid = ( b[0].z + b[1].z ) / 2;\n",
"\n",
" var box = new THREE.Geometry();\n",
" box.vertices.push( new THREE.Vector3( a[0]*b[0].x, a[1]*b[0].y, a[2]*b[0].z ) );\n",
" box.vertices.push( new THREE.Vector3( a[0]*b[1].x, a[1]*b[1].y, a[2]*b[1].z ) );\n",
" var boxMesh = new THREE.Line( box );\n",
" if ( options.frame ) scene.add( new THREE.BoxHelper( boxMesh, 'black' ) );\n",
"\n",
" if ( options.axesLabels ) {\n",
"\n",
" var d = options.decimals; // decimals\n",
" var offsetRatio = 0.1;\n",
" var al = options.axesLabels;\n",
"\n",
" var offset = offsetRatio * a[1]*( b[1].y - b[0].y );\n",
" var xm = xMid.toFixed(d);\n",
" if ( /^-0.?0*$/.test(xm) ) xm = xm.substr(1);\n",
" addLabel( al[0] + '=' + xm, a[0]*xMid, a[1]*b[1].y+offset, a[2]*b[0].z );\n",
" addLabel( ( b[0].x ).toFixed(d), a[0]*b[0].x, a[1]*b[1].y+offset, a[2]*b[0].z );\n",
" addLabel( ( b[1].x ).toFixed(d), a[0]*b[1].x, a[1]*b[1].y+offset, a[2]*b[0].z );\n",
"\n",
" var offset = offsetRatio * a[0]*( b[1].x - b[0].x );\n",
" var ym = yMid.toFixed(d);\n",
" if ( /^-0.?0*$/.test(ym) ) ym = ym.substr(1);\n",
" addLabel( al[1] + '=' + ym, a[0]*b[1].x+offset, a[1]*yMid, a[2]*b[0].z );\n",
" addLabel( ( b[0].y ).toFixed(d), a[0]*b[1].x+offset, a[1]*b[0].y, a[2]*b[0].z );\n",
" addLabel( ( b[1].y ).toFixed(d), a[0]*b[1].x+offset, a[1]*b[1].y, a[2]*b[0].z );\n",
"\n",
" var offset = offsetRatio * a[1]*( b[1].y - b[0].y );\n",
" var zm = zMid.toFixed(d);\n",
" if ( /^-0.?0*$/.test(zm) ) zm = zm.substr(1);\n",
" addLabel( al[2] + '=' + zm, a[0]*b[1].x, a[1]*b[0].y-offset, a[2]*zMid );\n",
" addLabel( ( b[0].z ).toFixed(d), a[0]*b[1].x, a[1]*b[0].y-offset, a[2]*b[0].z );\n",
" addLabel( ( b[1].z ).toFixed(d), a[0]*b[1].x, a[1]*b[0].y-offset, a[2]*b[1].z );\n",
"\n",
" }\n",
"\n",
" function addLabel( text, x, y, z, color='black', fontSize=14, fontFamily='monospace',\n",
" fontStyle='normal', fontWeight='normal', opacity=1 ) {\n",
"\n",
" var canvas = document.createElement( 'canvas' );\n",
" var context = canvas.getContext( '2d' );\n",
" var pixelRatio = Math.round( window.devicePixelRatio );\n",
"\n",
" var font = [fontStyle, fontWeight, fontSize + 'px', fontFamily].join(' ');\n",
"\n",
" context.font = font;\n",
" var width = context.measureText( text ).width;\n",
" var height = fontSize;\n",
"\n",
" // The dimensions of the canvas's underlying image data need to be powers\n",
" // of two in order for the resulting texture to support mipmapping.\n",
" canvas.width = THREE.MathUtils.ceilPowerOfTwo( width * pixelRatio );\n",
" canvas.height = THREE.MathUtils.ceilPowerOfTwo( height * pixelRatio );\n",
"\n",
" // Re-compute the unscaled dimensions after the power of two conversion.\n",
" width = canvas.width / pixelRatio;\n",
" height = canvas.height / pixelRatio;\n",
"\n",
" canvas.style.width = width + 'px';\n",
" canvas.style.height = height + 'px';\n",
"\n",
" context.scale( pixelRatio, pixelRatio );\n",
" context.fillStyle = color;\n",
" context.font = font; // Must be set again after measureText.\n",
" context.textAlign = 'center';\n",
" context.textBaseline = 'middle';\n",
" context.fillText( text, width/2, height/2 );\n",
"\n",
" var texture = new THREE.Texture( canvas );\n",
" texture.needsUpdate = true;\n",
"\n",
" var materialOptions = { map: texture, sizeAttenuation: false };\n",
" if ( opacity < 1 ) {\n",
" // Setting opacity=1 would cause the texture's alpha component to be\n",
" // discarded, giving the text a black background instead of the\n",
" // background being transparent.\n",
" materialOptions.opacity = opacity;\n",
" }\n",
" var sprite = new THREE.Sprite( new THREE.SpriteMaterial( materialOptions ) );\n",
" sprite.position.set( x, y, z );\n",
"\n",
" // Scaling factor, chosen somewhat arbitrarily so that the size of the text\n",
" // is consistent with previously generated plots.\n",
" var scale = 1/625;\n",
" if ( options.projection === 'orthographic' ) {\n",
" scale = midToCorner/256; // Needs to scale along with the plot itself.\n",
" }\n",
" sprite.scale.set( scale * width, scale * height, 1 );\n",
"\n",
" scene.add( sprite );\n",
"\n",
" return sprite;\n",
"\n",
" }\n",
"\n",
" if ( options.axes ) scene.add( new THREE.AxesHelper( Math.min( a[0]*b[1].x, a[1]*b[1].y, a[2]*b[1].z ) ) );\n",
"\n",
" var camera = createCamera();\n",
" camera.up.set( 0, 0, 1 );\n",
" camera.position.set( a[0]*xMid, a[1]*yMid, a[2]*zMid );\n",
"\n",
" var offset = new THREE.Vector3( a[0]*xRange, a[1]*yRange, a[2]*zRange );\n",
"\n",
" if ( options.viewpoint ) {\n",
"\n",
" var aa = options.viewpoint;\n",
" var axis = new THREE.Vector3( aa[0][0], aa[0][1], aa[0][2] ).normalize();\n",
" var angle = aa[1] * Math.PI / 180;\n",
" var q = new THREE.Quaternion().setFromAxisAngle( axis, angle ).inverse();\n",
"\n",
" offset.set( 0, 0, offset.length() );\n",
" offset.applyQuaternion( q );\n",
"\n",
" }\n",
"\n",
" camera.position.add( offset );\n",
"\n",
" function createCamera() {\n",
"\n",
" var aspect = window.innerWidth / window.innerHeight;\n",
"\n",
" if ( options.projection === 'orthographic' ) {\n",
" var camera = new THREE.OrthographicCamera( -1, 1, 1, -1, -1000, 1000 );\n",
" updateCameraAspect( camera, aspect );\n",
" return camera;\n",
" }\n",
"\n",
" return new THREE.PerspectiveCamera( 45, aspect, 0.1, 1000 );\n",
"\n",
" }\n",
"\n",
" function updateCameraAspect( camera, aspect ) {\n",
"\n",
" if ( camera.isPerspectiveCamera ) {\n",
" camera.aspect = aspect;\n",
" } else if ( camera.isOrthographicCamera ) {\n",
" // Fit the camera frustum to the bounding box's diagonal so that the entire plot fits\n",
" // within at the default zoom level and camera position.\n",
" if ( aspect > 1 ) { // Wide window\n",
" camera.top = midToCorner;\n",
" camera.right = midToCorner * aspect;\n",
" } else { // Tall or square window\n",
" camera.top = midToCorner / aspect;\n",
" camera.right = midToCorner;\n",
" }\n",
" camera.bottom = -camera.top;\n",
" camera.left = -camera.right;\n",
" }\n",
"\n",
" camera.updateProjectionMatrix();\n",
"\n",
" }\n",
"\n",
" var lights = [{&quot;x&quot;:-5, &quot;y&quot;:3, &quot;z&quot;:0, &quot;color&quot;:&quot;#7f7f7f&quot;, &quot;parent&quot;:&quot;camera&quot;}];\n",
" for ( var i=0 ; i < lights.length ; i++ ) {\n",
" var light = new THREE.DirectionalLight( lights[i].color, 1 );\n",
" light.position.set( a[0]*lights[i].x, a[1]*lights[i].y, a[2]*lights[i].z );\n",
" if ( lights[i].parent === 'camera' ) {\n",
" light.target.position.set( a[0]*xMid, a[1]*yMid, a[2]*zMid );\n",
" scene.add( light.target );\n",
" camera.add( light );\n",
" } else scene.add( light );\n",
" }\n",
" scene.add( camera );\n",
"\n",
" var ambient = {&quot;color&quot;:&quot;#7f7f7f&quot;};\n",
" scene.add( new THREE.AmbientLight( ambient.color, 1 ) );\n",
"\n",
" var controls = new THREE.OrbitControls( camera, renderer.domElement );\n",
" controls.target.set( a[0]*xMid, a[1]*yMid, a[2]*zMid );\n",
" controls.addEventListener( 'change', function() { if ( !animate ) render(); } );\n",
"\n",
" window.addEventListener( 'resize', function() {\n",
"\n",
" renderer.setSize( window.innerWidth, window.innerHeight );\n",
" updateCameraAspect( camera, window.innerWidth / window.innerHeight );\n",
" if ( !animate ) render();\n",
"\n",
" } );\n",
"\n",
" var texts = [];\n",
" for ( var i=0 ; i < texts.length ; i++ ) addText( texts[i] );\n",
"\n",
" function addText( json ) {\n",
" json.fontFamily = json.fontFamily.map( function( f ) {\n",
" // Need to put quotes around fonts that have whitespace in their names.\n",
" return /\\s/.test( f ) ? '&quot;' + f + '&quot;' : f;\n",
" }).join(', ');\n",
" var sprite = addLabel( json.text, a[0]*json.x, a[1]*json.y, a[2]*json.z, json.color,\n",
" json.fontSize, json.fontFamily, json.fontStyle, json.fontWeight,\n",
" json.opacity );\n",
" sprite.userData = json;\n",
" }\n",
"\n",
" var points = [];\n",
" for ( var i=0 ; i < points.length ; i++ ) addPoint( points[i] );\n",
"\n",
" function addPoint( json ) {\n",
"\n",
" var geometry = new THREE.Geometry();\n",
" var v = json.point;\n",
" geometry.vertices.push( new THREE.Vector3( a[0]*v[0], a[1]*v[1], a[2]*v[2] ) );\n",
"\n",
" var canvas = document.createElement( 'canvas' );\n",
" canvas.width = 128;\n",
" canvas.height = 128;\n",
"\n",
" var context = canvas.getContext( '2d' );\n",
" context.arc( 64, 64, 64, 0, 2 * Math.PI );\n",
" context.fillStyle = json.color;\n",
" context.fill();\n",
"\n",
" var texture = new THREE.Texture( canvas );\n",
" texture.needsUpdate = true;\n",
"\n",
" var transparent = json.opacity < 1 ? true : false;\n",
" var size = camera.isOrthographicCamera ? json.size : json.size/100;\n",
" var material = new THREE.PointsMaterial( { size: size, map: texture,\n",
" transparent: transparent, opacity: json.opacity,\n",
" alphaTest: .1 } );\n",
"\n",
" var c = new THREE.Vector3();\n",
" geometry.computeBoundingBox();\n",
" geometry.boundingBox.getCenter( c );\n",
" geometry.translate( -c.x, -c.y, -c.z );\n",
"\n",
" var mesh = new THREE.Points( geometry, material );\n",
" mesh.position.set( c.x, c.y, c.z );\n",
" mesh.userData = json;\n",
" scene.add( mesh );\n",
"\n",
" }\n",
"\n",
" var lines = [];\n",
" for ( var i=0 ; i < lines.length ; i++ ) addLine( lines[i] );\n",
"\n",
" function addLine( json ) {\n",
"\n",
" var geometry = new THREE.Geometry();\n",
" for ( var i=0 ; i < json.points.length ; i++ ) {\n",
" var v = json.points[i];\n",
" geometry.vertices.push( new THREE.Vector3( a[0]*v[0], a[1]*v[1], a[2]*v[2] ) );\n",
" }\n",
"\n",
" var transparent = json.opacity < 1 ? true : false;\n",
" var material = new THREE.LineBasicMaterial( { color: json.color, linewidth: json.linewidth,\n",
" transparent: transparent, opacity: json.opacity } );\n",
"\n",
" var c = new THREE.Vector3();\n",
" geometry.computeBoundingBox();\n",
" geometry.boundingBox.getCenter( c );\n",
" geometry.translate( -c.x, -c.y, -c.z );\n",
"\n",
" var mesh = new THREE.Line( geometry, material );\n",
" mesh.position.set( c.x, c.y, c.z );\n",
" mesh.userData = json;\n",
" scene.add( mesh );\n",
"\n",
" }\n",
"\n",
" var surfaces = [{&quot;vertices&quot;: [{&quot;x&quot;: 2.8775303643724692, &quot;y&quot;: -0.8461538461538458, &quot;z&quot;: -3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.8461538461538458, &quot;z&quot;: -2.968623481781377}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.9455128205128189, &quot;z&quot;: -3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.8461538461538458, &quot;z&quot;: 2.9686234817813775}, {&quot;x&quot;: 2.8775303643724692, &quot;y&quot;: -0.8461538461538458, &quot;z&quot;: 3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.9455128205128189, &quot;z&quot;: 3.0}, {&quot;x&quot;: 2.918016194331985, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: -3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.8461538461538458, &quot;z&quot;: -2.968623481781377}, {&quot;x&quot;: 2.8775303643724692, &quot;y&quot;: -0.8461538461538458, &quot;z&quot;: -3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: -2.9281376518218627}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.8461538461538458, &quot;z&quot;: -2.968623481781377}, {&quot;x&quot;: 2.918016194331985, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: -3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: 2.9281376518218627}, {&quot;x&quot;: 2.8775303643724692, &quot;y&quot;: -0.8461538461538458, &quot;z&quot;: 3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.8461538461538458, &quot;z&quot;: 2.9686234817813775}, {&quot;x&quot;: 2.918016194331985, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: 3.0}, {&quot;x&quot;: 2.8775303643724692, &quot;y&quot;: -0.8461538461538458, &quot;z&quot;: 3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: 2.9281376518218627}, {&quot;x&quot;: 2.9504048582995956, &quot;y&quot;: -0.5384615384615383, &quot;z&quot;: -3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: -2.9281376518218627}, {&quot;x&quot;: 2.918016194331985, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: -3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.5384615384615383, &quot;z&quot;: -2.8957489878542515}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: -2.9281376518218627}, {&quot;x&quot;: 2.9504048582995956, &quot;y&quot;: -0.5384615384615383, &quot;z&quot;: -3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.5384615384615383, &quot;z&quot;: 2.895748987854251}, {&quot;x&quot;: 2.918016194331985, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: 3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: 2.9281376518218627}, {&quot;x&quot;: 2.9504048582995956, &quot;y&quot;: -0.5384615384615383, &quot;z&quot;: 3.0}, {&quot;x&quot;: 2.918016194331985, &quot;y&quot;: -0.6923076923076921, &quot;z&quot;: 3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.5384615384615383, &quot;z&quot;: 2.895748987854251}, {&quot;x&quot;: 2.974696356275304, &quot;y&quot;: -0.3846153846153846, &quot;z&quot;: -3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.5384615384615383, &quot;z&quot;: -2.8957489878542515}, {&quot;x&quot;: 2.9504048582995956, &quot;y&quot;: -0.5384615384615383, &quot;z&quot;: -3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.3846153846153846, &quot;z&quot;: -2.8714574898785425}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.5384615384615383, &quot;z&quot;: -2.8957489878542515}, {&quot;x&quot;: 2.974696356275304, &quot;y&quot;: -0.3846153846153846, &quot;z&quot;: -3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.3846153846153846, &quot;z&quot;: 2.8714574898785434}, {&quot;x&quot;: 2.9504048582995956, &quot;y&quot;: -0.5384615384615383, &quot;z&quot;: 3.0}, {&quot;x&quot;: 2.8461538461538467, &quot;y&quot;: -0.5384615384615383, &quot;z&quot;: 2.895748987854251}, {&quot;x&quot;: 2.974696356275304, &quot;y&quot;: -0.3846153846153846, &quot;z&quot;: 3.0}, {&quot;x&quot;: 2.95040485829959
" for ( var i=0 ; i < surfaces.length ; i++ ) addSurface( surfaces[i] );\n",
"\n",
" function addSurface( json ) {\n",
"\n",
" var useFaceColors = 'faceColors' in json ? true : false;\n",
"\n",
" var geometry = new THREE.Geometry();\n",
" for ( var i=0 ; i < json.vertices.length ; i++ ) {\n",
" var v = json.vertices[i];\n",
" geometry.vertices.push( new THREE.Vector3( a[0]*v.x, a[1]*v.y, a[2]*v.z ) );\n",
" }\n",
" for ( var i=0 ; i < json.faces.length ; i++ ) {\n",
" var f = json.faces[i];\n",
" for ( var j=0 ; j < f.length - 2 ; j++ ) {\n",
" var face = new THREE.Face3( f[0], f[j+1], f[j+2] );\n",
" if ( useFaceColors ) face.color.set( json.faceColors[i] );\n",
" geometry.faces.push( face );\n",
" }\n",
" }\n",
" geometry.computeVertexNormals();\n",
"\n",
" var side = json.singleSide ? THREE.FrontSide : THREE.DoubleSide;\n",
" var transparent = json.opacity < 1 ? true : false;\n",
" var flatShading = json.useFlatShading ? json.useFlatShading : false;\n",
"\n",
" var material = new THREE.MeshPhongMaterial( { side: side,\n",
" color: useFaceColors ? 'white' : json.color,\n",
" vertexColors: useFaceColors ? THREE.FaceColors : THREE.NoColors,\n",
" transparent: transparent, opacity: json.opacity,\n",
" shininess: 20, flatShading: flatShading } );\n",
"\n",
" var c = new THREE.Vector3();\n",
" geometry.computeBoundingBox();\n",
" geometry.boundingBox.getCenter( c );\n",
" geometry.translate( -c.x, -c.y, -c.z );\n",
"\n",
" var mesh = new THREE.Mesh( geometry, material );\n",
" mesh.position.set( c.x, c.y, c.z );\n",
" if ( transparent && json.renderOrder ) mesh.renderOrder = json.renderOrder;\n",
" mesh.userData = json;\n",
" scene.add( mesh );\n",
"\n",
" if ( json.showMeshGrid ) {\n",
"\n",
" var geometry = new THREE.Geometry();\n",
"\n",
" for ( var i=0 ; i < json.faces.length ; i++ ) {\n",
" var f = json.faces[i];\n",
" for ( var j=0 ; j < f.length ; j++ ) {\n",
" var k = j === f.length-1 ? 0 : j+1;\n",
" var v1 = json.vertices[f[j]];\n",
" var v2 = json.vertices[f[k]];\n",
" // vertices in opposite directions on neighboring faces\n",
" var nudge = f[j] < f[k] ? .0005*zRange : -.0005*zRange;\n",
" geometry.vertices.push( new THREE.Vector3( a[0]*v1.x, a[1]*v1.y, a[2]*(v1.z+nudge) ) );\n",
" geometry.vertices.push( new THREE.Vector3( a[0]*v2.x, a[1]*v2.y, a[2]*(v2.z+nudge) ) );\n",
" }\n",
" }\n",
"\n",
" var material = new THREE.LineBasicMaterial( { color: 'black', linewidth: 1 } );\n",
"\n",
" var c = new THREE.Vector3();\n",
" geometry.computeBoundingBox();\n",
" geometry.boundingBox.getCenter( c );\n",
" geometry.translate( -c.x, -c.y, -c.z );\n",
"\n",
" var mesh = new THREE.LineSegments( geometry, material );\n",
" mesh.position.set( c.x, c.y, c.z );\n",
" mesh.userData = json;\n",
" scene.add( mesh );\n",
"\n",
" }\n",
"\n",
" }\n",
"\n",
" function render() {\n",
"\n",
" if ( window.updateAnimation ) animate = updateAnimation();\n",
" if ( animate ) requestAnimationFrame( render );\n",
"\n",
" renderer.render( scene, camera );\n",
"\n",
" }\n",
"\n",
" render();\n",
" controls.update();\n",
" if ( !animate ) render();\n",
"\n",
"\n",
" // menu functions\n",
"\n",
" function toggleMenu() {\n",
"\n",
" var m = document.getElementById( 'menu-content' );\n",
" if ( m.style.display === 'block' ) m.style.display = 'none'\n",
" else m.style.display = 'block';\n",
"\n",
" }\n",
"\n",
"\n",
" function saveAsPNG() {\n",
"\n",
" var a = document.body.appendChild( document.createElement( 'a' ) );\n",
" a.href = renderer.domElement.toDataURL( 'image/png' );\n",
" a.download = 'screenshot';\n",
" a.click();\n",
"\n",
" }\n",
"\n",
" function saveAsHTML() {\n",
"\n",
" toggleMenu(); // otherwise visible in output\n",
" event.stopPropagation();\n",
"\n",
" var blob = new Blob( [ '<!DOCTYPE html>\\n' + document.documentElement.outerHTML ] );\n",
" var a = document.body.appendChild( document.createElement( 'a' ) );\n",
" a.href = window.URL.createObjectURL( blob );\n",
" a.download = 'graphic.html';\n",
" a.click();\n",
"\n",
" }\n",
"\n",
" function getViewpoint() {\n",
"\n",
" function roundTo( x, n ) { return +x.toFixed(n); }\n",
"\n",
" var v = camera.quaternion.inverse();\n",
" var r = Math.sqrt( v.x*v.x + v.y*v.y + v.z*v.z );\n",
" var axis = [ roundTo( v.x / r, 4 ), roundTo( v.y / r, 4 ), roundTo( v.z / r, 4 ) ];\n",
" var angle = roundTo( 2 * Math.atan2( r, v.w ) * 180 / Math.PI, 2 );\n",
"\n",
" var textArea = document.createElement( 'textarea' );\n",
" textArea.textContent = JSON.stringify( axis ) + ',' + angle;\n",
" textArea.style.csstext = 'position: absolute; top: -100%';\n",
" document.body.append( textArea );\n",
" textArea.select();\n",
" document.execCommand( 'copy' );\n",
"\n",
" var m = document.getElementById( 'menu-message' );\n",
" m.innerHTML = 'Viewpoint copied to clipboard';\n",
" m.style.display = 'block';\n",
" setTimeout( function() { m.style.display = 'none'; }, 2000 );\n",
"\n",
" }\n",
"\n",
"</script>\n",
"\n",
"<div id=&quot;menu-container&quot; onclick=&quot;toggleMenu()&quot;>&#x24d8;\n",
"<div id=&quot;menu-message&quot;></div>\n",
"<div id=&quot;menu-content&quot;>\n",
"<div onclick=&quot;saveAsPNG()&quot;>Save as PNG</div>\n",
"<div onclick=&quot;saveAsHTML()&quot;>Save as HTML</div>\n",
"<div onclick=&quot;getViewpoint()&quot;>Get Viewpoint</div>\n",
"<div>Close Menu</div>\n",
"</div></div>\n",
"\n",
"\n",
"</body>\n",
"</html>\n",
"\"\n",
" width=\"100%\"\n",
" height=\"400\"\n",
" style=\"border: 0;\">\n",
"</iframe>\n"
],
"text/plain": [
"Graphics3d Object"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"var('x,y,z')\n",
"implicit_plot3d(x^2 + y^2 - z^2 == 0, (x,-3,3), (y,-3,3), (z,-3,3))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "SageMath 9.2",
"language": "sage",
"name": "sagemath"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.2"
}
},
"nbformat": 4,
"nbformat_minor": 4
}