164 lines
5.3 KiB
JavaScript
164 lines
5.3 KiB
JavaScript
![]() |
export default function(part) {
|
||
|
let {
|
||
|
paperless,
|
||
|
sa,
|
||
|
store,
|
||
|
complete,
|
||
|
points,
|
||
|
options,
|
||
|
macro,
|
||
|
Point,
|
||
|
paths,
|
||
|
Path,
|
||
|
measurements
|
||
|
} = part.shorthand();
|
||
|
|
||
|
const fitCap = (part, scale) => {
|
||
|
let {
|
||
|
paperless,
|
||
|
sa,
|
||
|
store,
|
||
|
complete,
|
||
|
points,
|
||
|
options,
|
||
|
macro,
|
||
|
Point,
|
||
|
paths,
|
||
|
Path,
|
||
|
measurements
|
||
|
} = part.shorthand();
|
||
|
|
||
|
let base = scale * measurements.headCircumference * (1 + options.headEase);
|
||
|
|
||
|
// Top
|
||
|
points.midFront = new Point(0, 0);
|
||
|
points.midFrontCp2 = points.midFront.shift(-90, base * 0.074);
|
||
|
points.midMid = points.midFront.shift(0, base * 0.34);
|
||
|
points.midBack = new Point(base * 0.654, base * 0.124);
|
||
|
points.midSide = new Point(base * 0.2525, base * 0.178);
|
||
|
points.midSideCp1 = points.midSide.shift(180, base * 0.185);
|
||
|
points.midSideCp2 = points.midSide.shift(0, base * 0.101);
|
||
|
points.backHollow = new Point(base * 0.488, base * 0.136);
|
||
|
points.backHollowCp1 = points.backHollow.shift(180, base * 0.033);
|
||
|
points.backHollowCp2 = points.backHollow.shift(0, base * 0.033);
|
||
|
points.backEdge = new Point(base * 0.576, base * 0.185);
|
||
|
let angle = points.backEdge.angle(points.midBack) + 90;
|
||
|
points.backSide = points.backEdge.shift(angle, base * 0.025);
|
||
|
points.backSideCp1 = points.backSide.shift(angle, base * 0.02);
|
||
|
points.midMidCp1 = points.midMid.shift(0, base * 0.1);
|
||
|
points.midBackCp2 = points.midBack.shift(angle, base * 0.09);
|
||
|
|
||
|
// Side
|
||
|
points.foldTop = new Point(0, 0);
|
||
|
points.foldTopCp1 = points.foldTop.shift(-90, base * 0.0433);
|
||
|
points.foldBottom = points.foldTop.shift(0, base * 0.126);
|
||
|
points.foldBottomCp2 = points.foldBottom.shift(-90, base * 0.0866);
|
||
|
points.tip = new Point(base * 0.411, base * 0.207);
|
||
|
points.tipCp1 = points.tip.shift(-85, base * 0.1);
|
||
|
points.tipCp2 = points.tip.shift(177, base * 0.067);
|
||
|
points.outerTop = new Point(base * 0.328, base * 0.337);
|
||
|
points.outerTopCp1 = points.outerTop.shift(180, base * 0.05);
|
||
|
points.outerTopCp2 = points.outerTop.shift(0, base * 0.05);
|
||
|
points.outerGuide = new Point(base * 0.0867, base * 0.1913);
|
||
|
points.outerGuideCp1 = points.outerGuide.shift(135, base * 0.076);
|
||
|
points.outerGuideCp2 = points.outerGuide.shift(-45, base * 0.145);
|
||
|
points.innerGuide = new Point(base * 0.22, base * 0.172);
|
||
|
points.innerGuideCp1 = points.innerGuide.shift(-38, base * 0.052);
|
||
|
points.innerGuideCp2 = points.innerGuide.shift(142, base * 0.035);
|
||
|
|
||
|
let backLength = points.backEdge.dist(points.midBack) * 2;
|
||
|
let sideLength =
|
||
|
new Path()
|
||
|
.move(points.tip)
|
||
|
.curve(points.tipCp2, points.innerGuideCp1, points.innerGuide)
|
||
|
.curve(points.innerGuideCp2, points.foldBottomCp2, points.foldBottom)
|
||
|
.length() * 2;
|
||
|
|
||
|
// Return delta between target and actual seam length
|
||
|
return (
|
||
|
measurements.headCircumference * (1 + options.headEase) -
|
||
|
(backLength + sideLength)
|
||
|
);
|
||
|
};
|
||
|
|
||
|
const sideSeamDelta = part => {
|
||
|
let { Path } = part.shorthand();
|
||
|
|
||
|
let top = new Path()
|
||
|
.move(points.midFront)
|
||
|
.curve(points.midFrontCp2, points.midSideCp1, points.midSide)
|
||
|
.curve(points.midSideCp2, points.backHollowCp1, points.backHollow)
|
||
|
.curve(points.backHollowCp2, points.backSideCp1, points.backSide)
|
||
|
.line(points.backEdge)
|
||
|
.length();
|
||
|
|
||
|
let side = new Path()
|
||
|
.move(points.foldTop)
|
||
|
.curve(points.foldTopCp1, points.outerGuideCp1, points.outerGuide)
|
||
|
.curve(points.outerGuideCp2, points.outerTopCp1, points.outerTop)
|
||
|
.curve(points.outerTopCp2, points.tipCp1, points.tip)
|
||
|
.length();
|
||
|
|
||
|
return top - side;
|
||
|
};
|
||
|
|
||
|
// Fit head
|
||
|
let scale = 1;
|
||
|
let count = 1;
|
||
|
let delta = fitCap(part, scale);
|
||
|
while (Math.abs(delta) > 1 && count < 25) {
|
||
|
count++;
|
||
|
if (delta > 0) scale = 1000 / (1000 - delta);
|
||
|
// Too small
|
||
|
else scale = 1000 / (1000 + delta); // Too large
|
||
|
delta = fitCap(part, scale);
|
||
|
}
|
||
|
|
||
|
// Match side seam
|
||
|
delta = sideSeamDelta(part);
|
||
|
count = 1;
|
||
|
let top = ["outerTop", "outerTopCp1", "outerTopCp2"];
|
||
|
let guide = ["outerGuide", "outerGuideCp1", "outerGuideCp2"];
|
||
|
while (Math.abs(delta) > 1 && count < 25) {
|
||
|
for (let i of top) points[i] = points[i].shift(-90, delta / 3);
|
||
|
for (let i of guide) points[i] = points[i].shift(-135, delta / 3);
|
||
|
delta = sideSeamDelta(part);
|
||
|
count++;
|
||
|
}
|
||
|
|
||
|
// Paths
|
||
|
paths.seam = new Path()
|
||
|
.move(points.midMid)
|
||
|
.line(points.midFront)
|
||
|
.curve(points.midFrontCp2, points.midSideCp1, points.midSide)
|
||
|
.curve(points.midSideCp2, points.backHollowCp1, points.backHollow)
|
||
|
.curve(points.backHollowCp2, points.backSideCp1, points.backSide)
|
||
|
.line(points.backEdge)
|
||
|
.line(points.midBack)
|
||
|
.curve(points.midBackCp2, points.midMidCp1, points.midMid)
|
||
|
.close()
|
||
|
.attr("class", "fabric");
|
||
|
|
||
|
paths.side = new Path()
|
||
|
.move(points.foldTop)
|
||
|
.curve(points.foldTopCp1, points.outerGuideCp1, points.outerGuide)
|
||
|
.curve(points.outerGuideCp2, points.outerTopCp1, points.outerTop)
|
||
|
.curve(points.outerTopCp2, points.tipCp1, points.tip)
|
||
|
.curve(points.tipCp2, points.innerGuideCp1, points.innerGuide)
|
||
|
.curve(points.innerGuideCp2, points.foldBottomCp2, points.foldBottom)
|
||
|
.attr("class", "fabric");
|
||
|
|
||
|
// Uncomment to see the side part here
|
||
|
paths.side.render = false;
|
||
|
|
||
|
if (complete) {
|
||
|
if (sa) {
|
||
|
}
|
||
|
|
||
|
if (paperless) {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return part;
|
||
|
}
|