Skip to content

Commit ff044f0

Browse files
authored
Merge pull request #12 from gl-vis/irregular-grid-cone-size
A few cone improvements
2 parents 8d0c829 + 3b3ef9d commit ff044f0

File tree

9 files changed

+3992
-155
lines changed

9 files changed

+3992
-155
lines changed

cone.js

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -169,33 +169,39 @@ module.exports = function(vectorfield, bounds) {
169169
var minX = 1/0, maxX = -1/0;
170170
var minY = 1/0, maxY = -1/0;
171171
var minZ = 1/0, maxZ = -1/0;
172-
var v2 = null;
172+
var p2 = null;
173+
var u2 = null;
173174
var positionVectors = [];
174-
var minSeparation = 1/0;
175+
var vectorScale = 1/0;
175176
for (var i = 0; i < positions.length; i++) {
176-
var v1 = positions[i];
177-
minX = Math.min(v1[0], minX);
178-
maxX = Math.max(v1[0], maxX);
179-
minY = Math.min(v1[1], minY);
180-
maxY = Math.max(v1[1], maxY);
181-
minZ = Math.min(v1[2], minZ);
182-
maxZ = Math.max(v1[2], maxZ);
177+
var p = positions[i];
178+
minX = Math.min(p[0], minX);
179+
maxX = Math.max(p[0], maxX);
180+
minY = Math.min(p[1], minY);
181+
maxY = Math.max(p[1], maxY);
182+
minZ = Math.min(p[2], minZ);
183+
maxZ = Math.max(p[2], maxZ);
183184
var u;
184185
if (meshgrid) {
185-
u = sampleMeshgrid(v1, vectors, meshgrid, true);
186+
u = sampleMeshgrid(p, vectors, meshgrid, true);
186187
} else {
187188
u = vectors[i];
188189
}
189190
if (V.length(u) > maxNorm) {
190191
maxNorm = V.length(u);
191192
}
192-
if (v2) {
193-
var separation = V.distance(v1, v2);
194-
if (separation < minSeparation) {
195-
minSeparation = separation;
196-
}
193+
if (i) {
194+
// Find vector scale [w/ units of time] using "successive" positions
195+
// (not "adjacent" with would be O(n^2)),
196+
//
197+
// The vector scale corresponds to the minimum "time" to travel across two
198+
// two adjacent positions at the average velocity of those two adjacent positions
199+
vectorScale = Math.min(vectorScale,
200+
2 * V.distance(p2, p) / (V.length(u2) + V.length(u))
201+
);
197202
}
198-
v2 = v1;
203+
p2 = p;
204+
u2 = u;
199205
positionVectors.push(u);
200206
}
201207
var minV = [minX, minY, minZ];
@@ -207,17 +213,14 @@ module.exports = function(vectorfield, bounds) {
207213
if (maxNorm === 0) {
208214
maxNorm = 1;
209215
}
216+
210217
// Inverted max norm would map vector with norm maxNorm to 1 coord space units in length
211218
var invertedMaxNorm = 1 / maxNorm;
212219

213-
if (!isFinite(minSeparation) || isNaN(minSeparation)) {
214-
minSeparation = 1.0;
220+
if (!isFinite(vectorScale) || isNaN(vectorScale)) {
221+
vectorScale = 1.0;
215222
}
216-
217-
// Inverted max norm multiplied scaled by smallest found vector position distance:
218-
// Maps a vector with norm maxNorm to minSeparation coord space units in length.
219-
// In practice, scales maxNorm vectors so that they are just long enough to reach the adjacent vector position.
220-
geo.vectorScale = invertedMaxNorm * minSeparation;
223+
geo.vectorScale = vectorScale;
221224

222225
var nml = vec3(0,1,0);
223226

example/cone_rossler.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
var createCamera = require('3d-view-controls')
2+
var getBounds = require('bound-points')
3+
var perspective = require('gl-mat4/perspective')
4+
var createAxes = require('gl-axes3d')
5+
var createSpikes = require('gl-spikes3d')
6+
var createSelect = require('gl-select-static')
7+
var getBounds = require('bound-points')
8+
var mouseChange = require('mouse-change')
9+
var createConePlot = require('../cone')
10+
var createMesh = createConePlot.createConeMesh;
11+
var data = require('./dataset-rossler.json');
12+
13+
var bounds = []
14+
15+
var conePlot = createConePlot({
16+
positions: data.positions,
17+
vectors: data.vectors,
18+
// uncomment to see visible cones
19+
//coneSize: 40,
20+
colormap: 'portland'
21+
}, bounds)
22+
23+
var canvas = document.createElement('canvas')
24+
document.body.appendChild(canvas)
25+
window.addEventListener('resize', require('canvas-fit')(canvas))
26+
var gl = canvas.getContext('webgl')
27+
28+
var camera = createCamera(canvas, {
29+
eye: [3,3,3],
30+
center: [0,0,0],
31+
zoomMax: 500,
32+
mode: 'turntable'
33+
})
34+
35+
36+
var mesh = createMesh(gl, conePlot)
37+
38+
var select = createSelect(gl, [canvas.width, canvas.height])
39+
var tickSpacing = 1;
40+
var ticks = bounds[0].map(function(v,i) {
41+
var arr = [];
42+
var firstTick = 0; //Math.ceil(bounds[0][i] / tickSpacing) * tickSpacing;
43+
var lastTick = 3; //Math.floor(bounds[1][i] / tickSpacing) * tickSpacing;
44+
for (var tick = firstTick; tick <= lastTick; tick += tickSpacing) {
45+
if (tick === -0) tick = 0;
46+
arr.push({x: tick, text: tick.toString()});
47+
}
48+
return arr;
49+
});
50+
var axes = createAxes(gl, { bounds: bounds, ticks: ticks })
51+
var spikes = createSpikes(gl, {
52+
bounds: bounds
53+
})
54+
var spikeChanged = false
55+
56+
mouseChange(canvas, function(buttons, x, y) {
57+
var pickData = select.query(x, canvas.height - y, 10)
58+
var pickResult = mesh.pick(pickData)
59+
if(pickResult) {
60+
spikes.update({
61+
position: pickResult.position,
62+
enabled: [true, true, true]
63+
})
64+
spikeChanged = true
65+
} else {
66+
spikeChanged = spikes.enabled[0]
67+
spikes.update({
68+
enabled: [false, false, false]
69+
})
70+
}
71+
})
72+
73+
function render() {
74+
requestAnimationFrame(render)
75+
76+
gl.enable(gl.DEPTH_TEST)
77+
78+
var needsUpdate = camera.tick()
79+
var cameraParams = {
80+
projection: perspective([], Math.PI/4, canvas.width/canvas.height, 0.1, 300),
81+
view: camera.matrix
82+
}
83+
84+
if(needsUpdate || spikeChanged) {
85+
gl.bindFramebuffer(gl.FRAMEBUFFER, null)
86+
gl.viewport(0, 0, canvas.width, canvas.height)
87+
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
88+
axes.draw(cameraParams)
89+
spikes.draw(cameraParams)
90+
mesh.draw(cameraParams)
91+
spikeChanged = false
92+
}
93+
94+
if(needsUpdate) {
95+
select.shape = [canvas.width, canvas.height]
96+
select.begin()
97+
mesh.drawPick(cameraParams)
98+
select.end()
99+
}
100+
}
101+
render()

0 commit comments

Comments
 (0)