Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Rapid Prototyping Lab
JavaScript Modules
Gerstner Wave
Commits
7f2343b9
Commit
7f2343b9
authored
Oct 19, 2019
by
loelkes
Browse files
Waves Version 2. Documentation.
parent
bff57434
Changes
4
Hide whitespace changes
Inline
Side-by-side
README.md
0 → 100644
View file @
7f2343b9
# Gerstner Wave Simulation

## API
### Wave
```
wave = new Wave( scaling, direction, speed, height, lambda )```
* scaling : THREE.Vector3. This defines the size of the field to emulate the wave in.
* direction : THREE.Vector3. Sets the direction of propgation of the wave.
* speed : float. Propagation speed.
* height : float. Height of the wave.
* lambda : float. Wavelenght relative to the scaling.
#### Properties
* ```.scaling : THREE.Vector3``` defines the size of the field.
* ```.direction : THREE.Vector3```. Propgation direction of the wave.
#### Methods
* ```.getParticle( particle )```
* ```.update()```
### MultipleWaves
```
sea = new MultipleWaves( scaling )
```
* scaling : THREE.Vector3. This defines the size of the field to emulate the wave in.
#### Properties
* ```
.scaling : THREE.Vector3
``` defines the size of the field.
#### Methods
* ```
.example()
```
* ```
.addWave( direction, height, speed, lambda )
```
* ```
.getParticle( particle )
```
* ```
.update()
```
## Related
*
[
Trochoidal wave
](
https://en.wikipedia.org/wiki/Trochoidal_wave
)
on Wikipedia.org
js/Wave.js
View file @
7f2343b9
...
...
@@ -19,96 +19,118 @@
// SOFTWARE.
class
Wave
{
constructor
(
x
,
z
,
dir
,
speed
=
1
,
height
=
1
,
waveLength
=
1
)
{
this
.
version
=
1
;
constructor
(
scaling
,
direction
,
speed
,
height
,
lambda
)
{
this
.
version
=
2
;
console
.
groupCollapsed
(
'
Gernster Wave. Version:
'
,
this
.
version
);
console
.
debug
(
'
Dimesions:
'
,
x
,
z
,
'
(x, z)
'
);
console
.
debug
(
'
Direction:
'
,
dir
+
'
°
'
)
console
.
debug
(
'
Parameters:
'
,
speed
,
height
,
waveLength
,
'
(Speed, Height, Wavelength)
'
);
console
.
debug
(
'
Parameters:
'
,
speed
,
height
,
lambda
,
'
(Speed, Height, lambda)
'
);
console
.
groupEnd
();
// x : dimension in X-axis
// z : dimension in Z-axis
// dir: direction in degrees, rotation around Y-axis
this
.
xSize
=
x
;
this
.
zSize
=
z
;
this
.
height
=
height
;
this
.
speed
=
speed
;
this
.
waveLength
=
waveLength
;
this
.
direction
=
new
THREE
.
Vector3
(
1
,
0
,
0
)
;
this
.
direction
.
applyAxisAngle
(
new
THREE
.
Vector3
(
0
,
1
,
0
),
THREE
.
Math
.
DEG2RAD
*
dir
)
;
this
.
lambda
=
lambda
;
this
.
direction
=
direction
;
this
.
scaling
=
scaling
;
this
.
t
=
0
;
return
;
}
set
direction
(
vect
)
{
if
(
vect
instanceof
THREE
.
Vector3
){
this
.
_direction
=
vect
;
}
else
{
throw
new
Error
(
'
You must provide a THREE.Vector3 for direction.
'
);
}
}
update
(
millis
=
0
)
{
get
direction
()
{
return
this
.
_direction
;
}
set
scaling
(
vect
)
{
if
(
vect
instanceof
THREE
.
Vector3
){
this
.
_scaling
=
vect
;
}
else
{
throw
new
Error
(
'
You must provide a THREE.Vector3 for scaling.
'
);
}
}
get
scaling
()
{
return
this
.
_scaling
;
}
update
(
millis
=
0
)
{
if
(
millis
==
0
)
millis
=
Date
.
now
();
this
.
t
=
this
.
speed
*
0.001
*
millis
%
(
2
*
Math
.
PI
);
return
;
}
xOffset
(
particle
)
{
return
2
*
Math
.
PI
*
(
particle
.
x
/
this
.
xSize
)
*
this
.
direction
.
x
;
_xOffset
(
pos
)
{
return
2
*
Math
.
PI
*
(
pos
.
x
/
this
.
scaling
.
x
)
*
this
.
direction
.
x
;
}
zOffset
(
particle
)
{
return
2
*
Math
.
PI
*
(
particle
.
z
/
this
.
zSize
)
*
this
.
direction
.
z
;
_zOffset
(
pos
)
{
return
2
*
Math
.
PI
*
(
pos
.
z
/
this
.
scaling
.
z
)
*
this
.
direction
.
z
;
}
pOffset
(
particle
)
{
return
this
.
waveLength
*
(
this
.
xOffset
(
particle
)
+
this
.
zOffset
(
particle
)
);
_pOffset
(
pos
)
{
return
this
.
lambda
*
(
this
.
_xOffset
(
pos
)
+
this
.
_zOffset
(
pos
)
);
}
getParticle
(
particle
)
{
var
x
=
this
.
direction
.
x
*
Math
.
cos
(
(
-
this
.
t
+
this
.
pOffset
(
particle
)
)
);
var
z
=
this
.
direction
.
z
*
Math
.
cos
(
(
-
this
.
t
+
this
.
pOffset
(
particle
)
)
);
var
y
=
Math
.
sin
(
-
this
.
t
+
this
.
pOffset
(
particle
)
);
return
new
THREE
.
Vector3
(
x
,
y
,
z
).
multiplyScalar
(
this
.
height
);
if
(
particle
instanceof
THREE
.
Vector3
)
{
var
x
=
this
.
direction
.
x
*
Math
.
cos
(
this
.
_pOffset
(
particle
)
-
this
.
t
);
var
z
=
this
.
direction
.
z
*
Math
.
cos
(
this
.
_pOffset
(
particle
)
-
this
.
t
);
var
y
=
Math
.
sin
(
this
.
_pOffset
(
particle
)
-
this
.
t
);
return
new
THREE
.
Vector3
(
x
,
y
,
z
).
multiplyScalar
(
this
.
height
);
}
else
{
throw
new
Error
(
'
You must provide a THREE.Vector3 as particle position.
'
);
}
}
}
class
MultipleWaves
{
constructor
(
x
,
y
)
{
this
.
version
=
1
;
constructor
(
scaling
)
{
this
.
version
=
2
;
this
.
scaling
=
scaling
;
console
.
groupCollapsed
(
'
Multiple Waves. Version
'
,
this
.
version
);
console
.
groupEnd
();
this
.
waves
=
[
new
Wave
(
x
,
y
,
-
90
,
2
,
0.2
,
2
),
new
Wave
(
x
,
y
,
10
,
2
,
0.2
,
1
),
new
Wave
(
x
,
y
,
120
,
1
,
0.2
,
4
),
];
this
.
waves
=
[];
}
set
scaling
(
vect
)
{
if
(
vect
instanceof
THREE
.
Vector3
){
this
.
_scaling
=
vect
;
}
else
{
throw
new
Error
(
'
You must provide a THREE.Vector3 for scaling.
'
);
}
}
getParticle
(
particle
)
{
get
scaling
()
{
return
this
.
_scaling
;
}
example
()
{
this
.
addWave
(
-
90
,
0.2
,
2
,
2
);
this
.
addWave
(
10
,
0.2
,
2
,
1
);
this
.
addWave
(
120
,
0.3
,
1
,
4
);
}
addWave
(
direction
=
45
,
height
=
0.5
,
speed
=
2
,
lambda
=
2
)
{
var
dir
=
direction
;
if
(
!
(
direction
instanceof
THREE
.
Vector3
)
)
{
dir
=
new
THREE
.
Vector3
(
1
,
0
,
0
);
dir
.
applyAxisAngle
(
new
THREE
.
Vector3
(
0
,
1
,
0
),
direction
*
THREE
.
Math
.
DEG2RAD
);
}
this
.
waves
.
push
(
new
Wave
(
this
.
scaling
,
dir
,
speed
,
height
,
lambda
)
);
}
getParticle
(
particle
)
{
var
position
=
new
THREE
.
Vector3
();
for
(
var
wave
of
this
.
waves
)
position
.
add
(
wave
.
getParticle
(
particle
)
);
return
position
;
}
update
()
{
// Call this within the animation loop.
var
now
=
Date
.
now
();
for
(
var
wave
of
this
.
waves
)
wave
.
update
(
now
);
}
}
js/project.js
View file @
7f2343b9
...
...
@@ -29,34 +29,6 @@ var stats = true;
const
TwoPi
=
Math
.
PI
*
2
;
// class WireframeCube {
//
// constructor(size=25) {
// this.geometry = new THREE.BoxBufferGeometry( size, size, size );
// this.wireframe = new THREE.EdgesGeometry( this.geometry );
// this.material = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 1 } );
// this.mesh = new THREE.LineSegments( this.wireframe, this.material );
// }
//
// animate(offset) {
// this.rotationOffset = offset // new THREE.Vector3(0,0,0);
// this.rotation = new THREE.Vector3(0,0,0);
// this.rotation.add(this.rotationOffset);
// this.rotationTarget = new THREE.Vector3(0,TwoPi,0);
// this.rotationTarget.add(this.rotationOffset);
// this.mesh.userData.tween = new TWEEN.Tween(this.rotation).to(this.rotationTarget, 10000);
//
// function onUpdate() {
// this.mesh.rotation.setFromVector3(this.rotation);
// }
//
// this.mesh.userData.tween.onUpdate(onUpdate.bind(this));
// this.mesh.userData.tween.repeat(Infinity);
// this.mesh.userData.tween.start()
//
// }
// }
function
polarArray
(
r
,
count
)
{
let
output
=
[];
...
...
@@ -112,12 +84,8 @@ class PointGrid {
this
.
xres
=
100
;
this
.
zres
=
100
;
this
.
params
=
{
xc
:
this
.
xres
,
yc
:
1
,
zc
:
this
.
zres
,
xs
:
x
/
this
.
xres
,
ys
:
1
,
zs
:
z
/
this
.
zres
xc
:
this
.
xres
,
yc
:
1
,
zc
:
this
.
zres
,
xs
:
x
/
this
.
xres
,
ys
:
1
,
zs
:
z
/
this
.
zres
};
this
.
grid
=
XYArray
(
this
.
params
);
this
.
fill
();
...
...
@@ -137,19 +105,15 @@ class PointGrid {
this
.
group
.
add
(
cube
);
}
return
;
}
}
function
initWorld
()
{
var
i
=
0
;
let
x
=
2500
;
let
z
=
2500
;
wave
=
new
MultipleWaves
(
x
,
z
);
ptGrid
=
new
PointGrid
(
x
,
z
);
let
scale
=
new
THREE
.
Vector3
(
2500
,
0
,
2500
)
wave
=
new
MultipleWaves
(
scale
);
wave
.
example
();
ptGrid
=
new
PointGrid
(
scale
.
x
,
scale
.
z
);
scene
.
add
(
ptGrid
.
group
);
onRenderFcts
.
push
(
function
()
{
wave
.
update
();
for
(
var
particle
of
ptGrid
.
group
.
children
)
{
...
...
@@ -161,43 +125,31 @@ function initWorld() {
return
;
}
///
class
GUIControls
{
constructor
()
{
this
.
gui
=
new
dat
.
GUI
();
}
textFolder
(
target
)
{
this
.
textCtrl
=
this
.
gui
.
addFolder
(
'
Text
'
);
this
.
textCtrl
.
add
(
target
,
'
size
'
).
name
(
'
Size
'
);
this
.
textCtrl
.
add
(
target
,
'
height
'
).
name
(
'
Thickness
'
);
this
.
textCtrl
.
addColor
(
target
,
'
color
'
).
name
(
'
Color
'
);
}
cameraFolder
(
camera
)
{
cameraFolder
(
target
)
{
this
.
cameraCtrl
=
this
.
gui
.
addFolder
(
'
Camera
'
);
this
.
cameraCtrl
.
add
(
camera
.
position
,
'
y
'
).
name
(
'
Height
'
);
this
.
cameraCtrl
.
add
(
camera
.
rotation
,
'
x
'
,
-
Math
.
PI
/
4
,
0
).
name
(
'
Pitch
'
);
this
.
cameraCtrl
.
add
(
target
.
position
,
'
y
'
).
name
(
'
Height
'
);
this
.
cameraCtrl
.
add
(
target
.
rotation
,
'
x
'
,
-
Math
.
PI
/
4
,
0
).
name
(
'
Pitch
'
);
}
waveFolder
(
waves
)
{
waveFolder
(
target
)
{
this
.
waveCtrl
=
this
.
gui
.
addFolder
(
'
Waves
'
);
this
.
waveCtrl
.
add
(
waves
,
'
speed
'
,
0
,
20
).
name
(
'
Speed
'
);
this
.
waveCtrl
.
add
(
waves
,
'
height
'
,
0
,
100
).
name
(
'
Height
'
);
this
.
waveCtrl
.
add
(
waves
,
'
waveLength
'
,
10
,
50
).
name
(
'
Width
'
);
this
.
waveCtrl
.
add
(
target
,
'
speed
'
,
0
,
20
).
name
(
'
Speed
'
);
this
.
waveCtrl
.
add
(
target
,
'
height
'
,
0
,
100
).
name
(
'
Height
'
);
this
.
waveCtrl
.
add
(
target
,
'
waveLength
'
,
10
,
50
).
name
(
'
Width
'
);
this
.
waveCtrl
.
open
();
}
}
function
initRenderer
()
{
...
...
@@ -205,7 +157,7 @@ function initRenderer() {
renderer
=
new
THREE
.
WebGLRenderer
({
antialias
:
true
,
// Performance on older mobile devices.
precision
:
'
mediump
'
,
// Performance on older mobile devices.
alpha
:
true
,
// Display webcam image in background.
//
alpha: true, // Display webcam image in background.
// powerPreference: "low-power", // Mobile application.
logarithmicDepthBuffer
:
true
});
...
...
@@ -215,18 +167,15 @@ function initRenderer() {
renderer
.
setSize
(
window
.
innerWidth
,
window
.
innerHeight
);
document
.
body
.
appendChild
(
renderer
.
domElement
);
console
.
debug
(
'
OK: Initialized renderer.
'
);
}
initFcts
.
push
(
initRenderer
);
function
initStats
()
{
stats
=
new
Stats
();
stats
.
showPanel
(
0
);
// 0: fps, 1: ms, 2: mb, 3+: custom
document
.
body
.
appendChild
(
stats
.
dom
);
console
.
debug
(
'
OK: Initialized statistics.
'
);
}
if
(
stats
)
{
...
...
@@ -234,15 +183,6 @@ if( stats ) {
}
function
initCamera
()
{
// camera = new THREE.OrthographicCamera(
// - window.innerWidth / 2, // Left
// + window.innerWidth / 2, // Right
// + window.innerHeight / 2, // Top
// - window.innerHeight / 2, // Bottom
// 1, // Near
// 2000 // Far
// );
camera
=
new
THREE
.
PerspectiveCamera
(
45
,
window
.
innerWidth
/
window
.
innerHeight
,
...
...
@@ -251,17 +191,14 @@ function initCamera() {
camera
.
position
.
set
(
0
,
2000
,
3000
);
camera
.
lookAt
(
new
THREE
.
Vector3
()
);
console
.
debug
(
'
OK: Initialized camera.
'
);
}
initFcts
.
push
(
initCamera
);
function
initScene
()
{
scene
=
new
THREE
.
Scene
();
scene
.
add
(
new
THREE
.
AmbientLight
(
0xffffff
));
console
.
log
(
'
OK: Initialized scene.
'
);
}
initFcts
.
push
(
initScene
);
...
...
@@ -302,16 +239,13 @@ initFcts.push( initControls );
initFcts
.
push
(
initWorld
);
function
render
()
{
renderer
.
render
(
scene
,
camera
);
TWEEN
.
update
();
}
onRenderFcts
.
push
(
render
);
function
onWindowResize
()
{
camera
.
aspect
=
window
.
innerWidth
/
window
.
innerHeight
;
camera
.
updateProjectionMatrix
();
renderer
.
setSize
(
window
.
innerWidth
,
window
.
innerHeight
);
...
...
@@ -320,51 +254,19 @@ function onWindowResize() {
window
.
addEventListener
(
'
resize
'
,
onWindowResize
,
false
);
// ----------------------------------------------------------------------
// Helper functions
function
getRandomInt
(
min
,
max
)
{
// Maximum exclusive and minimum inclusive
min
=
Math
.
ceil
(
min
);
max
=
Math
.
floor
(
max
);
return
Math
.
floor
(
Math
.
random
()
*
(
max
-
min
)
)
+
min
;
}
function
getMaxOfArray
(
numArray
)
{
// Max value inside an array
return
Math
.
max
.
apply
(
null
,
numArray
);
}
function
getMinOfArray
(
numArray
)
{
// Min value inside an array
return
Math
.
min
.
apply
(
null
,
numArray
);
}
function
init
()
{
console
.
group
(
'
Intitialize all the things!
'
);
initFcts
.
forEach
(
function
(
initFct
)
{
initFct
();
});
console
.
groupEnd
();
}
function
animate
()
{
if
(
stats
)
{
stats
.
begin
();
}
if
(
stats
)
stats
.
begin
();
onRenderFcts
.
forEach
(
function
(
onRenderFct
)
{
onRenderFct
();
});
if
(
stats
)
{
stats
.
end
();
}
if
(
stats
)
stats
.
end
();
requestAnimationFrame
(
animate
);
// Animation frame
}
media/preview.png
0 → 100644
View file @
7f2343b9
119 KB
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment