You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
earthquake_3d_viewer_front/three/examples/webgl_multiple_elements_tex...

701 lines
14 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - multiple elements with text</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
<style>
* {
box-sizing: border-box;
-moz-box-sizing: border-box;
}
body {
background-color: #fff;
color: #444;
margin: auto;
padding: .5in;
max-width: 7in;
text-align: justify;
}
a {
color: #08f;
}
#info {
left: 0px;
}
.view {
width: 5in;
height: 5in;
margin: auto;
}
#c {
position: fixed;
left: 0px; top: 0px;
width: 100%;
height: 100%;
background-color: #fff;
z-index: -1;
}
</style>
</head>
<body>
<canvas id="c"></canvas>
<div id="info"><a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - multiple elements with text - webgl</div>
<script type="importmap">
{
"imports": {
"three": "../build/three.module.js",
"three/addons/": "./jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const scenes = [];
const clock = new THREE.Clock();
let views, t, canvas, renderer;
window.onload = init;
function init() {
const balls = 20;
const size = .25;
const colors = [
'rgb(0,127,255)', 'rgb(255,0,0)', 'rgb(0,255,0)', 'rgb(0,255,255)',
'rgb(255,0,255)', 'rgb(255,0,127)', 'rgb(255,255,0)', 'rgb(0,255,127)'
];
canvas = document.getElementById( 'c' );
renderer = new THREE.WebGLRenderer( { canvas: canvas, antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setAnimationLoop( animate );
views = document.querySelectorAll( '.view' );
for ( let n = 0; n < views.length; n ++ ) {
const scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
const geometry0 = new THREE.BufferGeometry();
const geometry1 = new THREE.BufferGeometry();
const vertices = [];
if ( views[ n ].lattice ) {
const range = balls / 2;
for ( let i = - range; i <= range; i ++ ) {
for ( let j = - range; j <= range; j ++ ) {
for ( let k = - range; k <= range; k ++ ) {
vertices.push( i, j, k );
}
}
}
} else {
for ( let m = 0; m < Math.pow( balls, 3 ); m ++ ) {
const i = balls * Math.random() - balls / 2;
const j = balls * Math.random() - balls / 2;
const k = balls * Math.random() - balls / 2;
vertices.push( i, j, k );
}
}
geometry0.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
geometry1.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices.slice(), 3 ) );
const index = Math.floor( colors.length * Math.random() );
const canvas2 = document.createElement( 'canvas' );
canvas2.width = 128;
canvas2.height = 128;
const context = canvas2.getContext( '2d' );
context.arc( 64, 64, 64, 0, 2 * Math.PI );
context.fillStyle = colors[ index ];
context.fill();
const texture = new THREE.CanvasTexture( canvas2 );
texture.colorSpace = THREE.SRGBColorSpace;
const material = new THREE.PointsMaterial( { size: size, map: texture, transparent: true, alphaTest: 0.1 } );
scene.add( new THREE.Points( geometry0, material ) );
scene.userData.view = views[ n ];
scene.userData.geometry1 = geometry1;
const camera = new THREE.PerspectiveCamera( 75, 1, 0.1, 100 );
camera.position.set( 0, 0, 1.2 * balls );
scene.userData.camera = camera;
const controls = new OrbitControls( camera, views[ n ] );
scene.userData.controls = controls;
scenes.push( scene );
}
t = 0;
animate();
}
function updateSize() {
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if ( canvas.width !== width || canvas.height != height ) {
renderer.setSize( width, height, false );
}
}
function animate() {
updateSize();
renderer.setClearColor( 0xffffff );
renderer.setScissorTest( false );
renderer.clear();
renderer.setClearColor( 0x000000 );
renderer.setScissorTest( true );
scenes.forEach( function ( scene ) {
const rect = scene.userData.view.getBoundingClientRect();
// check if it's offscreen. If so skip it
if ( rect.bottom < 0 || rect.top > renderer.domElement.clientHeight ||
rect.right < 0 || rect.left > renderer.domElement.clientWidth ) {
return; // it's off screen
}
// set the viewport
const width = rect.right - rect.left;
const height = rect.bottom - rect.top;
const left = rect.left;
const bottom = renderer.domElement.clientHeight - rect.bottom;
renderer.setViewport( left, bottom, width, height );
renderer.setScissor( left, bottom, width, height );
renderer.render( scene, scene.userData.camera );
const points = scene.children[ 0 ];
const position = points.geometry.attributes.position;
const point = new THREE.Vector3();
const offset = new THREE.Vector3();
for ( let i = 0; i < position.count; i ++ ) {
point.fromBufferAttribute( scene.userData.geometry1.attributes.position, i );
scene.userData.view.displacement( point.x, point.y, point.z, t / 5, offset );
position.setXYZ( i, point.x + offset.x, point.y + offset.y, point.z + offset.z );
}
position.needsUpdate = true;
} );
t += clock.getDelta() * 60;
}
</script>
<p>Sound waves whose geometry is determined by a single dimension, plane waves, obey the wave equation</p>
<math display="block">
<mfrac>
<mrow>
<msup>
<mi>&part;</mi>
<mn>2</mn>
</msup>
<mi>u</mi>
</mrow>
<mrow>
<mi>&part;</mi>
<msup>
<mi>r</mi>
<mn>2</mn>
</msup>
</mrow>
</mfrac>
<mo>&minus;</mo>
<mfrac>
<mn>1</mn>
<msup>
<mi>c</mi>
<mn>2</mn>
</msup>
</mfrac>
<mo>&sdot;</mo>
<mfrac>
<mrow>
<msup>
<mi>&part;</mi>
<mn>2</mn>
</msup>
<mi>u</mi>
</mrow>
<mrow>
<mi>&part;</mi>
<msup>
<mi>t</mi>
<mn>2</mn>
</msup>
</mrow>
</mfrac>
<mo>=</mo>
<mn>0</mn>
</math>
<p>where <math><mi>c</mi></math> designates the speed of sound in the medium. The monochromatic solution for plane waves will be taken to be</p>
<math display="block">
<mi>u</mi>
<mo>(</mo>
<mi>r</mi>
<mo>,</mo>
<mi>t</mi>
<mo>)</mo>
<mo>=</mo>
<mi>sin</mi>
<mo>(</mo>
<mi>k</mi>
<mi>r</mi>
<mo>&plusmn;</mo>
<mi>&omega;</mi>
<mi>t</mi>
<mo>)</mo>
</math>
<p>
where <math><mi>&omega;</mi></math> is the frequency and
<math>
<mi>k</mi>
<mo>=</mo>
<mi>&omega;</mi>
<mo>/</mo>
<mi>c</mi>
</math>
is the wave number. The sign chosen in the argument determines the direction of movement of the waves.
</p>
<p>Here is a plane wave moving on a three-dimensional lattice of atoms:</p>
<div class="view">
<script>
/* eslint-disable prefer-const*/
let parent = document.scripts[ document.scripts.length - 1 ].parentNode;
parent.displacement = function ( x, y, z, t, target ) {
return target.set( Math.sin( x - t ), 0, 0 );
};
parent.lattice = true;
</script>
</div>
<p>Here is a plane wave moving through a three-dimensional random distribution of molecules:</p>
<div class="view">
<script>
parent = document.scripts[ document.scripts.length - 1 ].parentNode;
parent.displacement = function ( x, y, z, t, target ) {
return target.set( Math.sin( x - t ), 0, 0 );
};
parent.lattice = false;
</script>
</div>
<p>Sound waves whose geometry is determined by two dimensions, cylindrical waves, obey the wave equation</p>
<math display="block">
<mfrac>
<mrow>
<msup>
<mi>&part;</mi>
<mn>2</mn>
</msup>
<mi>u</mi>
</mrow>
<mrow>
<mi>&part;</mi>
<msup>
<mi>r</mi>
<mn>2</mn>
</msup>
</mrow>
</mfrac>
<mo>+</mo>
<mfrac>
<mrow>
<mn>1</mn>
</mrow>
<mrow>
<mi>r</mi>
</mrow>
</mfrac>
<mo>&sdot;</mo>
<mfrac>
<mrow>
<mi>&part;</mi>
<mi>u</mi>
</mrow>
<mrow>
<mi>&part;</mi>
<mi>r</mi>
</mrow>
</mfrac>
<mo>&minus;</mo>
<mfrac>
<mrow>
<mn>1</mn>
</mrow>
<mrow>
<msup>
<mi>c</mi>
<mn>2</mn>
</msup>
</mrow>
</mfrac>
<mo>&sdot;</mo>
<mfrac>
<mrow>
<msup>
<mi>&part;</mi>
<mn>2</mn>
</msup>
<mi>u</mi>
</mrow>
<mrow>
<mi>&part;</mi>
<msup>
<mi>t</mi>
<mn>2</mn>
</msup>
</mrow>
</mfrac>
<mo>=</mo>
<mn>0</mn>
</math>
<p>The monochromatic solution for cylindrical sound waves will be taken to be</p>
<math display="block">
<mi>u</mi>
<mo stretchy="false">(</mo>
<mi>r</mi>
<mo>,</mo>
<mi>t</mi>
<mo stretchy="false">)</mo>
<mo>=</mo>
<mfrac>
<mrow>
<mi>sin</mi>
<mo>(</mo>
<mi>k</mi>
<mi>r</mi>
<mo>&plusmn;</mo>
<mi>&omega;</mi>
<mi>t</mi>
<mo>)</mo>
</mrow>
<mrow>
<msqrt>
<mi>r</mi>
</msqrt>
</mrow>
</mfrac>
</math>
<p>Here is a cylindrical wave moving on a three-dimensional lattice of atoms:</p>
<div class="view">
<script>
parent = document.scripts[ document.scripts.length - 1 ].parentNode;
parent.displacement = function ( x, y, z, t, target ) {
if ( x * x + y * y < 0.01 ) {
return target.set( 0, 0, 0 );
} else {
const rho = Math.sqrt( x * x + y * y );
const phi = Math.atan2( y, x );
return target.set( 1.5 * Math.cos( phi ) * Math.sin( rho - t ) / Math.sqrt( rho ), 1.5 * Math.sin( phi ) * Math.sin( rho - t ) / Math.sqrt( rho ), 0 );
}
};
parent.lattice = true;
</script>
</div>
<p>Here is a cylindrical wave moving through a three-dimensional random distribution of molecules:</p>
<div class="view">
<script>
parent = document.scripts[ document.scripts.length - 1 ].parentNode;
parent.displacement = function ( x, y, z, t, target ) {
if ( x * x + y * y < 0.01 ) {
return target.set( 0, 0, 0 );
} else {
const rho = Math.sqrt( x * x + y * y );
const phi = Math.atan2( y, x );
return target.set( 1.5 * Math.cos( phi ) * Math.sin( rho - t ) / Math.sqrt( rho ), 1.5 * Math.sin( phi ) * Math.sin( rho - t ) / Math.sqrt( rho ), 0 );
}
};
parent.lattice = false;
</script>
</div>
<p>Sound waves whose geometry is determined by three dimensions, spherical waves, obey the wave equation</p>
<math display="block">
<mfrac>
<mrow>
<msup>
<mi>&part;</mi>
<mn>2</mn>
</msup>
<mi>u</mi>
</mrow>
<mrow>
<mi>&part;</mi>
<msup>
<mi>r</mi>
<mn>2</mn>
</msup>
</mrow>
</mfrac>
<mo>+</mo>
<mfrac>
<mrow>
<mn>2</mn>
</mrow>
<mrow>
<mi>r</mi>
</mrow>
</mfrac>
<mo>&sdot;</mo>
<mfrac>
<mrow>
<mi>&part;</mi>
<mi>u</mi>
</mrow>
<mrow>
<mi>&part;</mi>
<mi>r</mi>
</mrow>
</mfrac>
<mo>&minus;</mo>
<mfrac>
<mrow>
<mn>1</mn>
</mrow>
<mrow>
<msup>
<mi>c</mi>
<mn>2</mn>
</msup>
</mrow>
</mfrac>
<mo>&sdot;</mo>
<mfrac>
<mrow>
<msup>
<mi>&part;</mi>
<mn>2</mn>
</msup>
<mi>u</mi>
</mrow>
<mrow>
<mi>&part;</mi>
<msup>
<mi>t</mi>
<mn>2</mn>
</msup>
</mrow>
</mfrac>
<mo>=</mo>
<mn>0</mn>
</math>
<p>The monochromatic solution for spherical sound waves will be taken to be</p>
<math display="block">
<mi>u</mi>
<mo stretchy="false">(</mo>
<mi>r</mi>
<mo>,</mo>
<mi>t</mi>
<mo stretchy="false">)</mo>
<mo>=</mo>
<mfrac>
<mrow>
<mi>sin</mi>
<mo>(</mo>
<mi>k</mi>
<mi>r</mi>
<mo>&plusmn;</mo>
<mi>&omega;</mi>
<mi>t</mi>
<mo>)</mo>
</mrow>
<mrow>
<mi>r</mi>
</mrow>
</mfrac>
</math>
<p>Here is a spherical wave moving on a three-dimensional lattice of atoms:</p>
<div class="view">
<script>
parent = document.scripts[ document.scripts.length - 1 ].parentNode;
parent.displacement = function ( x, y, z, t, target ) {
if ( x * x + y * y + z * z < 0.01 ) {
return target.set( 0, 0, 0 );
} else {
const r = Math.sqrt( x * x + y * y + z * z );
const theta = Math.acos( z / r );
const phi = Math.atan2( y, x );
return target.set( 3 * Math.cos( phi ) * Math.sin( theta ) * Math.sin( r - t ) / r, 3 * Math.sin( phi ) * Math.sin( theta ) * Math.sin( r - t ) / r, 3 * Math.cos( theta ) * Math.sin( r - t ) / r );
}
};
parent.lattice = true;
</script>
</div>
<p>Here is a spherical wave moving through a three-dimensional random distribution of molecules:</p>
<div class="view">
<script>
parent = document.scripts[ document.scripts.length - 1 ].parentNode;
parent.displacement = function ( x, y, z, t, target ) {
if ( x * x + y * y + z * z < 0.01 ) {
return target.set( 0, 0, 0 );
} else {
const r = Math.sqrt( x * x + y * y + z * z );
const theta = Math.acos( z / r );
const phi = Math.atan2( y, x );
return target.set( 3 * Math.cos( phi ) * Math.sin( theta ) * Math.sin( r - t ) / r, 3 * Math.sin( phi ) * Math.sin( theta ) * Math.sin( r - t ) / r, 3 * Math.cos( theta ) * Math.sin( r - t ) / r );
}
};
parent.lattice = false;
</script>
</div>
<p>The mathematical description of sound waves can be carried to higher dimensions, but one needs to wait for Four.js and its higher-dimensional successors to attempt visualizations.</p>
</body>
</html>