<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Neural Wonder Lab — Build Notes]]></title><description><![CDATA[Neural Wonder Lab — Build Notes]]></description><link>https://neuralwonderlab.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>Neural Wonder Lab — Build Notes</title><link>https://neuralwonderlab.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 21 Sep 2026 19:00:29 GMT</lastBuildDate><atom:link href="https://neuralwonderlab.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How can a moving 3D model and its SVG drawing stay in sync?]]></title><description><![CDATA[A 3D preview and a downloadable drawing can look consistent while quietly describing different objects. Separate mesh code, hand-drawn outlines, and approximate dimension labels tend to drift as a des]]></description><link>https://neuralwonderlab.hashnode.dev/how-can-a-moving-3d-model-and-its-svg-drawing-stay-in-sync</link><guid isPermaLink="true">https://neuralwonderlab.hashnode.dev/how-can-a-moving-3d-model-and-its-svg-drawing-stay-in-sync</guid><category><![CDATA[ThreeJS]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Jongcha Lee]]></dc:creator><pubDate>Tue, 08 Sep 2026 17:34:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aa0458d662465b41c672440/2ce41dc1-26a0-441a-ab05-b18646ee6f88.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A 3D preview and a downloadable drawing can look consistent while quietly describing different objects. Separate mesh code, hand-drawn outlines, and approximate dimension labels tend to drift as a design changes. A useful alternative is to give them the same geometry functions and make each output responsible only for its presentation.</p>
<p>HELIO, a twelve-petal kinetic canopy concept, uses this approach. Its opening angle changes from 10° to 74°. The browser renders the shells, while a separate module projects their profile boundaries into an SVG plan and elevation.</p>
<p><strong>Authorship:</strong> GPT-6 Astra generated this article and developed HELIO’s geometry and implementation under human creative direction. The explanations below were checked against the project files and its existing automated tests. This is an account of that implementation, not a claim of human-only authorship.</p>
<p><em>Cover: an actual render of the interactive model. The separate AI-generated concept illustration is not used as evidence of its geometry.</em></p>
<h2>1. Define the coordinates before the views</h2>
<p>The geometry module uses Y as up and virtual metres as its length unit. Each petal begins in local coordinates: <code>s</code> runs along its length, <code>v</code> runs across its tangent direction, and <code>q</code> describes its curved surface and thickness offset.</p>
<p>The angle <code>alpha</code> is measured outward from vertical. A second angle, <code>phi</code>, locates petal <code>i</code> around the central axis. Twelve equally spaced petals therefore have a 30° azimuth step.</p>
<p>The following is an exact excerpt from <code>worldPoint</code> in <code>helio-geometry.mjs</code>. Earlier lines validate the inputs and convert <code>alpha</code> into radians, stored in <code>a</code>:</p>
<pre><code class="language-javascript">  const phi = 2 * Math.PI * i / PARAMS.N;
  const sin = Math.sin(a), cos = Math.cos(a);
  const radial = PARAMS.r0 + explode * PARAMS.explodeRadial + s * sin + q * cos;
  const x = radial * Math.cos(phi) - v * Math.sin(phi);
  const y = PARAMS.h + explode * PARAMS.explodeHeight + s * cos - q * sin;
  const z = radial * Math.sin(phi) + v * Math.cos(phi);
  if (![x, y, z].every(Number.isFinite)) throw new RangeError('Transformed coordinates overflow.');
  return [x, y, z];
</code></pre>
<p>The sine and cosine terms rotate the length and normal directions around a tangent hinge axis. They do not stretch the petal. The <code>explode</code> terms add a display translation; they are not part of the assembled dimensions.</p>
<h2>2. Reuse the boundary, then project it</h2>
<p><code>petalShell</code> samples the profile into a closed mesh with front and back surfaces, side edges, and end caps. The renderer creates a reusable shell from it and positions the twelve copies using the corresponding hinge basis.</p>
<p>The SVG module imports <code>localPoint</code>, <code>worldPoint</code>, and <code>modelMetrics</code>. It samples the same boundary at the same default resolution: 24 lengthwise segments. It also converts boundary coordinates to Float32, matching the mesh data format.</p>
<p>The projections are intentionally simple. Plan uses X and Z; elevation uses X and Y. The vertical SVG coordinate is inverted because screen coordinates increase downward. These are the actual projection functions:</p>
<pre><code class="language-javascript">  const plan = p =&gt; [planCenter[0] + p[0] * scale, planCenter[1] + p[2] * scale];
  const elevation = p =&gt; [elevationCenter + p[0] * scale, ground - p[1] * scale];
</code></pre>
<p>This is shared parametric geometry, not a screenshot trace or a guarantee of identical GPU floating-point results. The drawing shows assembled petal shells and omits supports. Its layered outlines are not a full hidden-line removal solution.</p>
<h2>3. Measure the vertices you actually generate</h2>
<p>A tip formula is tempting, but thickness, curvature, and width can place another vertex farther away. <code>modelMetrics</code> therefore evaluates the generated shell vertices and finds the largest <code>hypot(x, z)</code>, plus minimum and maximum Y.</p>
<p>These bounds exclude scenery, the mast, the base, and exploded offsets. At 42°, the checked shell envelope radius is about 7.31 virtual metres and its maximum Y is 8.72. The drawing’s height dimension starts at Y = 0; it is not the shell bounding-box height.</p>
<h2>4. Test invariants, then state the limits</h2>
<p>The existing tests passed when rerun for this article. They check distances, thickness, and fixed hinge positions at 10°, 42°, and 74°. They also check twelvefold symmetry, finite unit normals, closed shell topology, and bounds that contain every generated shell vertex. Returning the explosion value to zero reproduces the assembled shell data.</p>
<p>These checks catch implementation inconsistencies. They do not establish actuator forces, collision clearance for every component, wind resistance, structural safety, fabrication feasibility, or weather protection.</p>
<p>To explore the relationship, <a href="https://neuralwonderlab.blogspot.com/2026/09/blog-post.html">open HELIO’s interactive model</a>, change its angle, and compare the resulting SVG. For another project, keep geometry generation separate from both rendering and document layout, then test the relationships those outputs must preserve.</p>
<p><strong>Discussion:</strong> Which invariant would you add to catch a mismatch between an interactive view and its exported drawing?</p>
]]></content:encoded></item></channel></rss>