1
<html>
2
<head>
3
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
4
<title>untitled canvas</title>
5
<script>
6
console.log( "=============== script ==============" );
7
8
9
10
11
12
13
14
15
16
17
18
19
function $( id ) { return document.getElementById( id ); }
20
var HereDocument = /\/\*\s*([^]*?)\s*\*\//;
21
var canvasEL, canvas;
22
23
function onloadx() {
24
canvasEL = $( "canvasELID" );
25
canvas = canvasEL.getContext( '2d' );
26
screenW = canvasEL.width;
27
screenH = canvasEL.height;
28
29
30
31
32
masters = new Object();
33
masters.cube = new Object();
34
35
36
masters.cube.tens = [
37
{ x : -1, y : -1, z : -1 },
38
{ x : +1, y : -1, z : -1 },
39
{ x : +1, y : +1, z : -1 },
40
{ x : -1, y : +1, z : -1 },
41
42
{ x : -1, y : -1, z : +1 },
43
{ x : +1, y : -1, z : +1 },
44
{ x : +1, y : +1, z : +1 },
45
{ x : -1, y : +1, z : +1 },
46
];
47
48
masters.cube.mens = [
49
[ 3, 2, 1, 0 ],
50
[ 1, 2, 6, 5 ],
51
[ 0, 4, 7, 3 ],
52
[ 7, 6, 2, 3 ],
53
[ 0, 1, 5, 4 ],
54
[ 5, 6, 7, 4 ],
55
];
56
57
58
masters.cube.scale = 10;
59
60
61
masters.cube.posX = 0;
62
masters.cube.posY = 0;
63
masters.cube.posZ = 80;
64
65
66
masters.cube.kaitenH = 3.14 / 8;
67
masters.cube.kaitenV = 0;
68
69
70
masters.cube.baseColor = { r : 196, g : 196, b : 0 };
71
72
73
models = new Array();
74
var makeLink = function( master ) {
75
var model = new Object();
76
model.tens = master.tens;
77
model.mens = master.mens;
78
model.scale = master.scale;
79
model.posX = master.posX;
80
model.posY = master.posY;
81
model.posZ = master.posZ;
82
model.kaitenH = master.kaitenH;
83
model.kaitenV = master.kaitenV;
84
model.baseColor = objCpy( master.baseColor );
85
return model;
86
};
87
88
89
var model = makeLink( masters.cube );
90
model.posX = -15;
91
model.posZ -= 1;
92
model.baseColor = { r : 196, g : 48, b : 48 };
93
models.push( model );
94
95
96
var model = makeLink( masters.cube );
97
model.scale *= 1.2;
98
model.posX = 9;
99
model.posY = -models[ 0 ].scale + model.scale;
100
model.posZ += 5;
101
model.baseColor = { r : 48, g : 196, b : 48 };
102
models.push( model );
103
104
105
var model = makeLink( masters.cube );
106
model.scale *= 0.3;
107
model.posX = 1;
108
model.posY = -models[ 0 ].scale + model.scale;
109
model.posZ = 62;
110
model.kaitenH = 0.02;
111
model.baseColor = { r : 48, g : 48, b : 196 };
112
models.push( model );
113
114
cam = new Object();
115
116
117
cam.s = 30;
118
119
120
cam.kaitenH = 0;
121
cam.kaitenV = 0;
122
123
124
cam.posX = 0;
125
cam.posY = 0;
126
cam.posZ = 0;
127
128
129
var center = new Object();
130
center.x = models[ 2 ].posX;
131
center.y = models[ 2 ].posY;
132
center.z = models[ 2 ].posZ;
133
doTarget( cam, center );
134
var kaitenH = -3.14 / 4;
135
var kaitenV = -3.14 / 16 * 5;
136
camDomeKaiten( cam, center, kaitenH, kaitenV );
137
138
139
kougen = new Object();
140
kougen.pos = xyz( 0, 60, -60 );
141
142
draw();
143
}
144
145
function draw() {
146
147
148
for( var m = 0; m < models.length; m++ ) {
149
var model = models[ m ];
150
model.tensC = new Array();
151
152
153
for( var i = 0; i < model.tens.length; i++ ) {
154
var x = model.tens[ i ].x;
155
var y = model.tens[ i ].y;
156
var z = model.tens[ i ].z;
157
158
159
x *= model.scale;
160
y *= model.scale;
161
z *= model.scale;
162
163
164
var res = kaiten( x, z, model.kaitenH );
165
x = res.X;
166
z = res.Y;
167
168
var res = kaiten( z, y, model.kaitenV );
169
z = res.X;
170
y = res.Y;
171
172
173
x += model.posX;
174
y += model.posY;
175
z += model.posZ;
176
177
178
x += -cam.posX;
179
y += -cam.posY;
180
z += -cam.posZ;
181
182
183
184
var res = kaiten( x, z, -cam.kaitenH );
185
x = res.X;
186
z = res.Y;
187
188
var res = kaiten( z, y, -cam.kaitenV );
189
z = res.X;
190
y = res.Y;
191
192
193
194
var h = x * ( cam.s / z );
195
var v = -y * ( cam.s / z );
196
197
198
h *= 14.25;
199
v *= 14.25;
200
201
202
model.tensC[ i ] = new Object();
203
model.tensC[ i ].x = x;
204
model.tensC[ i ].y = y;
205
model.tensC[ i ].z = z;
206
model.tensC[ i ].h = h;
207
model.tensC[ i ].v = v;
208
209
}
210
}
211
212
213
214
215
var allmens = new Array();
216
217
218
for( var m = 0; m < models.length; m++ ) {
219
var model = models[ m ];
220
221
for( var j = 0; j < model.mens.length; j++ ) {
222
var men = model.mens[ j ];
223
224
var jusin;
225
var housen;
226
227
var tmpTens = new Array();
228
for( var i = 0; i < men.length; i++ )
229
tmpTens.push( model.tensC[ men[ i ] ] );
230
231
jusin = getJusin( tmpTens );
232
housen = getHousen( tmpTens );
233
234
235
236
if( ! checkVisibility( housen, jusin ) ) continue;
237
238
239
var theMen = new Object();
240
theMen.men = men;
241
theMen.jusin = jusin;
242
theMen.housen = housen;
243
theMen.model = model;
244
allmens.push( theMen );
245
246
}
247
}
248
249
250
251
252
allmens.sort( function( a, b ) {
253
if( a.jusin.z > b.jusin.z ) return -1;
254
else if( a.jusin.z < b.jusin.z ) return 1;
255
else return 0;
256
} );
257
258
259
260
for( var i = 0; i < allmens.length; i++ ) {
261
var men = allmens[ i ].men;
262
var model = allmens[ i ].model;
263
var housen = allmens[ i ].housen;
264
265
266
canvas.beginPath();
267
for( var j = 0; j < men.length; j++ ) {
268
var tenIDX = men[ j ];
269
var ten = model.tensC[ tenIDX ];
270
271
var h = ten.h;
272
var v = ten.v;
273
274
275
if( j == 0 ) {
276
canvas.moveTo( screenW / 2 + h, screenH / 2 + v );
277
} else {
278
canvas.lineTo( screenW / 2 + h, screenH / 2 + v );
279
}
280
}
281
canvas.closePath();
282
283
284
285
286
var kougenP = xyz( kougen.pos.x - jusin.x, kougen.pos.y - jusin.y, kougen.pos.z - jusin.z );
287
canvas.fillStyle = rgb2str( lambelt( toNorm( kougenP ), housen, model.baseColor ) );
288
canvas.fill();
289
290
291
canvas.strokeStyle = "black";
292
canvas.stroke();
293
}
294
}
295
296
297
298
function checkVisibility( housen, jusin ) {
299
300
301
var sisen = objCpy( jusin );
302
sisen.x *= -1;
303
sisen.y *= -1;
304
sisen.z *= -1;
305
306
307
var a = naiseki( housen, sisen );
308
309
return a > 0;
310
}
311
312
function kaiten( x, y, theta2 ) {
313
314
315
316
317
var theta1 = Math.atan2( y, x );
318
var hankei = Math.sqrt( x * x + y * y );
319
var kaitenX = Math.cos( theta1 + theta2 ) * hankei;
320
var kaitenY = Math.sin( theta1 + theta2 ) * hankei;
321
return { X : kaitenX, Y : kaitenY };
322
}
323
324
function rgb2str( rgb ) {
325
326
327
328
console.log( "RGB(" + rgb.r + "," + rgb.g + "," + rgb.b + ")" );
329
return "RGB(" + rgb.r + "," + rgb.g + "," + rgb.b + ")";
330
}
331
332
function objCpy( obj ) {
333
334
335
336
var res = new Object();
337
for( var name in obj ) {
338
res[ name ] = obj[ name ];
339
}
340
return res;
341
}
342
343
function xyz( x, y, z ) {
344
345
346
347
return { x : x, y : y, z : z };
348
}
349
350
function getJusin( p ) {
351
352
353
354
355
var res = xyz( 0, 0, 0 );
356
for( var i = 0; i < p.length; i++ ) {
357
res.x += p[ i ].x;
358
res.y += p[ i ].y;
359
res.z += p[ i ].z;
360
}
361
res.x /= p.length;
362
res.y /= p.length;
363
res.z /= p.length;
364
return res;
365
}
366
367
function doTarget( cam, targetP ) {
368
369
370
371
372
373
var tx = targetP.x - cam.posX;
374
var ty = targetP.y - cam.posY;
375
var tz = targetP.z - cam.posZ;
376
377
378
var kakudoTH = Math.atan2( tz, tx );
379
var kakudoTV = Math.atan2( ty, tz );
380
381
382
cam.kaitenH = kakudoTH - 1.57;
383
cam.kaitenV = kakudoTV;
384
}
385
386
function camDomeKaiten( cam, center, theta2H, theta2V ) {
387
388
389
390
391
392
if( theta2H != 0 ) {
393
394
var res = kaiten2( center.x, center.z, cam.posX, cam.posZ, theta2H );
395
cam.posX = res.X;
396
cam.posZ = res.Y;
397
cam.kaitenH += theta2H;
398
}
399
400
401
if( theta2V != 0 ) {
402
403
404
405
406
407
408
var v = Math.abs( Math.floor( ( cam.kaitenV + theta2V ) * 100 ) / 100 );
409
if( v >= 3.14 / 2 ) {
410
theta2V = 3.14 / 2 * ( theta2V > 0 ? 1 : -1 ) - cam.kaitenV;
411
412
if( theta2V == 0 ) return;
413
}
414
415
416
var kaitenHbak = cam.kaitenH;
417
418
var res = kaiten2( center.x, center.z, cam.posX, cam.posZ, -cam.kaitenH );
419
cam.posX = res.X;
420
cam.posZ = res.Y;
421
cam.kaitenH = 0;
422
423
424
var res = kaiten2( center.z, center.y, cam.posZ, cam.posY, theta2V );
425
cam.posZ = res.X;
426
cam.posY = res.Y;
427
cam.kaitenV += theta2V;
428
429
430
var res = kaiten2( center.x, center.z, cam.posX, cam.posZ, kaitenHbak );
431
cam.posX = res.X;
432
cam.posZ = res.Y;
433
cam.kaitenH = kaitenHbak;
434
435
}
436
}
437
438
function kaiten2( centerX, centerY, x, y, theta2 ) {
439
440
441
442
443
x -= centerX;
444
y -= centerY;
445
var theta1 = Math.atan2( y, x );
446
var hankei = Math.sqrt( x * x + y * y );
447
var kaitenX = Math.cos( theta1 + theta2 ) * hankei;
448
var kaitenY = Math.sin( theta1 + theta2 ) * hankei;
449
kaitenX += centerX;
450
kaitenY += centerY;
451
return { X : kaitenX, Y : kaitenY };
452
}
453
454
function naiseki( v1, v2 ) {
455
456
457
458
459
var a = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
460
return a;
461
}
462
463
function getHousen( p ) {
464
465
466
467
468
var x1 = p[ 0 ].x, y1 = p[ 0 ].y, z1 = p[ 0 ].z;
469
var x2 = p[ 1 ].x, y2 = p[ 1 ].y, z2 = p[ 1 ].z;
470
var x3 = p[ 2 ].x, y3 = p[ 2 ].y, z3 = p[ 2 ].z;
471
472
473
var res = new Object();
474
res.x = (y2-y1)*(z3-z2)-(z2-z1)*(y3-y2);
475
res.y = (z2-z1)*(x3-x2)-(x2-x1)*(z3-z2);
476
res.z = (x2-x1)*(y3-y2)-(y2-y1)*(x3-x2);
477
res = toNorm( res );
478
479
return res;
480
}
481
482
function toNorm( p ) {
483
484
485
486
487
488
var len = Math.sqrt( p.x * p.x + p.y * p.y + p.z * p.z );
489
var res = new Object();
490
res.x = p.x / len;
491
res.y = p.y / len;
492
res.z = p.z / len;
493
return res;
494
}
495
496
function lambelt( housen, kougen, rgb ) {
497
var cosTheta = naiseki( housen, kougen );
498
var directPer = 0.6;
499
var ambientPer = 1 - directPer;
500
501
502
var dirR = rgb.r * directPer * cosTheta;
503
var ambR = rgb.r * ambientPer;
504
var dirG = rgb.g * directPer * cosTheta;
505
var ambG = rgb.g * ambientPer;
506
var dirB = rgb.b * directPer * cosTheta;
507
var ambB = rgb.b * ambientPer;
508
509
510
var res = new Object();
511
res.r = Math.round( dirR + ambR );
512
res.g = Math.round( dirG + ambG );
513
res.b = Math.round( dirB + ambB );
514
515
return res;
516
}
517
518
519
</script>
520
<style>
521
</style>
522
</head>
523
<body onload="onloadx();" style="
524
background-color : lightgray;
525
height : 100%;
526
margin : 0;
527
">
528
<canvas id="canvasELID" width="512" height="448" style="
529
display : block;
530
margin : auto;
531
background-color : white;
532
border : solid 1px black;
533
">There is no canvas.</canvas>
534
</body>
535
</html>