UNPKG

12.8 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = {}));
5}(this, (function (exports) { 'use strict';
6
7 function ccw(polygon) {
8
9 var _p = polygon.slice(0), sum = 0;
10
11 _p.push(_p[0]);
12
13 for (var i = 0; i <= polygon.length - 1; i++) {
14
15 var j = i + 1;
16 var p1 = _p[i].rotated;
17 var p2 = _p[j].rotated;
18
19 sum += (p2.x - p1.x) * (p2.y + p1.y);
20 }
21 // if the area is positive
22 // the curve is counter-clockwise
23 // because of the flipped y-Axis in the browser
24 return sum > 0 ? true : false;
25 }
26
27 function centroid(polygon){
28 var _x = 0, _y = 0, _z = 0, _n = polygon.length;
29
30 for (var i = _n - 1; i >= 0; i--) {
31 _x += polygon[i].rotated.x;
32 _y += polygon[i].rotated.y;
33 _z += polygon[i].rotated.z;
34 }
35
36 return {
37 x: _x / _n,
38 y: _y / _n,
39 z: _z / _n,
40 };
41 }
42
43 function rotateRzRyRx(po, angles){
44
45 var rc = angles.rotateCenter;
46
47 po.x -= rc[0];
48 po.y -= rc[1];
49 po.z -= rc[2];
50
51 var rz = rotateZ(po, angles.z);
52 var ry = rotateY(rz, angles.y);
53 var rx = rotateX(ry, angles.x);
54
55 rx.x += rc[0];
56 rx.y += rc[1];
57 rx.z += rc[2];
58
59 return rx;
60 }
61
62 function rotateX(p, a){
63 var sa = Math.sin(a), ca = Math.cos(a);
64 return {
65 x: p.x,
66 y: p.y * ca - p.z * sa,
67 z: p.y * sa + p.z * ca
68 };
69 }
70
71 function rotateY(p, a){
72 var sa = Math.sin(a), ca = Math.cos(a);
73 return {
74 x: p.z * sa + p.x * ca,
75 y: p.y,
76 z: p.z * ca - p.x * sa
77 };
78 }
79
80 function rotateZ(p, a){
81 var sa = Math.sin(a), ca = Math.cos(a);
82 return {
83 x: p.x * ca - p.y * sa,
84 y: p.x * sa + p.y * ca,
85 z: p.z
86 };
87 }
88
89 function point(points, options, point, angles){
90
91 for (var i = points.length - 1; i >= 0; i--) {
92
93 var p = points[i];
94
95 p.rotated = rotateRzRyRx({x : point.x(p), y : point.y(p), z : point.z(p)}, angles);
96 p.centroid = p.rotated;
97 p.projected = options.project(p.rotated, options);
98 }
99 return points;
100 }
101
102 function cube(cubes, options, point$1, angles){
103 for (var i = cubes.length - 1; i >= 0; i--) {
104
105 var cube = cubes[i];
106
107 var vertices = point([
108 cube[0],
109 cube[1],
110 cube[2],
111 cube[3],
112 cube[4],
113 cube[5],
114 cube[6],
115 cube[7]
116 ], options, point$1, angles);
117
118 var v1 = vertices[0];
119 var v2 = vertices[1];
120 var v3 = vertices[2];
121 var v4 = vertices[3];
122 var v5 = vertices[4];
123 var v6 = vertices[5];
124 var v7 = vertices[6];
125 var v8 = vertices[7];
126
127 var front = [v1, v2, v3, v4];
128 var back = [v8, v7, v6, v5];
129 var left = [v5, v6, v2, v1];
130 var right = [v4, v3, v7, v8];
131 var top = [v5, v1, v4, v8];
132 var bottom = [v2, v6, v7, v3];
133
134 front.centroid = centroid(front);
135 back.centroid = centroid(back);
136 left.centroid = centroid(left);
137 right.centroid = centroid(right);
138 top.centroid = centroid(top);
139 bottom.centroid = centroid(bottom);
140
141 front.ccw = ccw(front);
142 back.ccw = ccw(back);
143 left.ccw = ccw(left);
144 right.ccw = ccw(right);
145 top.ccw = ccw(top);
146 bottom.ccw = ccw(bottom);
147
148 front.face = 'front';
149 back.face = 'back';
150 left.face = 'left';
151 right.face = 'right';
152 top.face = 'top';
153 bottom.face = 'bottom';
154
155 var faces = [front, back, left, right, top, bottom];
156
157 cube.faces = faces;
158 cube.centroid = {x: (left.centroid.x + right.centroid.x)/2, y: (top.centroid.y + bottom.centroid.y)/2, z: (front.centroid.z + back.centroid.z/2)};
159 }
160 return cubes;
161 }
162
163 function gridPlane(grid, options, point$1, angles){
164
165 var points = point(grid, options, point$1, angles);
166 var cnt = 0, planes = [];
167 var numPts = options.row;
168 var numRow = points.length/numPts;
169
170 for (var i = numRow - 1; i > 0; i--) {
171 for (var j = numPts - 1; j > 0; j--) {
172
173 var p1 = j + i * numPts, p4 = p1 - 1, p2 = p4 - numPts + 1, p3 = p2 - 1;
174 var pl = [points[p1], points[p2], points[p3], points[p4]];
175
176 pl.plane = 'plane_' + cnt++;
177 pl.ccw = ccw(pl);
178 pl.centroid = centroid(pl);
179 planes.push(pl);
180 }
181 }
182
183 return planes;
184 }
185
186 function lineStrip(lineStrip, options, point, angles){
187
188 for (var i = lineStrip.length - 1; i >= 0; i--) {
189
190 var l = lineStrip[i], m = l.length/2, t = parseInt(m);
191
192 for (var j = l.length - 1; j >= 0; j--) {
193 var p = l[j];
194 p.rotated = rotateRzRyRx({x : point.x(p), y : point.y(p), z : point.z(p)}, angles);
195 p.projected = options.project(p.rotated, options);
196 }
197
198 l.centroid = t === m ? centroid([ l[m - 1], l[m] ]) : { x: l[t].rotated.x, y: l[t].rotated.y, z: l[t].rotated.z };
199 }
200 return lineStrip;
201 }
202
203 function line(lines, options, point, angles){
204
205 for (var i = lines.length - 1; i >= 0; i--) {
206
207 var line = lines[i];
208
209 var p1 = line[0];
210 var p2 = line[1];
211
212 p1.rotated = rotateRzRyRx({x : point.x(p1), y : point.y(p1), z : point.z(p1)}, angles);
213 p2.rotated = rotateRzRyRx({x : point.x(p2), y : point.y(p2), z : point.z(p2)}, angles);
214
215 p1.projected = options.project(p1.rotated, options);
216 p2.projected = options.project(p2.rotated, options);
217
218 line.centroid = centroid(line);
219 }
220 return lines;
221 }
222
223 function plane(planes, options, point, angles){
224
225 for (var i = planes.length - 1; i >= 0; i--) {
226
227 var plane = planes[i];
228
229 var p1 = plane[0];
230 var p2 = plane[1];
231 var p3 = plane[2];
232 var p4 = plane[3];
233
234 p1.rotated = rotateRzRyRx({x : point.x(p1), y : point.y(p1), z : point.z(p1)}, angles);
235 p2.rotated = rotateRzRyRx({x : point.x(p2), y : point.y(p2), z : point.z(p2)}, angles);
236 p3.rotated = rotateRzRyRx({x : point.x(p3), y : point.y(p3), z : point.z(p3)}, angles);
237 p4.rotated = rotateRzRyRx({x : point.x(p4), y : point.y(p4), z : point.z(p4)}, angles);
238
239 p1.projected = options.project(p1.rotated, options);
240 p2.projected = options.project(p2.rotated, options);
241 p3.projected = options.project(p3.rotated, options);
242 p4.projected = options.project(p4.rotated, options);
243
244 plane.ccw = ccw(plane);
245 plane.centroid = centroid(plane);
246 }
247 return planes;
248 }
249
250 function triangle(triangles, options, point, angles){
251
252 for (var i = triangles.length - 1; i >= 0; i--) {
253 var tri = triangles[i];
254 var p1 = tri[0];
255 var p2 = tri[1];
256 var p3 = tri[2];
257
258 p1.rotated = rotateRzRyRx({x : point.x(p1), y : point.y(p1), z : point.z(p1)}, angles);
259 p2.rotated = rotateRzRyRx({x : point.x(p2), y : point.y(p2), z : point.z(p2)}, angles);
260 p3.rotated = rotateRzRyRx({x : point.x(p3), y : point.y(p3), z : point.z(p3)}, angles);
261
262 p1.projected = options.project(p1.rotated, options);
263 p2.projected = options.project(p2.rotated, options);
264 p3.projected = options.project(p3.rotated, options);
265
266 tri.ccw = ccw(tri);
267 tri.centroid = centroid(tri);
268 }
269 return triangles;
270 }
271
272 function drawLineStrip(lineStrip){
273 var lastPoint = lineStrip[lineStrip.length - 1];
274 var path = 'M' + lastPoint.projected.x + ',' + lastPoint.projected.y;
275 for (var i = lineStrip.length - 2; i >= 0; i--) {
276 var p = lineStrip[i].projected;
277 path += 'L' + p.x + ',' + p.y;
278 }
279 return path;
280 }
281
282 function drawPlane(d){
283 return 'M' + d[0].projected.x + ',' + d[0].projected.y + 'L' + d[1].projected.x + ',' + d[1].projected.y + 'L' + d[2].projected.x + ',' + d[2].projected.y + 'L' + d[3].projected.x + ',' + d[3].projected.y + 'Z';
284 }
285
286 function drawTriangle(d){
287 return 'M' + d[0].projected.x + ',' + d[0].projected.y + 'L' + d[1].projected.x + ',' + d[1].projected.y + 'L' + d[2].projected.x + ',' + d[2].projected.y + 'Z';
288 }
289
290 function orthographic(d, options){
291 return {
292 x: options.origin[0] + options.scale * d.x,
293 y: options.origin[1] + options.scale * d.y
294 };
295 }
296
297 function x(p) {
298 return p[0];
299 }
300
301 function y(p) {
302 return p[1];
303 }
304
305 function z(p) {
306 return p[2];
307 }
308
309 /**
310 * @author Stefan Nieke / http://niekes.com/
311 */
312 function _3d() {
313
314 var origin = [0, 0],
315 scale = 1,
316 projection = orthographic,
317 angleX = 0,
318 angleY = 0,
319 angleZ = 0,
320 rotateCenter = [0,0,0],
321 x$1 = x,
322 y$1 = y,
323 z$1 = z,
324 row = undefined,
325 shape = 'POINT',
326 processData = {
327 'CUBE' : cube,
328 'GRID' : gridPlane,
329 'LINE' : line,
330 'LINE_STRIP' : lineStrip,
331 'PLANE' : plane,
332 'POINT' : point,
333 'SURFACE' : gridPlane,
334 'TRIANGLE' : triangle,
335 },
336 draw = {
337 'CUBE' : drawPlane,
338 'GRID' : drawPlane,
339 'LINE_STRIP' : drawLineStrip,
340 'PLANE' : drawPlane,
341 'SURFACE' : drawPlane,
342 'TRIANGLE' : drawTriangle,
343 };
344
345 function _3d(data){
346 return processData[shape](
347 data,
348 { scale: scale, origin: origin, project: projection, row: row },
349 { x: x$1, y: y$1, z: z$1 },
350 { x: angleX, y: angleY, z: angleZ, rotateCenter: rotateCenter }
351 );
352 }
353
354 _3d.origin = function(_){
355 return arguments.length ? (origin = _, _3d) : origin;
356 };
357
358 _3d.scale = function(_){
359 return arguments.length ? (scale = _, _3d) : scale;
360 };
361
362 _3d.rotateX = function(_){
363 return arguments.length ? (angleX = _, _3d) : angleX;
364 };
365
366 _3d.rotateY = function(_){
367 return arguments.length ? (angleY = _, _3d) : angleY;
368 };
369
370 _3d.rotateZ = function(_){
371 return arguments.length ? (angleZ = _, _3d) : angleZ;
372 };
373
374 _3d.shape = function(_, r){
375 return arguments.length ? (shape = _, row = r, _3d) : shape;
376 };
377
378 _3d.rotateCenter = function(_){
379 return arguments.length ? (rotateCenter = _, _3d) : rotateCenter;
380 };
381
382 _3d.x = function(_){
383 return arguments.length ? (x$1 = typeof _ === 'function' ? _ : +_, _3d) : x$1;
384 };
385
386 _3d.y = function(_){
387 return arguments.length ? (y$1 = typeof _ === 'function' ? _ : +_, _3d) : y$1;
388 };
389
390 _3d.z = function(_){
391 return arguments.length ? (z$1 = typeof _ === 'function' ? _ : +_, _3d) : z$1;
392 };
393
394 _3d.sort = function(a, b){
395 var _a = a.centroid.z, _b = b.centroid.z;
396 return _a < _b ? -1 : _a > _b ? 1 : _a >= _b ? 0 : NaN;
397 };
398
399 _3d.draw = function(d){
400 if(!((shape === 'POINT') || (shape === 'LINE'))){
401 return draw[shape](d);
402 }
403 };
404
405 return _3d;
406 }
407
408 exports._3d = _3d;
409
410 Object.defineProperty(exports, '__esModule', { value: true });
411
412})));