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 } }
-
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
-
@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