diff mrjunejune/pages/public/dog.js @ 82:1ded13720541

Added new logos.
author June Park <parkjune1995@gmail.com>
date Thu, 01 Jan 2026 12:45:22 -0800
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mrjunejune/pages/public/dog.js	Thu Jan 01 12:45:22 2026 -0800
@@ -0,0 +1,242 @@
+// -- Dog -- //
+const SCREEN_WIDTH = 800;
+const SCREEN_HEIGHT = 600;
+const PIXEL_SIZE = 3;
+const FRAME = 60;
+
+const dog = document.getElementById("epi3D");
+dog.width = SCREEN_WIDTH;
+dog.height = SCREEN_HEIGHT;
+const ctx = dog.getContext("2d");
+
+function drawBackground() {
+  ctx.fillStyle = "black";
+  ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+}
+
+function drawPixel({x, y}) {
+  ctx.fillStyle = "blue";
+  ctx.fillRect(x * SCREEN_WIDTH, y * SCREEN_HEIGHT, PIXEL_SIZE, PIXEL_SIZE);
+}
+
+function normalize({x, y}) {
+  return {
+    x: ((x + 1) / 2),
+    y: (1 - ((y + 1) / 2)),
+  }
+}
+
+function threeDtotwoD({x, y, z}) {
+  return {
+    x: x/z,
+    y: y/z
+  }
+}
+
+function drawLine(point1, point2) {
+  ctx.beginPath();
+  ctx.moveTo(point1.x * SCREEN_WIDTH, point1.y * SCREEN_HEIGHT);
+  ctx.lineTo(point2.x * SCREEN_WIDTH, point2.y * SCREEN_HEIGHT);
+  ctx.lineWidth = 3;
+  ctx.strokeStyle = "red";
+  ctx.stroke();
+}
+
+let points = [];
+let vertices = [];
+
+async function loadXYZModel(filepath) {
+  try {
+    const response = await fetch(filepath);
+    const xyzContent = await response.text();
+    // return parseXYZFile(xyzContent);
+    return parseSmartSTL(xyzContent);
+  } catch (error) {
+    console.error('Error loading XYZ file:', error);
+    return null;
+  }
+}
+
+function downsamplePoints(points, gridSize = 0.2) {
+  const grid = new Map();
+  
+  for (const point of points) {
+    // Create grid cell key
+    const cellX = Math.floor(point.x / gridSize);
+    const cellY = Math.floor(point.y / gridSize);
+    const cellZ = Math.floor(point.z / gridSize);
+    const key = `${cellX},${cellY},${cellZ}`;
+    
+    // Keep first point in each cell (or you could average them)
+    if (!grid.has(key)) {
+      grid.set(key, point);
+    }
+  }
+  
+  return Array.from(grid.values());
+}
+
+async function initModel() {
+  const model = await loadXYZModel('/public/dog.xyz');
+  
+  if (model) {
+    const normalizedPoints = normalizePoints(model.points, 1.0);
+    points = downsamplePoints(normalizedPoints, 0.1); // grid method
+
+    vertices = model.vertices;
+    for (let i = 0; i < points.length - 1; i++) {
+      vertices.push([i, i + 1]);
+    }
+    
+    // Start the animation after loading
+    drawAnimation();
+  } else {
+    console.error('Failed to load model');
+  }
+}
+
+function parseSmartSTL(stlString) {
+  const lines = stlString.split('\n');
+  const points = [];
+  const vortexs = [];
+  
+  let currentNormal = "";
+  let tempVertices = [];
+
+  lines.forEach((line) => {
+    const trimmed = line.trim();
+
+    // 1. Detect the "Angle" (Normal)
+    if (trimmed.startsWith('facet normal')) {
+      const normal = trimmed.replace('facet normal ', '');
+      // Only care if the normal is different from the last one (it's a new angle)
+      // Or just keep them all for now and we'll filter by position
+      currentNormal = normal;
+      tempVertices = [];
+    }
+
+    // 2. Grab the vertices
+    if (trimmed.startsWith('vertex')) {
+      const parts = trimmed.split(/\s+/);
+      tempVertices.push({
+        x: parseFloat(parts[1]),
+        y: parseFloat(parts[2]),
+        z: parseFloat(parts[3])
+      });
+    }
+
+    // 3. When the triangle ends, connect them
+    if (trimmed.startsWith('endloop')) {
+      const startIndex = points.length;
+      points.push(...tempVertices);
+      
+      // Create a triangle connection (vortex)
+      vortexs.push([startIndex, startIndex + 1, startIndex + 2]);
+    }
+  });
+
+  return { points, vortexs };
+}
+
+// Usage:
+// const { points, vortexs } = parseSmartSTL(yourStlString);
+
+initModel();
+
+function parseXYZFile(xyzFileContent) {
+  const lines = xyzFileContent.trim().split('\n').filter(line => line.trim());
+  
+  const points = lines.map(line => {
+    const coords = line.trim().split(/\s+/).map(Number);
+    return {
+      x: coords[0],
+      y: coords[1],
+      z: coords[2]
+    };
+  });
+  
+  return { points };
+}
+
+function normalizePoints(points, scale = 1.0) {
+  const xs = points.map(p => p.x);
+  const ys = points.map(p => p.y);
+  const zs = points.map(p => p.z);
+  
+  const minX = Math.min(...xs), maxX = Math.max(...xs);
+  const minY = Math.min(...ys), maxY = Math.max(...ys);
+  const minZ = Math.min(...zs), maxZ = Math.max(...zs);
+  
+  const centerX = (minX + maxX) / 2;
+  const centerY = (minY + maxY) / 2;
+  const centerZ = (minZ + maxZ) / 2;
+  
+  const rangeX = maxX - minX;
+  const rangeY = maxY - minY;
+  const rangeZ = maxZ - minZ;
+  const maxRange = Math.max(rangeX, rangeY, rangeZ);
+  
+  return points.map(p => ({
+    x: ((p.x - centerX) / maxRange) * scale,
+    y: ((p.y - centerY) / maxRange) * scale,
+    z: ((p.z - centerZ) / maxRange) * scale
+  }));
+}
+
+function rotate_xz({x, y, z}, angle) {
+  return {
+    x: x * Math.cos(angle) - z * Math.sin(angle),
+    y: y,
+    z: x * Math.sin(angle) + z * Math.cos(angle),
+  }
+}
+
+function move_point(point, { x, y, z}) {
+  return {
+    ...point,
+    x: point.x + x,
+    y: 1 - (point.y + y),
+    z: point.z + z
+  }
+}
+
+function move_z(point, dz) {
+  return {...point, z: point.z + dz}
+}
+
+let dz = 0;
+let dt = 1/FRAME;
+let angle = 0;
+
+function drawAnimation() {
+  drawBackground();
+  // dz += 1 * dt;
+  angle += 1 * Math.PI * dt;
+
+  for (const point of points) {
+    drawPixel(
+        threeDtotwoD(
+          move_point(rotate_xz(point, angle), { x: 0.7, y: 0.5, z: 1.5})
+        )
+    );
+  } 
+
+  for (const vertex of vertices) {
+    for (let i = 0; i < vertex.length - 1; i++) {
+      const point1 = normalize(
+        threeDtotwoD(
+          move_point(rotate_xz(points[vertex[i]], angle), { x: 0.7, y: 0.5, z: 1.5})
+        )
+      );
+      const point2 = normalize(
+        threeDtotwoD(
+          move_point(rotate_xz(points[vertex[i + 1]], angle), { x: 0.7, y: 0.5, z: 1.5})
+        )
+      );
+      drawLine(point1, point2);
+    }
+  }
+  
+  setTimeout(() => drawAnimation(), 1000/60);
+}
+drawAnimation();