1
0
Fork 0
freesewing/packages/sandy/src/shared.js
2019-08-03 15:03:33 +02:00

107 lines
3.2 KiB
JavaScript

const draftRingSector = (part, rot, an, radIn, radEx, rotate = false) => {
let { utils, Point, points, Path } = part.shorthand()
const roundExtended = (radius, angle = 90) => {
let arg = utils.deg2rad(angle / 2)
return (radius * 4 * (1 - Math.cos(arg))) / Math.sin(arg) / 3
}
/**
* Calculates the distance of the control point for the internal
* and external arcs using bezierCircleExtended
*/
let distIn = roundExtended(radIn, an / 2)
let distEx = roundExtended(radEx, an / 2)
// The centre of the circles
points.center = new Point(0, 0)
/**
* This function is expected to draft ring sectors for
* angles up to 180%. Since roundExtended works
* best for angles until 90º, we generate the ring
* sector using the half angle and then duplicate it
*/
/**
* The first point of the internal arc, situated at
* a radIn distance below the centre
*/
points.in1 = points.center.shift(-90, radIn)
/**
* The control point for 'in1'. It's situated at a
* distance $distIn calculated with bezierCircleExtended
* and the line between it and 'in1' is perpendicular to
* the line between 'in1' and the centre, so it's
* shifted in the direction 0º
*/
points.in1C = points.in1.shift(0, distIn)
/**
* The second point of the internal arc, situated at
* a $radIn distance of the centre in the direction
* $an/2 - 90º
*/
points.in2 = points.center.shift(an / 2 - 90, radIn)
/**
* The control point for 'in2'. It's situated at a
* distance $distIn calculated with bezierCircleExtended
* and the line between it and 'in2' is perpendicular to
* the line between 'in2' and the centre, so it's
* shifted in the direction $an/2 + 180º
*/
points.in2C = points.in2.shift(an / 2 + 180, distIn)
/**
* The points for the external arc are generated in the
* same way, using $radEx and $distEx instead
*/
points.ex1 = points.center.shift(-90, radEx)
points.ex1C = points.ex1.shift(0, distEx)
points.ex2 = points.center.shift(an / 2 - 90, radEx)
points.ex2C = points.ex2.shift(an / 2 + 180, distEx)
// Flip all the points to generate the full ring sector
for (let id of ['in2', 'in2C', 'in1C', 'ex1C', 'ex2C', 'ex2'])
points[id + 'Flipped'] = points[id].flipX()
// Rotate all the points an angle rot
for (let id of [
'in1',
'in1C',
'in2',
'in2C',
'ex1',
'ex1C',
'ex2',
'ex2C',
'in2Flipped',
'in2CFlipped',
'in1CFlipped',
'ex1CFlipped',
'ex2CFlipped',
'ex2Flipped'
])
points[id + 'Rotated'] = points[id].rotate(rot, points.center)
if (rotate) {
// Rotate all points so the line from in1Rotated to ex1Rotated is vertical
let deg = 270 - points.in2Flipped.angle(points.ex2Flipped)
for (let id in points) {
points[id] = points[id].rotate(deg, points.in2Flipped)
}
}
// Return the path of the full ring sector
return new Path()
.move(points.in2Flipped)
.curve(points.in2CFlipped, points.in1CFlipped, points.in1)
.curve(points.in1C, points.in2C, points.in2)
.line(points.ex2)
.curve(points.ex2C, points.ex1C, points.ex1)
.curve(points.ex1CFlipped, points.ex2CFlipped, points.ex2Flipped)
.close()
}
export default draftRingSector