comparison graphics/index.js @ 173:827c6ac504cd hg-web

Merged in default here.
author MrJuneJune <me@mrjunejune.com>
date Mon, 19 Jan 2026 18:59:10 -0800
parents 8ceb5d3c6bdd
children
comparison
equal deleted inserted replaced
151:c033667da5f9 173:827c6ac504cd
1 const SCREEN_WIDTH = 600; 1 const SCREEN_WIDTH = 600;
2 const SCREEN_HEIGHT = 600; 2 const SCREEN_HEIGHT = 600;
3 const PIXEL_SIZE = 10; 3 const PIXEL_SIZE = 1;
4 const FRAME = 60 4 const FRAME = 60
5 5
6 game.width = SCREEN_WIDTH; 6 game.width = SCREEN_WIDTH;
7 game.height = SCREEN_HEIGHT; 7 game.height = SCREEN_HEIGHT;
8 8
12 ctx.fillStyle = "black"; 12 ctx.fillStyle = "black";
13 ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); 13 ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
14 } 14 }
15 15
16 function drawPixel({x, y}) { 16 function drawPixel({x, y}) {
17 ctx.fillStyle = "blue"; 17 ctx.fillStyle = "pink";
18 ctx.fillRect(x * SCREEN_WIDTH, y * SCREEN_HEIGHT, PIXEL_SIZE, PIXEL_SIZE); 18 ctx.fillRect(x * SCREEN_WIDTH, y * SCREEN_HEIGHT, PIXEL_SIZE, PIXEL_SIZE);
19 } 19 }
20 20
21 function normazlie({x, y}) { 21 function normalize({x, y}) {
22 return { 22 return {
23 x: ((x + 1) / 2), 23 x: ((x + 1) / 2),
24 y: (1 - ((y + 1) / 2)), 24 y: (1 - ((y + 1) / 2)),
25 } 25 }
26 } 26 }
31 y: y/z 31 y: y/z
32 } 32 }
33 } 33 }
34 34
35 function drawLine({x, y}, {x2, y2}) { 35 function drawLine({x, y}, {x2, y2}) {
36 console.log("Hello", x,y, x2,y2);
37 ctx.beginPath(); 36 ctx.beginPath();
38 ctx.moveTo(x * SCREEN_WIDTH, y * SCREEN_HEIGHT); 37 ctx.moveTo(x * SCREEN_WIDTH, y * SCREEN_HEIGHT);
39 ctx.lineTo(x2 * SCREEN_WIDTH, y2* SCREEN_HEIGHT); 38 ctx.lineTo(x2 * SCREEN_WIDTH, y2* SCREEN_HEIGHT);
40 ctx.lineWidth = 3; 39 ctx.lineWidth = 3;
41 ctx.strokeStyle = "red"; 40 ctx.strokeStyle = "red";
42 ctx.stroke(); 41 ctx.stroke();
43 } 42 }
44 43
45 const test = 0; 44
46 const points = [ 45 // function generateHeartPoints(resolution = 0.008) {
47 {x: -0.25, y: 0.25, z: 0.5 + test}, 46 // const points = [];
48 {x: -0.25, y: -0.25, z: 0.5 + test}, 47 // // Nordstrom needs a slightly higher threshold because the
49 {x: 0.25, y: -0.25, z: 0.5 + test}, 48 // // gradient of the cubic is steeper in some areas.
50 {x: 0.25, y: 0.25, z: 0.5 + test}, 49 // const threshold = 0.0001;
51 50 //
52 {x: -0.25, y: 0.25, z: -0.5 + test}, 51 // for (let x = -1.5; x <= 1.5; x += resolution) {
53 {x: -0.25, y: -0.25, z: -0.5 + test}, 52 // for (let y = -1.5; y <= 1.5; y += resolution) {
54 {x: 0.25, y: -0.25, z: -0.5 + test}, 53 // for (let z = -1.5; z <= 1.5; z += resolution) {
55 {x: 0.25, y: 0.25, z: -0.5 + test}, 54 //
56 ] 55 // const x2 = x * x;
57 const vortexs = [ 56 // const y2 = y * y;
58 [0, 1, 2, 3], 57 // const z2 = z * z;
59 [4, 5, 6, 7], 58 // const z3 = z2 * z;
60 [0, 4], 59 //
61 [1, 5], 60 // // Nordstrom Equation: (2x² + y² + z² - 1)³ - (1/10)x²z³ - y²z³ = 0
62 [2, 6], 61 // const inner = (2 * x2) + y2 + z2 - 1;
63 [3, 7], 62 // const value = Math.pow(inner, 3) - (0.1 * x2 * z3) - (y2 * z3);
64 ] 63 //
64 // if (Math.abs(value) < threshold) {
65 // // Keep the jitter for that organic "floating dust" look
66 // points.push({
67 // x: x + (Math.random() - 0.5) * resolution,
68 // y: y + (Math.random() - 0.5) * resolution,
69 // z: z + (Math.random() - 0.5) * resolution
70 // });
71 // }
72 // }
73 // }
74 // }
75 // return points;
76 // }
77
78 function generateHeartPoints(resolution = 0.01) {
79 const points = [];
80 const threshold = 0.001;
81
82 for (let x = -1.5; x <= 1.5; x += resolution) {
83 for (let y = -1.5; y <= 1.5; y += resolution) {
84 for (let z = -1.5; z <= 1.5; z += resolution) {
85
86 const x2 = x * x;
87 const y2 = y * y;
88 const z2 = z * z;
89 const z3 = z2 * z;
90
91 const inner = x2 + (9/4) * y2 + z2 - 1;
92 const value = Math.pow(inner, 3) - x2 * z3 - (9/80) * y2 * z3;
93
94 if (Math.abs(value) < threshold) {
95 points.push({
96 x: x + (Math.random() - 0.5) * 0.01,
97 y: y + (Math.random() - 0.5) * 0.01,
98 z: z + (Math.random() - 0.5) * 0.01
99 });
100 }
101 }
102 }
103 }
104 return points;
105 }
106
107 let points = generateHeartPoints();
108 const intial_start_z = 2;
109 points = points.map(point => ({...point, x: point.x + intial_start_z}));
110 // const points = [
111 // {x: -0.25, y: 0.25, z: 0.25},
112 // {x: -0.25, y: -0.25, z: 0.25},
113 // {x: 0.25, y: -0.25, z: 0.25},
114 // {x: 0.25, y: 0.25, z: 0.25},
115 //
116 // {x: -0.25, y: 0.25, z: -0.25},
117 // {x: -0.25, y: -0.25, z: -0.25},
118 // {x: 0.25, y: -0.25, z: -0.25},
119 // {x: 0.25, y: 0.25, z: -0.25},
120 // ]
121 // const vortexs = [
122 // [0, 1, 2, 3],
123 // [4, 5, 6, 7],
124 // [0, 4],
125 // [1, 5],
126 // [2, 6],
127 // [3, 7],
128 // ]
129
130 function rotate_xy({x, y, z}, angle) {
131 return {
132 x: x * Math.cos(angle) - y * Math.sin(angle),
133 y: x * Math.sin(angle) + y * Math.cos(angle),
134 z: z
135 };
136 }
65 137
66 function rotate_xz({x,y,z}, angle) { 138 function rotate_xz({x,y,z}, angle) {
67 return { 139 return {
68 x: x * Math.cos(angle) - z*Math.sin(angle), 140 x: x * Math.cos(angle) - z*Math.sin(angle),
69 y: y, 141 y: y,
70 z: x * Math.sin(angle) + z*Math.cos(angle), 142 z: x * Math.sin(angle) + z*Math.cos(angle),
71 } 143 }
72 } 144 }
73 145
146 function rotate_yz({x, y, z}, angle) {
147 return {
148 x: x,
149 y: y * Math.sin(angle) + z * Math.cos(angle),
150 z: y * Math.cos(angle) - z * Math.sin(angle)
151 };
152 }
153
74 function move_z(point, dz) { 154 function move_z(point, dz) {
75 return {...point, z: point.z + dz} 155 return {...point, z: point.z + dz}
156 }
157
158 function move_y(point, dy) {
159 return {...point, y: point.y + dy}
76 } 160 }
77 161
78 let dz = 0; 162 let dz = 0;
79 let dt = 1/FRAME; 163 let dt = 1/FRAME;
80 let angle = 0; 164 let angle = 0;
165 const fontPoint = {x: SCREEN_WIDTH / 2, y: SCREEN_HEIGHT * 0.3};
81 166
82 function drawAnimation() { 167 function drawAnimation() {
83 drawBackground(); 168 drawBackground();
84 dz += 1 * dt; 169 dz -= 1 * dt;
85 // angle += 2*Math.PI*dt; 170 angle += 2*Math.PI*dt*0.2;
86 angle = 0; 171
87 for (var vortex of vortexs) 172 // Texts...
173 ctx.font = "60px serif";
174 ctx.textAlign = "center"; // Ensures the point is the middle of the text
175 ctx.textBaseline = "middle";
176 ctx.fillStyle = "pink";
177 ctx.fillText("Heart!", fontPoint.x, fontPoint.y);
178
179 // Hearts...
180 for (var point of points)
88 { 181 {
89 for (let i = 0; i < vortex.length; i++) 182 const newPoint = normalize(
90 { 183 threeDtotwoD(
91 const newPoint = normazlie( 184 move_z(rotate_yz(rotate_xz(rotate_xy(point, angle), angle), angle), dz)
92 threeDtotwoD( 185 // move_z(point, dz)
93 move_z(rotate_xz(points[vortex[(i+1)%vortex.length]], angle), dz) 186 )
94 )
95 );
96
97 drawLine(
98 normazlie(
99 threeDtotwoD(
100 move_z(rotate_xz(points[vortex[i]], angle), dz)
101 )
102 ),
103 {x2: newPoint.x, y2: newPoint.y}
104 ); 187 );
105 } 188 drawPixel(newPoint);
106 } 189 }
190
191 // for (var vortex of vortexs)
192 // {
193 // for (let i = 0; i < vortex.length; i++)
194 // {
195 // const newPoint = normalize(
196 // threeDtotwoD(
197 // move_z(rotate_xz(points[vortex[(i+1)%vortex.length]], angle), dz)
198 // )
199 // );
200
201 // drawLine(
202 // normalize(
203 // threeDtotwoD(
204 // move_z(rotate_xz(points[vortex[i]], angle), dz)
205 // )
206 // ),
207 // {x2: newPoint.x, y2: newPoint.y}
208 // );
209 // }
210 // }
107 setTimeout(() => drawAnimation(), 1000/60) 211 setTimeout(() => drawAnimation(), 1000/60)
108 } 212 }
109 213
110 drawAnimation() 214 drawAnimation()
111 215