11const { TAU } = require ( '../../maths/constants' )
2- const slice = require ( './slice' )
32const mat4 = require ( '../../maths/mat4' )
4- const extrudeFromSlices = require ( './extrudeFromSlices' )
3+
54const geom2 = require ( '../../geometries/geom2' )
65
6+ const extrudeFromSlices = require ( './extrudeFromSlices' )
7+ const slice = require ( './slice' )
8+
79/**
810 * Perform a helical extrude of the geometry, using the given options.
911 *
1012 * @param {Object } options - options for extrusion
11- * @param {Number } [options.angle=TAU] - angle of the extrusion (RADIANS) positive for right-hand rotation, negative for left-hand
13+ * @param {Number } [options.angle=TAU] - angle of the extrusion (RADIANS); positive for right-hand rotation, negative for left-hand
1214 * @param {Number } [options.startAngle=0] - start angle of the extrusion (RADIANS)
13- * @param {Number } [options.pitch=10] - elevation gain for each turn
15+ * @param {Number } [options.pitch=10] - elevation gain for each full rotation
1416 * @param {Number } [options.height] - total height of the helix path. Ignored if pitch is set.
1517 * @param {Number } [options.endOffset=0] - offset the final radius of the extrusion, allowing for tapered helix, and or spiral
1618 * @param {Number } [options.segmentsPerRotation=32] - number of segments per full rotation of the extrusion
@@ -20,24 +22,23 @@ const geom2 = require('../../geometries/geom2')
2022 *
2123 * @example
2224 * const myshape = circle({size: 3, center: [10, 0]}) // position for extrusion about Z
23- * const mycoil = extrudeHelical({angle: TAU* 2, pitch: 10, segmentsPerRotation: 64}, myshape))
25+ * const mycoil = extrudeHelical({angle: TAU * 2, pitch: 10, segmentsPerRotation: 64}, myshape))
2426 */
2527const extrudeHelical = ( options , geometry ) => {
2628 const defaults = {
2729 angle : TAU ,
2830 startAngle : 0 ,
2931 pitch : 10 ,
32+ height : 0 ,
3033 endOffset : 0 ,
3134 segmentsPerRotation : 32
3235 }
33- const { angle, endOffset, segmentsPerRotation, startAngle } = Object . assign ( { } , defaults , options )
34-
35- let pitch
36- // ignore height if pitch is set
37- if ( ! options . pitch && options . height ) {
38- pitch = options . height / ( angle / TAU )
39- } else {
40- pitch = options . pitch ? options . pitch : defaults . pitch
36+ let { angle, startAngle, pitch, height, endOffset, segmentsPerRotation } = Object . assign ( { } , defaults , options )
37+
38+ // calculate pitch from height if available
39+ if ( height != 0 ) {
40+ // height / number of full rotations
41+ pitch = height / ( angle / TAU )
4142 }
4243
4344 // needs at least 3 segments for each revolution
@@ -46,7 +47,7 @@ const extrudeHelical = (options, geometry) => {
4647 if ( segmentsPerRotation < minNumberOfSegments ) { throw new Error ( 'The number of segments per rotation needs to be at least 3.' ) }
4748
4849 const shapeSides = geom2 . toSides ( geometry )
49- if ( shapeSides . length === 0 ) throw new Error ( 'the given geometry cannot be empty' )
50+ if ( shapeSides . length === 0 ) throw new Error ( 'The given geometry cannot be empty' )
5051
5152 // const pointsWithNegativeX = shapeSides.filter((s) => (s[0][0] < 0))
5253 const pointsWithPositiveX = shapeSides . filter ( ( s ) => ( s [ 0 ] [ 0 ] >= 0 ) )
@@ -60,9 +61,11 @@ const extrudeHelical = (options, geometry) => {
6061
6162 const calculatedSegments = Math . round ( segmentsPerRotation / TAU * Math . abs ( angle ) )
6263 const segments = calculatedSegments >= 2 ? calculatedSegments : 2
64+
6365 // define transform matrix variables for performance increase
6466 const step1 = mat4 . create ( )
65- let matrix
67+ const step2 = mat4 . create ( )
68+
6669 const sliceCallback = ( progress , index , base ) => {
6770 const zRotation = startAngle + angle / segments * index
6871 const xOffset = endOffset / segments * index
@@ -84,14 +87,13 @@ const extrudeHelical = (options, geometry) => {
8487 mat4 . fromXRotation ( mat4 . create ( ) , - TAU / 4 * Math . sign ( angle ) ) // rotate the slice correctly to not create inside-out polygon
8588 )
8689
87- matrix = mat4 . create ( )
8890 mat4 . multiply (
89- matrix ,
91+ step2 ,
9092 // finally rotate around Z axis
9193 mat4 . fromZRotation ( mat4 . create ( ) , zRotation ) ,
9294 step1
9395 )
94- return slice . transform ( matrix , base )
96+ return slice . transform ( step2 , base )
9597 }
9698
9799 return extrudeFromSlices (
0 commit comments