1861 lines
100 KiB
Plaintext
1861 lines
100 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"id": "72d5a30c-1a59-4a55-9680-fdfa7979625b",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# load('zetas_triples_general.py')\n",
|
|
"R.<x, y, z> = PolynomialRing(QQ, order='neglex')\n",
|
|
"S.<u, v> = PolynomialRing(QQ, order='neglex')\n",
|
|
"f = v^2 - u^2\n",
|
|
"g = u^4\n",
|
|
"F = z^3 - 3 * f(u=x, v=y) * z + 2 * g(u=x, v=y)\n",
|
|
"h = F.discriminant(z)(x=u, y=v)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "57f4e587-fd6a-4aa2-8423-78e8b5f0d2dd",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"10"
|
|
]
|
|
},
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"F.jacobian_ideal().vector_space_dimension()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"id": "9207fe2e-adca-4549-a083-74d467563684",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"10"
|
|
]
|
|
},
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"R0.<t> = QQ[]\n",
|
|
"Kt = R0.fraction_field()\n",
|
|
"Rt.<x, y, z> = PolynomialRing(Kt, order='neglex')\n",
|
|
"S.<u, v> = PolynomialRing(Kt, order='neglex')\n",
|
|
"f = v^2 - u^2\n",
|
|
"g = u^4\n",
|
|
"F = z^3 - 3 * f(u=x, v=y) * z + 2 * g(u=x, v=y)\n",
|
|
"h = F.discriminant(z)(x=u, y=v)\n",
|
|
"F.jacobian_ideal().vector_space_dimension()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"id": "27e92ddc-34d6-4290-880f-9d3561a8ec4e",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"10"
|
|
]
|
|
},
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"Ft = F + t * x * z^2\n",
|
|
"Ft.jacobian_ideal().vector_space_dimension()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"id": "8cc358aa-03d1-4b9c-b4ff-87b0324bd55b",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"load('zetas_triples_general.py')\n",
|
|
"ht = Ft.discriminant(z)(x=u, y=v)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"id": "d21a93b0-b0c4-4cd2-b648-f4bca8f78376",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"Zt = ZetaFunctions(ht)\n",
|
|
"Z = ZetaFunctions(h)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"id": "59240908-d672-4520-90e5-7358840f8c23",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[(-108) * (-v + u)^3 * (v + u)^3]"
|
|
]
|
|
},
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"[p.factor() for p in Z.get_polyfaces_dictionary(compact=True) if p.number_of_terms() > 1]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"id": "a1a4111c-050d-4656-be38-ceac87684b47",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[(9) * (v - u)^2 * (v + u)^2 * (12*v^2 + (t^2 - 12)*u^2)]"
|
|
]
|
|
},
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"[p.factor() for p in Zt.get_polyfaces_dictionary(compact=True) if p.number_of_terms() > 1]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"id": "8ac2847d-121a-4a78-a202-7e1692998c99",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"Zta = ZetaFunctions(ht(v=v + u))\n",
|
|
"Za = ZetaFunctions(h(v=v + u))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"id": "e7884c6b-458b-4d7c-8c8f-376ec4b87c9a",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[(108) * v^3 * (v + 2*u)^3, (108) * u^3 * (8*v^3 - u^5)]"
|
|
]
|
|
},
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"[p.factor() for p in Za.get_polyfaces_dictionary(compact=True) if p.number_of_terms() > 1]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"id": "442b2c9c-c7f1-4fb9-ac12-bf372d90a342",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[(9) * v^2 * (v + 2*u)^2 * (12*v^2 + 24*u*v + (t^2)*u^2),\n",
|
|
" ((4*t^2)) * u^4 * (9*v^2 + (-2*t)*u^3)]"
|
|
]
|
|
},
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"[p.factor() for p in Zta.get_polyfaces_dictionary(compact=True) if p.number_of_terms() > 1]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"id": "bb3b178d-c56c-491d-8bc6-c951d101ff92",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"Ztb = ZetaFunctions(ht(v=v - u))\n",
|
|
"Zb = ZetaFunctions(h(v=v -u ))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"id": "7121f34f-2792-4ed5-8e20-fb0024e1638d",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[(-108) * (-v + 2*u)^3 * v^3, (-108) * u^3 * (8*v^3 + u^5)]"
|
|
]
|
|
},
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"[p.factor() for p in Zb.get_polyfaces_dictionary(compact=True) if p.number_of_terms() > 1]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"id": "9986d1b9-fc85-4019-845f-438f79021f2b",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[(9) * v^2 * (v - 2*u)^2 * (12*v^2 - 24*u*v + (t^2)*u^2),\n",
|
|
" ((4*t^2)) * u^4 * (9*v^2 + (-2*t)*u^3)]"
|
|
]
|
|
},
|
|
"execution_count": 19,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"[p.factor() for p in Ztb.get_polyfaces_dictionary(compact=True) if p.number_of_terms() > 1]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 24,
|
|
"id": "fb974d4e-ea53-48e8-97e3-6878039dfbe6",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"Zt = ZetaFunctions(Ft)\n",
|
|
"Z = ZetaFunctions(F)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 47,
|
|
"id": "9974eefe-db38-4da1-b438-eb56f6effbe4",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def nwt(p):\n",
|
|
" return p(u=u^2, v=u^7 * (v + 1))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 27,
|
|
"id": "2b0713c1-0f81-4477-b0e4-b37c3ad80456",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"<iframe srcdoc=\"<!DOCTYPE html>\n",
|
|
"<html>\n",
|
|
"<head>\n",
|
|
"<title></title>\n",
|
|
"<meta charset="utf-8">\n",
|
|
"<meta name=viewport content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">\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",
|
|
" .dark-theme #menu-container { color: white; }\n",
|
|
"\n",
|
|
" .dark-theme #menu-message { background-color: #181818; }\n",
|
|
"\n",
|
|
" .dark-theme #menu-content { background-color: #181818; border-color: white; }\n",
|
|
"\n",
|
|
" .dark-theme #menu-content div { border-color: white; }\n",
|
|
"\n",
|
|
" .dark-theme #menu-content div:hover { background-color: #303030; }\n",
|
|
"\n",
|
|
"</style>\n",
|
|
"\n",
|
|
"</head>\n",
|
|
"\n",
|
|
"<body>\n",
|
|
"\n",
|
|
"<script src="/nbextensions/threejs-sage/r122/three.min.js"></script>\n",
|
|
"<script>\n",
|
|
" if ( !window.THREE ) document.write(' \\\n",
|
|
"<script src="https://cdn.jsdelivr.net/gh/sagemath/threejs-sage@r122/build/three.min.js"><\\/script> \\\n",
|
|
" ');\n",
|
|
"</script>\n",
|
|
" \n",
|
|
"<script>\n",
|
|
"\n",
|
|
" var options = {"animate": false, "animationControls": true, "aspectRatio": [1.0, 1.0, 1.0], "autoScaling": [false, false, false], "autoPlay": true, "axes": false, "axesLabels": ["x", "y", "z"], "axesLabelsStyle": null, "decimals": 2, "delay": 20, "frame": true, "loop": true, "projection": "perspective", "theme": "light", "viewpoint": false};\n",
|
|
" var animate = options.animate;\n",
|
|
"\n",
|
|
" if ( options.theme === 'dark' )\n",
|
|
" document.body.className = 'dark-theme';\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( options.theme === 'dark' ? 0 : 0xffffff, 1 );\n",
|
|
" document.body.appendChild( renderer.domElement );\n",
|
|
"\n",
|
|
" var b = [{"x":-0.05706339097770922, "y":-0.048541019662496854, "z":-0.05999999999999995}, {"x":5.0, "y":3.0, "z":4.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 rxRange = Math.sqrt( Math.pow( b[1].z - b[0].z, 2 )\n",
|
|
" + Math.pow( b[1].y - b[0].y, 2 ) );\n",
|
|
" var ryRange = Math.sqrt( Math.pow( b[1].x - b[0].x, 2 )\n",
|
|
" + Math.pow( b[1].z - b[0].z, 2 ) );\n",
|
|
" var rzRange = 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",
|
|
"\n",
|
|
" var autoScaling = options.autoScaling;\n",
|
|
" var autoAspect = 2.5;\n",
|
|
" if ( xRange > autoAspect * rxRange && autoScaling[0] ) a[0] = autoAspect * rxRange / xRange;\n",
|
|
" if ( yRange > autoAspect * ryRange && autoScaling[1] ) a[1] = autoAspect * ryRange / yRange;\n",
|
|
" if ( zRange > autoAspect * rzRange && autoScaling[2] ) a[2] = autoAspect * rzRange / 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",
|
|
" var boxColor = options.theme === 'dark' ? 'white' : 'black';\n",
|
|
" if ( options.frame ) scene.add( new THREE.BoxHelper( boxMesh, boxColor ) );\n",
|
|
"\n",
|
|
" if ( options.axesLabels ) {\n",
|
|
"\n",
|
|
" var d = options.decimals; // decimals\n",
|
|
" var offsetRatio = 0.1;\n",
|
|
" var al = options.axesLabels;\n",
|
|
" var als = options.axesLabelsStyle || [{}, {}, {}];\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, als[0] );\n",
|
|
" addLabel( ( b[0].x ).toFixed(d), a[0]*b[0].x, a[1]*b[1].y+offset, a[2]*b[0].z, als[0] );\n",
|
|
" addLabel( ( b[1].x ).toFixed(d), a[0]*b[1].x, a[1]*b[1].y+offset, a[2]*b[0].z, als[0] );\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, als[1] );\n",
|
|
" addLabel( ( b[0].y ).toFixed(d), a[0]*b[1].x+offset, a[1]*b[0].y, a[2]*b[0].z, als[1] );\n",
|
|
" addLabel( ( b[1].y ).toFixed(d), a[0]*b[1].x+offset, a[1]*b[1].y, a[2]*b[0].z, als[1] );\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, als[2] );\n",
|
|
" addLabel( ( b[0].z ).toFixed(d), a[0]*b[1].x, a[1]*b[0].y-offset, a[2]*b[0].z, als[2] );\n",
|
|
" addLabel( ( b[1].z ).toFixed(d), a[0]*b[1].x, a[1]*b[0].y-offset, a[2]*b[1].z, als[2] );\n",
|
|
"\n",
|
|
" }\n",
|
|
"\n",
|
|
" function addLabel( text, x, y, z, style ) {\n",
|
|
"\n",
|
|
" var color = style.color || 'black';\n",
|
|
" var fontSize = style.fontSize || 14;\n",
|
|
" var fontFamily = style.fontFamily || 'monospace';\n",
|
|
" var fontStyle = style.fontStyle || 'normal';\n",
|
|
" var fontWeight = style.fontWeight || 'normal';\n",
|
|
" var opacity = style.opacity || 1;\n",
|
|
"\n",
|
|
" if ( options.theme === 'dark' )\n",
|
|
" if ( color === 'black' || color === '#000000' )\n",
|
|
" color = 'white';\n",
|
|
"\n",
|
|
" if ( Array.isArray( fontStyle ) ) {\n",
|
|
" fontFamily = fontFamily.map( function( f ) {\n",
|
|
" // Need to put quotes around fonts that have whitespace in their names.\n",
|
|
" return /\\s/.test( f ) ? '"' + f + '"' : f;\n",
|
|
" }).join(', ');\n",
|
|
" }\n",
|
|
"\n",
|
|
" var canvas = document.createElement( 'canvas' );\n",
|
|
" var context = canvas.getContext( '2d' );\n",
|
|
" var pixelRatio = Math.round( window.devicePixelRatio );\n",
|
|
"\n",
|
|
" // For example: italic bold 20px "Times New Roman", Georgia, serif\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, depthWrite: 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",
|
|
" // camera is positioned so that the line from the camera to the center\n",
|
|
" // of the bounding sphere of the objects makes an angle of 60 degrees with x-axis\n",
|
|
" // and an angle of 30 degrees with z-axis and the field of view of the camera looking\n",
|
|
" // at the center has an angle of 45 degrees.\n",
|
|
" const sin8 = Math.sin(Math.PI / 8);\n",
|
|
" const sin5 = Math.sin(Math.PI / 5);\n",
|
|
" const cos5 = Math.cos(Math.PI / 5);\n",
|
|
" const sin3 = Math.sin(Math.PI / 3);\n",
|
|
" const cos3 = Math.cos(Math.PI / 3);\n",
|
|
" var r = midToCorner / sin8;\n",
|
|
" var offset = new THREE.Vector3( r * sin3 * cos5, r * sin3 * sin5, r * cos3 );\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",
|
|
" // Scale the near and far clipping planes along with the overall plot size.\n",
|
|
" var nearClip = 0.01 * midToCorner;\n",
|
|
" var farClip = 100 * midToCorner;\n",
|
|
"\n",
|
|
" if ( options.projection === 'orthographic' ) {\n",
|
|
" var camera = new THREE.OrthographicCamera( -1, 1, 1, -1, -farClip, farClip );\n",
|
|
" updateCameraAspect( camera, aspect );\n",
|
|
" return camera;\n",
|
|
" }\n",
|
|
"\n",
|
|
" return new THREE.PerspectiveCamera( 45, aspect, nearClip, farClip );\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 = [{"x":-5, "y":3, "z":0, "color":"#7f7f7f", "parent":"camera"}];\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 = {"color":"#7f7f7f"};\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 ( window.rescaleFatLines ) rescaleFatLines();\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",
|
|
" var sprite = addLabel( json.text, a[0]*json.x, a[1]*json.y, a[2]*json.z, json );\n",
|
|
" sprite.userData = json;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var points = [{"point": [0.0, 0.0, 3.0], "size": 10.0, "color": "#0000ff", "opacity": 1.0}, {"point": [0.0, 2.0, 1.0], "size": 10.0, "color": "#0000ff", "opacity": 1.0}, {"point": [2.0, 0.0, 1.0], "size": 10.0, "color": "#0000ff", "opacity": 1.0}, {"point": [4.0, 0.0, 0.0], "size": 10.0, "color": "#0000ff", "opacity": 1.0}, {"point": [0.0, 0.0, 3.0], "size": 30.0, "color": "#ff0000", "opacity": 1.0}, {"point": [0.0, 2.0, 1.0], "size": 30.0, "color": "#ff0000", "opacity": 1.0}, {"point": [2.0, 0.0, 1.0], "size": 30.0, "color": "#ff0000", "opacity": 1.0}, {"point": [4.0, 0.0, 0.0], "size": 30.0, "color": "#ff0000", "opacity": 1.0}, {"point": [0.0, 0.0, 0.0], "size": 30.0, "color": "#000000", "opacity": 1.0}];\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 = [{"points": [[0.0, 0.0, 3.0], [0.0, 2.0, 1.0]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"points": [[0.0, 0.0, 3.0], [2.0, 0.0, 1.0]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"points": [[0.0, 2.0, 1.0], [2.0, 0.0, 1.0]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"points": [[0.0, 2.0, 1.0], [4.0, 0.0, 0.0]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"points": [[2.0, 0.0, 1.0], [4.0, 0.0, 0.0]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}];\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 c = new THREE.Vector3();\n",
|
|
" geometry.computeBoundingBox();\n",
|
|
" geometry.boundingBox.getCenter( c );\n",
|
|
" geometry.translate( -c.x, -c.y, -c.z );\n",
|
|
"\n",
|
|
" var transparent = json.opacity < 1 ? true : false;\n",
|
|
" var materialOptions = { color: json.color, linewidth: json.linewidth,\n",
|
|
" transparent: transparent, opacity: json.opacity };\n",
|
|
"\n",
|
|
" var mesh;\n",
|
|
" if ( json.linewidth > 1 && window.createFatLineStrip ) {\n",
|
|
" mesh = createFatLineStrip( geometry, materialOptions );\n",
|
|
" } else {\n",
|
|
" var material = new THREE.LineBasicMaterial( materialOptions );\n",
|
|
" mesh = new THREE.Line( geometry, material );\n",
|
|
" }\n",
|
|
"\n",
|
|
" mesh.position.set( c.x, c.y, c.z );\n",
|
|
" mesh.userData = json;\n",
|
|
" scene.add( mesh );\n",
|
|
"\n",
|
|
" }\n",
|
|
"\n",
|
|
" var surfaces = [{"vertices": [{"x": 0.0, "y": 0.0, "z": 3.8200000000000003}, {"x": 0.019021130325903073, "y": 0.006180339887498949, "z": 3.8200000000000003}, {"x": 0.0, "y": 0.02, "z": 3.8200000000000003}, {"x": 0.011755705045849465, "y": -0.016180339887498948, "z": 3.8200000000000003}, {"x": -0.011755705045849461, "y": -0.01618033988749895, "z": 3.8200000000000003}, {"x": -0.019021130325903073, "y": 0.006180339887498945, "z": 3.8200000000000003}, {"x": 0.019021130325903073, "y": 0.006180339887498949, "z": 3.0}, {"x": 0.0, "y": 0.02, "z": 3.0}, {"x": 0.011755705045849465, "y": -0.016180339887498948, "z": 3.0}, {"x": -0.011755705045849461, "y": -0.01618033988749895, "z": 3.0}, {"x": -0.019021130325903073, "y": 0.006180339887498945, "z": 3.0}, {"x": 0.0, "y": 0.0, "z": 3.0}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6, 7], [1, 3, 8, 6], [3, 4, 9, 8], [4, 5, 10, 9], [5, 2, 7, 10], [7, 6, 11], [6, 8, 11], [8, 9, 11], [9, 10, 11], [10, 7, 11]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 0.0, "y": 0.0, "z": 4.0}, {"x": 0.05706339097770921, "y": 0.018541019662496848, "z": 3.8200000000000003}, {"x": 0.0, "y": 0.06, "z": 3.8200000000000003}, {"x": 0.03526711513754839, "y": -0.04854101966249684, "z": 3.8200000000000003}, {"x": -0.03526711513754838, "y": -0.048541019662496854, "z": 3.8200000000000003}, {"x": -0.05706339097770922, "y": 0.018541019662496834, "z": 3.8200000000000003}, {"x": 0.0, "y": 0.0, "z": 3.8200000000000003}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6], [1, 3, 6], [3, 4, 6], [4, 5, 6], [5, 2, 6]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 0.0, "y": 2.8200000000000003, "z": 1.0}, {"x": 0.019021130325903073, "y": 2.8200000000000003, "z": 0.9938196601125011}, {"x": 0.0, "y": 2.8200000000000003, "z": 0.9800000000000001}, {"x": 0.011755705045849465, "y": 2.8200000000000003, "z": 1.016180339887499}, {"x": -0.011755705045849461, "y": 2.8200000000000003, "z": 1.016180339887499}, {"x": -0.019021130325903073, "y": 2.8200000000000003, "z": 0.9938196601125011}, {"x": 0.019021130325903073, "y": 2.0, "z": 0.993819660112501}, {"x": 0.0, "y": 2.0, "z": 0.98}, {"x": 0.011755705045849465, "y": 2.0, "z": 1.016180339887499}, {"x": -0.011755705045849461, "y": 2.0, "z": 1.016180339887499}, {"x": -0.019021130325903073, "y": 2.0, "z": 0.993819660112501}, {"x": 0.0, "y": 2.0, "z": 1.0}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6, 7], [1, 3, 8, 6], [3, 4, 9, 8], [4, 5, 10, 9], [5, 2, 7, 10], [7, 6, 11], [6, 8, 11], [8, 9, 11], [9, 10, 11], [10, 7, 11]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 0.0, "y": 3.0000000000000004, "z": 1.0}, {"x": 0.05706339097770921, "y": 2.8200000000000003, "z": 0.9814589803375031}, {"x": 0.0, "y": 2.8200000000000003, "z": 0.94}, {"x": 0.03526711513754839, "y": 2.8200000000000003, "z": 1.048541019662497}, {"x": -0.03526711513754838, "y": 2.8200000000000003, "z": 1.048541019662497}, {"x": -0.05706339097770922, "y": 2.8200000000000003, "z": 0.9814589803375031}, {"x": 0.0, "y": 2.8200000000000003, "z": 1.0}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6], [1, 3, 6], [3, 4, 6], [4, 5, 6], [5, 2, 6]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 4.0, "y": 0.8200000000000001, "z": 5.021051876504149e-17}, {"x": 4.019021130325903, "y": 0.8200000000000001, "z": -0.006180339887498899}, {"x": 4.0, "y": 0.8200000000000001, "z": -0.019999999999999952}, {"x": 4.011755705045849, "y": 0.8200000000000001, "z": 0.016180339887498996}, {"x": 3.9882442949541503, "y": 0.8200000000000001, "z": 0.016180339887499}, {"x": 3.980978869674097, "y": 0.8200000000000001, "z": -0.006180339887498895}, {"x": 4.019021130325903, "y": 3.7843667304341507e-19, "z": -0.006180339887498949}, {"x": 4.0, "y": 1.2246467991473532e-18, "z": -0.02}, {"x": 4.011755705045849, "y": -9.907600726170915e-19, "z": 0.016180339887498948}, {"x": 3.9882442949541503, "y": -9.907600726170917e-19, "z": 0.01618033988749895}, {"x": 3.980978869674097, "y": 3.784366730434148e-19, "z": -0.006180339887498945}, {"x": 4.0, "y": 0.0, "z": 0.0}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6, 7], [1, 3, 8, 6], [3, 4, 9, 8], [4, 5, 10, 9], [5, 2, 7, 10], [7, 6, 11], [6, 8, 11], [8, 9, 11], [9, 10, 11], [10, 7, 11]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 4.0, "y": 1.0, "z": 6.123233995736767e-17}, {"x": 4.057063390977709, "y": 0.8200000000000001, "z": -0.0185410196624968}, {"x": 4.0, "y": 0.8200000000000001, "z": -0.05999999999999995}, {"x": 4.0352671151375485, "y": 0.8200000000000001, "z": 0.04854101966249689}, {"x": 3.9647328848624515, "y": 0.8200000000000001, "z": 0.0485410196624969}, {"x": 3.942936609022291, "y": 0.8200000000000001, "z": -0.018541019662496785}, {"x": 4.0, "y": 0.8200000000000001, "z": 5.021051876504149e-17}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6], [1, 3, 6], [3, 4, 6], [4, 5, 6], [5, 2, 6]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 4.82, "y": 0.0, "z": 5.021051876504149e-17}, {"x": 4.82, "y": 0.006180339887498949, "z": -0.019021130325903024}, {"x": 4.82, "y": 0.02, "z": 5.021051876504149e-17}, {"x": 4.82, "y": -0.016180339887498948, "z": -0.011755705045849415}, {"x": 4.82, "y": -0.01618033988749895, "z": 0.011755705045849512}, {"x": 4.82, "y": 0.006180339887498945, "z": 0.01902113032590312}, {"x": 4.0, "y": 0.006180339887498949, "z": -0.019021130325903073}, {"x": 4.0, "y": 0.02, "z": 0.0}, {"x": 4.0, "y": -0.016180339887498948, "z": -0.011755705045849465}, {"x": 4.0, "y": -0.01618033988749895, "z": 0.011755705045849461}, {"x": 4.0, "y": 0.006180339887498945, "z": 0.019021130325903073}, {"x": 4.0, "y": 0.0, "z": 0.0}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6, 7], [1, 3, 8, 6], [3, 4, 9, 8], [4, 5, 10, 9], [5, 2, 7, 10], [7, 6, 11], [6, 8, 11], [8, 9, 11], [9, 10, 11], [10, 7, 11]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 5.0, "y": 0.0, "z": 6.123233995736767e-17}, {"x": 4.82, "y": 0.018541019662496848, "z": -0.05706339097770916}, {"x": 4.82, "y": 0.06, "z": 5.021051876504149e-17}, {"x": 4.82, "y": -0.04854101966249684, "z": -0.03526711513754834}, {"x": 4.82, "y": -0.048541019662496854, "z": 0.035267115137548426}, {"x": 4.82, "y": 0.018541019662496834, "z": 0.057063390977709266}, {"x": 4.82, "y": 0.0, "z": 5.021051876504149e-17}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6], [1, 3, 6], [3, 4, 6], [4, 5, 6], [5, 2, 6]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 0.0, "y": 0.0, "z": 3.0}, {"x": 0.0, "y": 2.0, "z": 1.0}, {"x": 2.0, "y": 0.0, "z": 1.0}, {"x": 4.0, "y": 0.0, "z": 0.0}, {"x": 0.0, "y": 0.0, "z": 4.0}, {"x": 0.0, "y": 3.0, "z": 1.0}, {"x": 4.0, "y": 1.0, "z": 0.0}, {"x": 5.0, "y": 0.0, "z": 0.0}], "faces": [[7, 3, 2, 0, 4], [2, 0, 1], [4, 0, 1, 5], [3, 6, 5, 1], [2, 1, 3], [6, 3, 7]], "color": "#008000", "opacity": 1.0, "useFlatShading": true}];\n",
|
|
" 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 depthWrite = 'depthWrite' in json ? json.depthWrite : !transparent;\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",
|
|
" depthWrite: depthWrite } );\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 ) addSurfaceMeshGrid( json );\n",
|
|
"\n",
|
|
" }\n",
|
|
"\n",
|
|
" function addSurfaceMeshGrid( json ) {\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 c = new THREE.Vector3();\n",
|
|
" geometry.computeBoundingBox();\n",
|
|
" geometry.boundingBox.getCenter( c );\n",
|
|
" geometry.translate( -c.x, -c.y, -c.z );\n",
|
|
"\n",
|
|
" var gridColor = options.theme === 'dark' ? 'white' : 'black';\n",
|
|
" var linewidth = json.linewidth || 1;\n",
|
|
" var materialOptions = { color: gridColor, linewidth: linewidth };\n",
|
|
"\n",
|
|
" var mesh;\n",
|
|
" if ( linewidth > 1 && window.createFatLineSegments ) {\n",
|
|
" mesh = createFatLineSegments( geometry, materialOptions );\n",
|
|
" } else {\n",
|
|
" var material = new THREE.LineBasicMaterial( materialOptions );\n",
|
|
" mesh = new THREE.LineSegments( geometry, material );\n",
|
|
" }\n",
|
|
"\n",
|
|
" mesh.position.set( c.x, c.y, c.z );\n",
|
|
" mesh.userData = json;\n",
|
|
" scene.add( mesh );\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 = suggestFilename();\n",
|
|
" a.click();\n",
|
|
"\n",
|
|
" function suggestFilename() {\n",
|
|
" if ( !document.title ) {\n",
|
|
" return 'graphic.html';\n",
|
|
" } else if ( /\\.html?$/i.test( document.title ) ) {\n",
|
|
" return document.title; // already ends in .htm or .html\n",
|
|
" } else {\n",
|
|
" return document.title + '.html';\n",
|
|
" }\n",
|
|
" }\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",
|
|
" function getCamera() {\n",
|
|
"\n",
|
|
" function roundTo( x, n ) { return +x.toFixed(n); }\n",
|
|
"\n",
|
|
" var pos = camera.position;\n",
|
|
" var pos_r = [ roundTo( pos.x, 4 ), roundTo( pos.y, 4 ), roundTo( pos.z, 4 ) ];\n",
|
|
" // var up = camera.up; // up is always (0,0,1)\n",
|
|
" var textArea = document.createElement('textarea');\n",
|
|
" var cam_position = JSON.stringify(pos_r);\n",
|
|
" textArea.textContent = ',camera_position=' + cam_position;\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 = 'Camera position '+ cam_position+' 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="menu-container" onclick="toggleMenu()">&#x24d8;\n",
|
|
"<div id="menu-message"></div>\n",
|
|
"<div id="menu-content">\n",
|
|
"<div onclick="saveAsPNG()">Save as PNG</div>\n",
|
|
"<div onclick="saveAsHTML()">Save as HTML</div>\n",
|
|
"<div onclick="getCamera()">Get camera</div>\n",
|
|
"<div onclick="getViewpoint()">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": 27,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"Z.newton_plot()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 28,
|
|
"id": "9ce635a7-c084-458e-889c-62d791adbf57",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"<iframe srcdoc=\"<!DOCTYPE html>\n",
|
|
"<html>\n",
|
|
"<head>\n",
|
|
"<title></title>\n",
|
|
"<meta charset="utf-8">\n",
|
|
"<meta name=viewport content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">\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",
|
|
" .dark-theme #menu-container { color: white; }\n",
|
|
"\n",
|
|
" .dark-theme #menu-message { background-color: #181818; }\n",
|
|
"\n",
|
|
" .dark-theme #menu-content { background-color: #181818; border-color: white; }\n",
|
|
"\n",
|
|
" .dark-theme #menu-content div { border-color: white; }\n",
|
|
"\n",
|
|
" .dark-theme #menu-content div:hover { background-color: #303030; }\n",
|
|
"\n",
|
|
"</style>\n",
|
|
"\n",
|
|
"</head>\n",
|
|
"\n",
|
|
"<body>\n",
|
|
"\n",
|
|
"<script src="/nbextensions/threejs-sage/r122/three.min.js"></script>\n",
|
|
"<script>\n",
|
|
" if ( !window.THREE ) document.write(' \\\n",
|
|
"<script src="https://cdn.jsdelivr.net/gh/sagemath/threejs-sage@r122/build/three.min.js"><\\/script> \\\n",
|
|
" ');\n",
|
|
"</script>\n",
|
|
" \n",
|
|
"<script>\n",
|
|
"\n",
|
|
" var options = {"animate": false, "animationControls": true, "aspectRatio": [1.0, 1.0, 1.0], "autoScaling": [false, false, false], "autoPlay": true, "axes": false, "axesLabels": ["x", "y", "z"], "axesLabelsStyle": null, "decimals": 2, "delay": 20, "frame": true, "loop": true, "projection": "perspective", "theme": "light", "viewpoint": false};\n",
|
|
" var animate = options.animate;\n",
|
|
"\n",
|
|
" if ( options.theme === 'dark' )\n",
|
|
" document.body.className = 'dark-theme';\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( options.theme === 'dark' ? 0 : 0xffffff, 1 );\n",
|
|
" document.body.appendChild( renderer.domElement );\n",
|
|
"\n",
|
|
" var b = [{"x":-0.05706339097770922, "y":-0.048541019662496854, "z":-0.05999999999999995}, {"x":5.0, "y":3.0, "z":4.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 rxRange = Math.sqrt( Math.pow( b[1].z - b[0].z, 2 )\n",
|
|
" + Math.pow( b[1].y - b[0].y, 2 ) );\n",
|
|
" var ryRange = Math.sqrt( Math.pow( b[1].x - b[0].x, 2 )\n",
|
|
" + Math.pow( b[1].z - b[0].z, 2 ) );\n",
|
|
" var rzRange = 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",
|
|
"\n",
|
|
" var autoScaling = options.autoScaling;\n",
|
|
" var autoAspect = 2.5;\n",
|
|
" if ( xRange > autoAspect * rxRange && autoScaling[0] ) a[0] = autoAspect * rxRange / xRange;\n",
|
|
" if ( yRange > autoAspect * ryRange && autoScaling[1] ) a[1] = autoAspect * ryRange / yRange;\n",
|
|
" if ( zRange > autoAspect * rzRange && autoScaling[2] ) a[2] = autoAspect * rzRange / 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",
|
|
" var boxColor = options.theme === 'dark' ? 'white' : 'black';\n",
|
|
" if ( options.frame ) scene.add( new THREE.BoxHelper( boxMesh, boxColor ) );\n",
|
|
"\n",
|
|
" if ( options.axesLabels ) {\n",
|
|
"\n",
|
|
" var d = options.decimals; // decimals\n",
|
|
" var offsetRatio = 0.1;\n",
|
|
" var al = options.axesLabels;\n",
|
|
" var als = options.axesLabelsStyle || [{}, {}, {}];\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, als[0] );\n",
|
|
" addLabel( ( b[0].x ).toFixed(d), a[0]*b[0].x, a[1]*b[1].y+offset, a[2]*b[0].z, als[0] );\n",
|
|
" addLabel( ( b[1].x ).toFixed(d), a[0]*b[1].x, a[1]*b[1].y+offset, a[2]*b[0].z, als[0] );\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, als[1] );\n",
|
|
" addLabel( ( b[0].y ).toFixed(d), a[0]*b[1].x+offset, a[1]*b[0].y, a[2]*b[0].z, als[1] );\n",
|
|
" addLabel( ( b[1].y ).toFixed(d), a[0]*b[1].x+offset, a[1]*b[1].y, a[2]*b[0].z, als[1] );\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, als[2] );\n",
|
|
" addLabel( ( b[0].z ).toFixed(d), a[0]*b[1].x, a[1]*b[0].y-offset, a[2]*b[0].z, als[2] );\n",
|
|
" addLabel( ( b[1].z ).toFixed(d), a[0]*b[1].x, a[1]*b[0].y-offset, a[2]*b[1].z, als[2] );\n",
|
|
"\n",
|
|
" }\n",
|
|
"\n",
|
|
" function addLabel( text, x, y, z, style ) {\n",
|
|
"\n",
|
|
" var color = style.color || 'black';\n",
|
|
" var fontSize = style.fontSize || 14;\n",
|
|
" var fontFamily = style.fontFamily || 'monospace';\n",
|
|
" var fontStyle = style.fontStyle || 'normal';\n",
|
|
" var fontWeight = style.fontWeight || 'normal';\n",
|
|
" var opacity = style.opacity || 1;\n",
|
|
"\n",
|
|
" if ( options.theme === 'dark' )\n",
|
|
" if ( color === 'black' || color === '#000000' )\n",
|
|
" color = 'white';\n",
|
|
"\n",
|
|
" if ( Array.isArray( fontStyle ) ) {\n",
|
|
" fontFamily = fontFamily.map( function( f ) {\n",
|
|
" // Need to put quotes around fonts that have whitespace in their names.\n",
|
|
" return /\\s/.test( f ) ? '"' + f + '"' : f;\n",
|
|
" }).join(', ');\n",
|
|
" }\n",
|
|
"\n",
|
|
" var canvas = document.createElement( 'canvas' );\n",
|
|
" var context = canvas.getContext( '2d' );\n",
|
|
" var pixelRatio = Math.round( window.devicePixelRatio );\n",
|
|
"\n",
|
|
" // For example: italic bold 20px "Times New Roman", Georgia, serif\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, depthWrite: 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",
|
|
" // camera is positioned so that the line from the camera to the center\n",
|
|
" // of the bounding sphere of the objects makes an angle of 60 degrees with x-axis\n",
|
|
" // and an angle of 30 degrees with z-axis and the field of view of the camera looking\n",
|
|
" // at the center has an angle of 45 degrees.\n",
|
|
" const sin8 = Math.sin(Math.PI / 8);\n",
|
|
" const sin5 = Math.sin(Math.PI / 5);\n",
|
|
" const cos5 = Math.cos(Math.PI / 5);\n",
|
|
" const sin3 = Math.sin(Math.PI / 3);\n",
|
|
" const cos3 = Math.cos(Math.PI / 3);\n",
|
|
" var r = midToCorner / sin8;\n",
|
|
" var offset = new THREE.Vector3( r * sin3 * cos5, r * sin3 * sin5, r * cos3 );\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",
|
|
" // Scale the near and far clipping planes along with the overall plot size.\n",
|
|
" var nearClip = 0.01 * midToCorner;\n",
|
|
" var farClip = 100 * midToCorner;\n",
|
|
"\n",
|
|
" if ( options.projection === 'orthographic' ) {\n",
|
|
" var camera = new THREE.OrthographicCamera( -1, 1, 1, -1, -farClip, farClip );\n",
|
|
" updateCameraAspect( camera, aspect );\n",
|
|
" return camera;\n",
|
|
" }\n",
|
|
"\n",
|
|
" return new THREE.PerspectiveCamera( 45, aspect, nearClip, farClip );\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 = [{"x":-5, "y":3, "z":0, "color":"#7f7f7f", "parent":"camera"}];\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 = {"color":"#7f7f7f"};\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 ( window.rescaleFatLines ) rescaleFatLines();\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",
|
|
" var sprite = addLabel( json.text, a[0]*json.x, a[1]*json.y, a[2]*json.z, json );\n",
|
|
" sprite.userData = json;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var points = [{"point": [0.0, 0.0, 3.0], "size": 10.0, "color": "#0000ff", "opacity": 1.0}, {"point": [0.0, 2.0, 1.0], "size": 10.0, "color": "#0000ff", "opacity": 1.0}, {"point": [4.0, 0.0, 0.0], "size": 10.0, "color": "#0000ff", "opacity": 1.0}, {"point": [2.0, 0.0, 1.0], "size": 10.0, "color": "#0000ff", "opacity": 1.0}, {"point": [0.0, 0.0, 3.0], "size": 30.0, "color": "#ff0000", "opacity": 1.0}, {"point": [0.0, 2.0, 1.0], "size": 30.0, "color": "#ff0000", "opacity": 1.0}, {"point": [2.0, 0.0, 1.0], "size": 30.0, "color": "#ff0000", "opacity": 1.0}, {"point": [4.0, 0.0, 0.0], "size": 30.0, "color": "#ff0000", "opacity": 1.0}, {"point": [0.0, 0.0, 0.0], "size": 30.0, "color": "#000000", "opacity": 1.0}];\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 = [{"points": [[0.0, 0.0, 3.0], [0.0, 2.0, 1.0]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"points": [[0.0, 0.0, 3.0], [2.0, 0.0, 1.0]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"points": [[0.0, 2.0, 1.0], [4.0, 0.0, 0.0]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"points": [[0.0, 2.0, 1.0], [2.0, 0.0, 1.0]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"points": [[4.0, 0.0, 0.0], [2.0, 0.0, 1.0]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}];\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 c = new THREE.Vector3();\n",
|
|
" geometry.computeBoundingBox();\n",
|
|
" geometry.boundingBox.getCenter( c );\n",
|
|
" geometry.translate( -c.x, -c.y, -c.z );\n",
|
|
"\n",
|
|
" var transparent = json.opacity < 1 ? true : false;\n",
|
|
" var materialOptions = { color: json.color, linewidth: json.linewidth,\n",
|
|
" transparent: transparent, opacity: json.opacity };\n",
|
|
"\n",
|
|
" var mesh;\n",
|
|
" if ( json.linewidth > 1 && window.createFatLineStrip ) {\n",
|
|
" mesh = createFatLineStrip( geometry, materialOptions );\n",
|
|
" } else {\n",
|
|
" var material = new THREE.LineBasicMaterial( materialOptions );\n",
|
|
" mesh = new THREE.Line( geometry, material );\n",
|
|
" }\n",
|
|
"\n",
|
|
" mesh.position.set( c.x, c.y, c.z );\n",
|
|
" mesh.userData = json;\n",
|
|
" scene.add( mesh );\n",
|
|
"\n",
|
|
" }\n",
|
|
"\n",
|
|
" var surfaces = [{"vertices": [{"x": 0.0, "y": 0.0, "z": 3.8200000000000003}, {"x": 0.019021130325903073, "y": 0.006180339887498949, "z": 3.8200000000000003}, {"x": 0.0, "y": 0.02, "z": 3.8200000000000003}, {"x": 0.011755705045849465, "y": -0.016180339887498948, "z": 3.8200000000000003}, {"x": -0.011755705045849461, "y": -0.01618033988749895, "z": 3.8200000000000003}, {"x": -0.019021130325903073, "y": 0.006180339887498945, "z": 3.8200000000000003}, {"x": 0.019021130325903073, "y": 0.006180339887498949, "z": 3.0}, {"x": 0.0, "y": 0.02, "z": 3.0}, {"x": 0.011755705045849465, "y": -0.016180339887498948, "z": 3.0}, {"x": -0.011755705045849461, "y": -0.01618033988749895, "z": 3.0}, {"x": -0.019021130325903073, "y": 0.006180339887498945, "z": 3.0}, {"x": 0.0, "y": 0.0, "z": 3.0}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6, 7], [1, 3, 8, 6], [3, 4, 9, 8], [4, 5, 10, 9], [5, 2, 7, 10], [7, 6, 11], [6, 8, 11], [8, 9, 11], [9, 10, 11], [10, 7, 11]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 0.0, "y": 0.0, "z": 4.0}, {"x": 0.05706339097770921, "y": 0.018541019662496848, "z": 3.8200000000000003}, {"x": 0.0, "y": 0.06, "z": 3.8200000000000003}, {"x": 0.03526711513754839, "y": -0.04854101966249684, "z": 3.8200000000000003}, {"x": -0.03526711513754838, "y": -0.048541019662496854, "z": 3.8200000000000003}, {"x": -0.05706339097770922, "y": 0.018541019662496834, "z": 3.8200000000000003}, {"x": 0.0, "y": 0.0, "z": 3.8200000000000003}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6], [1, 3, 6], [3, 4, 6], [4, 5, 6], [5, 2, 6]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 0.0, "y": 2.8200000000000003, "z": 1.0}, {"x": 0.019021130325903073, "y": 2.8200000000000003, "z": 0.9938196601125011}, {"x": 0.0, "y": 2.8200000000000003, "z": 0.9800000000000001}, {"x": 0.011755705045849465, "y": 2.8200000000000003, "z": 1.016180339887499}, {"x": -0.011755705045849461, "y": 2.8200000000000003, "z": 1.016180339887499}, {"x": -0.019021130325903073, "y": 2.8200000000000003, "z": 0.9938196601125011}, {"x": 0.019021130325903073, "y": 2.0, "z": 0.993819660112501}, {"x": 0.0, "y": 2.0, "z": 0.98}, {"x": 0.011755705045849465, "y": 2.0, "z": 1.016180339887499}, {"x": -0.011755705045849461, "y": 2.0, "z": 1.016180339887499}, {"x": -0.019021130325903073, "y": 2.0, "z": 0.993819660112501}, {"x": 0.0, "y": 2.0, "z": 1.0}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6, 7], [1, 3, 8, 6], [3, 4, 9, 8], [4, 5, 10, 9], [5, 2, 7, 10], [7, 6, 11], [6, 8, 11], [8, 9, 11], [9, 10, 11], [10, 7, 11]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 0.0, "y": 3.0000000000000004, "z": 1.0}, {"x": 0.05706339097770921, "y": 2.8200000000000003, "z": 0.9814589803375031}, {"x": 0.0, "y": 2.8200000000000003, "z": 0.94}, {"x": 0.03526711513754839, "y": 2.8200000000000003, "z": 1.048541019662497}, {"x": -0.03526711513754838, "y": 2.8200000000000003, "z": 1.048541019662497}, {"x": -0.05706339097770922, "y": 2.8200000000000003, "z": 0.9814589803375031}, {"x": 0.0, "y": 2.8200000000000003, "z": 1.0}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6], [1, 3, 6], [3, 4, 6], [4, 5, 6], [5, 2, 6]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 4.0, "y": 0.8200000000000001, "z": 5.021051876504149e-17}, {"x": 4.019021130325903, "y": 0.8200000000000001, "z": -0.006180339887498899}, {"x": 4.0, "y": 0.8200000000000001, "z": -0.019999999999999952}, {"x": 4.011755705045849, "y": 0.8200000000000001, "z": 0.016180339887498996}, {"x": 3.9882442949541503, "y": 0.8200000000000001, "z": 0.016180339887499}, {"x": 3.980978869674097, "y": 0.8200000000000001, "z": -0.006180339887498895}, {"x": 4.019021130325903, "y": 3.7843667304341507e-19, "z": -0.006180339887498949}, {"x": 4.0, "y": 1.2246467991473532e-18, "z": -0.02}, {"x": 4.011755705045849, "y": -9.907600726170915e-19, "z": 0.016180339887498948}, {"x": 3.9882442949541503, "y": -9.907600726170917e-19, "z": 0.01618033988749895}, {"x": 3.980978869674097, "y": 3.784366730434148e-19, "z": -0.006180339887498945}, {"x": 4.0, "y": 0.0, "z": 0.0}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6, 7], [1, 3, 8, 6], [3, 4, 9, 8], [4, 5, 10, 9], [5, 2, 7, 10], [7, 6, 11], [6, 8, 11], [8, 9, 11], [9, 10, 11], [10, 7, 11]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 4.0, "y": 1.0, "z": 6.123233995736767e-17}, {"x": 4.057063390977709, "y": 0.8200000000000001, "z": -0.0185410196624968}, {"x": 4.0, "y": 0.8200000000000001, "z": -0.05999999999999995}, {"x": 4.0352671151375485, "y": 0.8200000000000001, "z": 0.04854101966249689}, {"x": 3.9647328848624515, "y": 0.8200000000000001, "z": 0.0485410196624969}, {"x": 3.942936609022291, "y": 0.8200000000000001, "z": -0.018541019662496785}, {"x": 4.0, "y": 0.8200000000000001, "z": 5.021051876504149e-17}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6], [1, 3, 6], [3, 4, 6], [4, 5, 6], [5, 2, 6]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 4.82, "y": 0.0, "z": 5.021051876504149e-17}, {"x": 4.82, "y": 0.006180339887498949, "z": -0.019021130325903024}, {"x": 4.82, "y": 0.02, "z": 5.021051876504149e-17}, {"x": 4.82, "y": -0.016180339887498948, "z": -0.011755705045849415}, {"x": 4.82, "y": -0.01618033988749895, "z": 0.011755705045849512}, {"x": 4.82, "y": 0.006180339887498945, "z": 0.01902113032590312}, {"x": 4.0, "y": 0.006180339887498949, "z": -0.019021130325903073}, {"x": 4.0, "y": 0.02, "z": 0.0}, {"x": 4.0, "y": -0.016180339887498948, "z": -0.011755705045849465}, {"x": 4.0, "y": -0.01618033988749895, "z": 0.011755705045849461}, {"x": 4.0, "y": 0.006180339887498945, "z": 0.019021130325903073}, {"x": 4.0, "y": 0.0, "z": 0.0}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6, 7], [1, 3, 8, 6], [3, 4, 9, 8], [4, 5, 10, 9], [5, 2, 7, 10], [7, 6, 11], [6, 8, 11], [8, 9, 11], [9, 10, 11], [10, 7, 11]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 5.0, "y": 0.0, "z": 6.123233995736767e-17}, {"x": 4.82, "y": 0.018541019662496848, "z": -0.05706339097770916}, {"x": 4.82, "y": 0.06, "z": 5.021051876504149e-17}, {"x": 4.82, "y": -0.04854101966249684, "z": -0.03526711513754834}, {"x": 4.82, "y": -0.048541019662496854, "z": 0.035267115137548426}, {"x": 4.82, "y": 0.018541019662496834, "z": 0.057063390977709266}, {"x": 4.82, "y": 0.0, "z": 5.021051876504149e-17}], "faces": [[0, 1, 2], [0, 3, 1], [0, 4, 3], [0, 5, 4], [0, 2, 5], [2, 1, 6], [1, 3, 6], [3, 4, 6], [4, 5, 6], [5, 2, 6]], "color": "#0000ff", "opacity": 1.0, "linewidth": 1.0}, {"vertices": [{"x": 0.0, "y": 0.0, "z": 3.0}, {"x": 0.0, "y": 2.0, "z": 1.0}, {"x": 4.0, "y": 0.0, "z": 0.0}, {"x": 2.0, "y": 0.0, "z": 1.0}, {"x": 0.0, "y": 0.0, "z": 4.0}, {"x": 0.0, "y": 3.0, "z": 1.0}, {"x": 4.0, "y": 1.0, "z": 0.0}, {"x": 5.0, "y": 0.0, "z": 0.0}], "faces": [[7, 2, 3, 0, 4], [3, 0, 1], [4, 0, 1, 5], [2, 6, 5, 1], [6, 2, 7], [3, 1, 2]], "color": "#008000", "opacity": 1.0, "useFlatShading": true}];\n",
|
|
" 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 depthWrite = 'depthWrite' in json ? json.depthWrite : !transparent;\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",
|
|
" depthWrite: depthWrite } );\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 ) addSurfaceMeshGrid( json );\n",
|
|
"\n",
|
|
" }\n",
|
|
"\n",
|
|
" function addSurfaceMeshGrid( json ) {\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 c = new THREE.Vector3();\n",
|
|
" geometry.computeBoundingBox();\n",
|
|
" geometry.boundingBox.getCenter( c );\n",
|
|
" geometry.translate( -c.x, -c.y, -c.z );\n",
|
|
"\n",
|
|
" var gridColor = options.theme === 'dark' ? 'white' : 'black';\n",
|
|
" var linewidth = json.linewidth || 1;\n",
|
|
" var materialOptions = { color: gridColor, linewidth: linewidth };\n",
|
|
"\n",
|
|
" var mesh;\n",
|
|
" if ( linewidth > 1 && window.createFatLineSegments ) {\n",
|
|
" mesh = createFatLineSegments( geometry, materialOptions );\n",
|
|
" } else {\n",
|
|
" var material = new THREE.LineBasicMaterial( materialOptions );\n",
|
|
" mesh = new THREE.LineSegments( geometry, material );\n",
|
|
" }\n",
|
|
"\n",
|
|
" mesh.position.set( c.x, c.y, c.z );\n",
|
|
" mesh.userData = json;\n",
|
|
" scene.add( mesh );\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 = suggestFilename();\n",
|
|
" a.click();\n",
|
|
"\n",
|
|
" function suggestFilename() {\n",
|
|
" if ( !document.title ) {\n",
|
|
" return 'graphic.html';\n",
|
|
" } else if ( /\\.html?$/i.test( document.title ) ) {\n",
|
|
" return document.title; // already ends in .htm or .html\n",
|
|
" } else {\n",
|
|
" return document.title + '.html';\n",
|
|
" }\n",
|
|
" }\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",
|
|
" function getCamera() {\n",
|
|
"\n",
|
|
" function roundTo( x, n ) { return +x.toFixed(n); }\n",
|
|
"\n",
|
|
" var pos = camera.position;\n",
|
|
" var pos_r = [ roundTo( pos.x, 4 ), roundTo( pos.y, 4 ), roundTo( pos.z, 4 ) ];\n",
|
|
" // var up = camera.up; // up is always (0,0,1)\n",
|
|
" var textArea = document.createElement('textarea');\n",
|
|
" var cam_position = JSON.stringify(pos_r);\n",
|
|
" textArea.textContent = ',camera_position=' + cam_position;\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 = 'Camera position '+ cam_position+' 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="menu-container" onclick="toggleMenu()">&#x24d8;\n",
|
|
"<div id="menu-message"></div>\n",
|
|
"<div id="menu-content">\n",
|
|
"<div onclick="saveAsPNG()">Save as PNG</div>\n",
|
|
"<div onclick="saveAsHTML()">Save as HTML</div>\n",
|
|
"<div onclick="getCamera()">Get camera</div>\n",
|
|
"<div onclick="getViewpoint()">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": 28,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"Zt.newton_plot()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 30,
|
|
"id": "974b2099-0fdb-42b4-829b-72b6e0a7b38b",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Newton's polyhedron of z^3 - 3*y^2*z + 3*x^2*z + 2*x^4:\n",
|
|
" support points = [(0, 0, 3), (0, 2, 1), (2, 0, 1), (4, 0, 0)]\n",
|
|
" vertices = [(0, 0, 3), (0, 2, 1), (2, 0, 1), (4, 0, 0)]\n",
|
|
" number of compact faces = 11\n",
|
|
" Facet 1: -4 + 2*z + y + x >= 0\n",
|
|
" Facet 4: -3 + z + y + x >= 0\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"Z.give_info_newton(compact=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 31,
|
|
"id": "7a653a38-c2f6-45e5-bf44-81173d1ede55",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Newton's polyhedron of z^3 - 3*y^2*z + t*x*z^2 + 3*x^2*z + 2*x^4:\n",
|
|
" support points = [(0, 0, 3), (0, 2, 1), (1, 0, 2), (2, 0, 1), (4, 0, 0)]\n",
|
|
" vertices = [(0, 0, 3), (0, 2, 1), (4, 0, 0), (2, 0, 1)]\n",
|
|
" number of compact faces = 11\n",
|
|
" Facet 0: -4 + 2*z + y + x >= 0\n",
|
|
" Facet 4: -3 + z + y + x >= 0\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"Zt.give_info_newton(compact=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"id": "448680b0-7998-4c7a-a400-f44bbed407bb",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"z^3 - 3*y^2*z + t*x*z^2 + 3*x^2*z + 2*x^4"
|
|
]
|
|
},
|
|
"execution_count": 32,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"Ft"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 48,
|
|
"id": "05705617-d0f6-464a-a9a0-4cefb5bce4d1",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"u^14 * (2*v + v^2 + u^3 + u^3*v)"
|
|
]
|
|
},
|
|
"execution_count": 48,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"nwt(f).factor()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 49,
|
|
"id": "4eb24e43-3a10-4db9-8502-8c62289a3fe7",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"u^24 * (1 + 6*u^3 + 6*u^3*v + 4*u^4*v^2 + 4*u^4*v^3 + u^4*v^4 + 15*u^6 + 30*u^6*v + 15*u^6*v^2 + 4*u^7*v + 6*u^7*v^2 + 2*u^7*v^3 + 20*u^9 + 60*u^9*v + 60*u^9*v^2 + 20*u^9*v^3 + u^10 + 2*u^10*v + u^10*v^2 + 15*u^12 + 60*u^12*v + 90*u^12*v^2 + 60*u^12*v^3 + 15*u^12*v^4 + 6*u^15 + 30*u^15*v + 60*u^15*v^2 + 60*u^15*v^3 + 30*u^15*v^4 + 6*u^15*v^5 + u^18 + 6*u^18*v + 15*u^18*v^2 + 20*u^18*v^3 + 15*u^18*v^4 + 6*u^18*v^5 + u^18*v^6)"
|
|
]
|
|
},
|
|
"execution_count": 49,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"nwt(g).factor()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 50,
|
|
"id": "28776340-947d-4ed6-a492-79f9341b9f18",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"(1 + v)^2 * u^14"
|
|
]
|
|
},
|
|
"execution_count": 50,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"nwt(f2).factor()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 39,
|
|
"id": "358b6044-7de1-4bfe-9e4f-283adfc93aca",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"(3/2) * (1 + v) * u^21 * (2*v + v^2 + u^3 + u^3*v)"
|
|
]
|
|
},
|
|
"execution_count": 39,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"nwt(g1).factor()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 40,
|
|
"id": "cda085bf-987d-44c2-8dbd-ae21afaa3251",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"(1 + v)^3 * u^21"
|
|
]
|
|
},
|
|
"execution_count": 40,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"nwt(g3).factor()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 41,
|
|
"id": "9684ce50-7ff0-4b4c-9580-497c3e3b3964",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"h1 = F1.discriminant(z)(x=u, y=v)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 42,
|
|
"id": "220532f1-226a-4898-9ff8-5f0344a7de16",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[(-27) * (v^2 - u^7) * (3965*v^4 + 2735*u^7*v^2 + 2048*u^14)]"
|
|
]
|
|
},
|
|
"execution_count": 42,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"Z1 = ZetaFunctions(h1)\n",
|
|
"[q.factor() for q in Z1.get_polyfaces_dictionary(compact=True) if q.number_of_terms() > 1]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"id": "17c661cd-7293-41a1-b9ec-2e71269ae582",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[(108) * u^21 * (3*v^2 - 2*u^3)]"
|
|
]
|
|
},
|
|
"execution_count": 20,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"h1a = S(h1(u=u^2, v=u^7 * (1 + v)) / u^21)\n",
|
|
"Z1a = ZetaFunctions(h1a)\n",
|
|
"[q.factor() for q in Z1a.get_polyfaces_dictionary(compact=True) if q.number_of_terms() > 1]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 55,
|
|
"id": "aa670fe5-7aa2-4b88-9e85-4351e528b2a1",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"Rt.<x, y, z, t> = QQ[]\n",
|
|
"Ft = Rt(F - 3 * f2(u=x, v=y) * t^2 * z + 2 * g1(u=x, v=y) * t + 2 * g3(u=x, v=y) * t^3)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 58,
|
|
"id": "198a37ca-5a9d-4fe4-8949-e9ca06d48119",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"J = Rt.ideal([Ft.derivative(a) for a in Rt.gens()[:-1]] + [Ft])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 66,
|
|
"id": "77792a73-db8e-43a5-93b7-dacb75f92c4f",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"Gt = Ft(z=z + y * t)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 67,
|
|
"id": "18ec2301-7665-436a-9a9c-e1070d99dfd1",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"3*y*z^2"
|
|
]
|
|
},
|
|
"execution_count": 67,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"Gt.derivative(t)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "0fa40cb1-67c3-40c4-bf4b-60dd202979d2",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "SageMath 10.5.beta3",
|
|
"language": "sage",
|
|
"name": "sagemath-devel"
|
|
},
|
|
"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.12.5"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|