JSCAD User Group

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    1. Home
    2. Nick Taylor
    • Profile
    • Following 0
    • Followers 0
    • Topics 1
    • Posts 1
    • Best 0
    • Controversial 0
    • Groups 0

    Nick Taylor

    @Nick Taylor

    0
    Reputation
    1
    Profile views
    1
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Nick Taylor Unfollow Follow

    Latest posts made by Nick Taylor

    • Excessively elaborate eggs etc

      Hi all - first post.

      My name is Nick Taylor - and I am an the ultimate newbie when it comes to JScad, although I did start programming in 1979, have the degree, and a couple of decades of commercial experience... which is a fancy way of saying I am a recovering web-dev.

      I now do manufacturing and design etc... and am building an electric guitar which is based on a flattened egg shape.

      So.... this is what i have so far, which generates the egg.... it is basically a parabola sitting upside down on top of a circle, joined then rotated into a 3D shape.

      I am experiencing all sorts of weirdness to do with unexpected boolean behaviour (eg: intersect does what a union should do), and I look at this code and despair.... there has GOT to be a more concise way of doing this.

      If anyone has any help or advice, I would be most eternally, tearfully grateful.

      If there is a better way of presenting this code (eg: giving it a main function), let me know.

      
      //
      // egg_shape
      // ---------------------------------------------------------------------------------
      
      function egg_shape(resolution, radius, parabola_top) {
      
          const a = findTangentA(radius, parabola_top, resolution);
          const tangentPoints = findTangentPoints(a, parabola_top, radius, resolution);
      
          const circlePoints = [];
          const rSquared = radius * radius;
          const xMax = Math.sqrt(rSquared);
          const step = 0.5;
          
          // Top half of circle
          for (let x = -xMax; x <= xMax; x += step) {
              const y = Math.sqrt(rSquared - x * x);
              circlePoints.push([x, y]);
          }
          
          // Bottom half of circle (reverse direction)
          for (let x = xMax; x >= -xMax; x -= step) {
              const y = -Math.sqrt(rSquared - x * x);
              circlePoints.push([x, y]);
          }
          
          const circleGeom = polygon({ points: circlePoints });
      
          const { xLeft, xRight } = tangentPoints;
          const parabolaPoints = [];
       
          
          for (let x = xLeft; x <= xRight; x += step) {
              const y = -a * x * x + parabola_top;
              parabolaPoints.push([x, y]);
          }
          
          const parabolaGeom = polygon({ points: parabolaPoints });
      
          // intersect does what a union should do
          const eggProfile = intersect(circleGeom, parabolaGeom);
      
          // Create 3D egg by rotating the 2D profile
          return extrudeRotate({
              segments: resolution,
              angle: Math.PI * 2
          }, eggProfile);
      }
      
      
      
      //
      // findTangentA
      // ---------------------------------------------------------------------------------
      
      function findTangentA(radius, h, resolution) {
          const R2 = radius * radius
          const stepA = 0.00001 
          const tolerance = 0.1
          const searchStep = 0.5 
          
          for (let a = 0.005; a < 0.02; a += stepA) {
              let count = 0
              for (let x = -radius; x <= radius; x += searchStep) {
                  const y = -a * x * x + h
                  const dist = x * x + y * y
                  if (Math.abs(dist - R2) < tolerance) count++
              }
              if (count === 2) return a  
          }
          
          return 0.0095  // Fallback value
      }
      
      
      
      //
      // findTangentPoints
      // ---------------------------------------------------------------------------------
      
      function findTangentPoints(a, h, radius, resolution) {
          const R2 = radius * radius
          const points = []
          const dx = 0.01 
          const tolerance = 0.001  
          
          for (let x = -radius; x <= radius; x += dx) {
              const y = -a * x * x + h
              const d = x * x + y * y
              if (Math.abs(d - R2) < tolerance) points.push(x)
          }
          
          if (points.length >= 2) {
              return { xLeft: Math.min(...points), xRight: Math.max(...points) }
          }
          return { xLeft: -radius * 0.8, xRight: radius * 0.8 }
      }
      
      
      
      posted in Design Discussions
      Nick Taylor
      Nick Taylor