JSCAD User Group

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups

    Excessively elaborate eggs etc

    Design Discussions
    3
    3
    305
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Nick Taylor
      Nick Taylor last edited by Nick Taylor

      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 }
      }
      
      
      
      hrgdavor z3dev 2 Replies Last reply Reply Quote 0
      • z3dev
        z3dev @Nick Taylor last edited by

        The booleans are working fine but the orientation of the polygons are super important. You can check the orientation your self, but one of the easiest checks if volume().

        Hope that helps

        1 Reply Last reply Reply Quote 0
        • hrgdavor
          hrgdavor @Nick Taylor last edited by

          @Nick-Taylor this script looks incomplete, it is better to share a full script.

          also if you have discord we have a channel there https://discord.gg/6PB7qZ4HC7

          1 Reply Last reply Reply Quote 0
          • First post
            Last post
          Powered by NodeBB | Contributors