跳到主要内容

Rounding the corners

We already know how to round corners, we'll have the round macro take care of that for us.

With our corners rounded, we should also update our path. Fortunately, we merely have to update the start of it.

function draftBib({
Path,
Point,
paths,
points,
measurements,
options,
utils,
macro,
part,
}) {

/*
* Construct the quarter neck opening
*/
let tweak = 1
let target = (measurements.head * options.neckRatio) /4
let delta
do {
points.right = new Point(
tweak * measurements.head / 10,
0
)
points.bottom = new Point(
0,
tweak * measurements.head / 12
)

points.rightCp1 = points.right.shift(
90,
points.bottom.dy(points.right) / 2
)
points.bottomCp2 = points.bottom.shift(
0,
points.bottom.dx(points.right) / 2
)

paths.quarterNeck = new Path()
.move(points.right)
.curve(
points.rightCp1,
points.bottomCp2,
points.bottom
)
.hide()

delta = paths.quarterNeck.length() - target
if (delta > 0) tweak = tweak * 0.99
else tweak = tweak * 1.02
} while (Math.abs(delta) > 1)

/*
* Construct the complete neck opening
*/
points.rightCp2 = points.rightCp1.flipY()
points.bottomCp1 = points.bottomCp2.flipX()
points.left = points.right.flipX()
points.leftCp1 = points.rightCp2.flipX()
points.leftCp2 = points.rightCp1.flipX()
points.top = points.bottom.flipY()
points.topCp1 = points.bottomCp2.flipY()
points.topCp2 = points.bottomCp1.flipY()

// Drawing the bib outline
const width = measurements.head * options.widthRatio
const length = measurements.head * options.lengthRatio

points.topLeft = new Point(
width / -2,
points.top.y - (width / 2 - points.right.x)
)
points.topRight = points.topLeft.shift(0, width)
points.bottomLeft = points.topLeft.shift(-90, length)
points.bottomRight = points.topRight.shift(-90, length)

/*
* Shape the straps
*/
points.edgeLeft = new Point(points.topLeft.x, points.left.y)
points.edgeRight = new Point(points.topRight.x, points.right.y)
points.edgeTop = new Point(0, points.topLeft.y)

points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5)
points.edgeRightCp = points.edgeLeftCp.flipX()
points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards(
points.topLeft,
0.5
)
points.edgeTopRightCp = points.edgeTopLeftCp.flipX()

// Round the straps
const strap = points.edgeTop.dy(points.top)

points.提示Right = points.edgeTop.translate(strap / 2, strap / 2)
points.提示RightTop = new Point(points.提示Right.x, points.edgeTop.y)
points.提示RightBottom = new Point(points.提示Right.x, points.top.y)

/*
* Macros will return the auto-generated IDs
*/
const ids1 = {
提示RightTop: macro("round", {
id: "提示RightTop",
from: points.edgeTop,
to: points.提示Right,
via: points.提示RightTop,
}),
提示RightBottom: macro("round", {
id: "提示RightBottom",
from: points.提示Right,
to: points.top,
via: points.提示RightBottom,
})
}

/*
* Create points from them with easy names
*/
for (const side in ids1) {
for (const id of ['start', 'cp1', 'cp2', 'end']) {
points[`${side}${utils.capitalize(id)}`] = points[ids1[side].points[id]].copy()
}
}

/*
* This is the list of points we need to rotate
* to move our strap out of the way
*/
const rotateThese = [
"edgeTopLeftCp",
"edgeTop",
"提示Right",
"提示RightTop",
"提示RightTopStart",
"提示RightTopCp1",
"提示RightTopCp2",
"提示RightTopEnd",
"提示RightBottomStart",
"提示RightBottomCp1",
"提示RightBottomCp2",
"提示RightBottomEnd",
"提示RightBottom",
"top",
"topCp2"
]
/*
* We're rotating all the points in
* the `rotateThese` array around
* the `edgeLeft` point.
*
* We're using increments of 1 degree
* until the `提示RightBottomStart` point
* is 1 mm beyond the center of our bib.
*/
while (points.提示RightBottomStart.x > -1) {
for (const p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft)
}

// Add points for second strap
points.edgeTopRightCp = points.edgeTopLeftCp.flipX()
points.topCp1 = points.topCp2.flipX()
points.提示LeftTopStart = points.提示RightTopStart.flipX()
points.提示LeftTopCp1 = points.提示RightTopCp1.flipX()
points.提示LeftTopCp2 = points.提示RightTopCp2.flipX()
points.提示LeftTopEnd = points.提示RightTopEnd.flipX()
points.提示LeftBottomStart = points.提示RightBottomStart.flipX()
points.提示LeftBottomCp1 = points.提示RightBottomCp1.flipX()
points.提示LeftBottomCp2 = points.提示RightBottomCp2.flipX()
points.提示LeftBottomEnd = points.提示RightBottomEnd.flipX()

/*
* Round the bottom corners
* Macros will return the auto-generated IDs
*/
const ids2 = {
bottomLeft: macro("round", {
id: "bottomLeft",
from: points.topLeft,
to: points.bottomRight,
via: points.bottomLeft,
radius: points.bottomRight.x / 4,
}),
bottomRight: macro("round", {
id: "bottomRight",
from: points.bottomLeft,
to: points.topRight,
via: points.bottomRight,
radius: points.bottomRight.x / 4,
})
}

/*
* Create points from them with easy names
*/
for (const side in ids2) {
for (const id of ['start', 'cp1', 'cp2', 'end']) {
points[`${side}${utils.capitalize(id)}`] = points[ids2[side].points[id]].copy()
}
}

// Create one path for the bib outline
paths.seam = new Path()
.move(points.edgeLeft)
/* We only need to replace the start
* with the new lines below
.line(points.bottomLeft)
.line(points.bottomRight)
*/
.line(points.bottomLeftStart)
.curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd)
.line(points.bottomRightStart)
.curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd)
.line(points.edgeRight)
.curve(
points.edgeRightCp,
points.edgeTopRightCp,
points.提示LeftTopStart
)
.curve(
points.提示LeftTopCp1,
points.提示LeftTopCp2,
points.提示LeftTopEnd
)
.curve(
points.提示LeftBottomCp1,
points.提示LeftBottomCp2,
points.提示LeftBottomEnd
)
.curve(
points.topCp1,
points.rightCp2,
points.right
)
.curve(
points.rightCp1,
points.bottomCp2,
points.bottom
)
.curve(
points.bottomCp1,
points.leftCp2,
points.left
)
.curve(
points.leftCp1,
points.topCp2,
points.提示RightBottomEnd
)
.curve(
points.提示RightBottomCp2,
points.提示RightBottomCp1,
points.提示RightBottomStart
)
.curve(
points.提示RightTopCp2,
points.提示RightTopCp1,
points.提示RightTopStart
)
.curve(
points.edgeTopLeftCp,
points.edgeLeftCp,
points.edgeLeft
)
.close()
.addClass("fabric")

return part
}

The shape of our bib is now completed