2019-07-12 13:13:09 +02:00
|
|
|
const draftRingSector = (part, rot, an, radIn, radEx, rotate = false) => {
|
2019-07-13 09:21:09 +02:00
|
|
|
let { utils, Point, points, Path } = part.shorthand();
|
2019-07-12 10:04:42 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2019-07-12 13:13:09 +02:00
|
|
|
if (rotate) {
|
|
|
|
// Rotate all points so the line from in1Rotated to ex1Rotated is vertical
|
2019-07-13 08:22:35 +02:00
|
|
|
let deg = 270 - points.in2Flipped.angle(points.ex2Flipped);
|
2019-07-12 13:13:09 +02:00
|
|
|
for (let id in points) {
|
2019-07-13 08:22:35 +02:00
|
|
|
points[id] = points[id].rotate(deg, points.in2Flipped);
|
2019-07-12 13:13:09 +02:00
|
|
|
}
|
|
|
|
}
|
2019-07-12 10:04:42 +02:00
|
|
|
// 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;
|