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.

mjs
design/src/bib
function draftBib({
  Path,
  Point,
  paths,
  points,
  measurements,
  options,
  utils,
  macro,
  part,
}
) {

  /*
   * Construct the neck opening
   */
  const target = (measurements.head * options.neckRatio) / 4
  let tweak = 1
  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() // Add this line

    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.tipRight = points.edgeTop.translate(strap / 2, strap / 2)
  points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y)
  points.tipRightBottom = new Point(points.tipRight.x, points.top.y)

  /*
   * Macros will return the auto-generated IDs
   */
  const ids1 = {
    tipRightTop: macro("round", {
      id: "tipRightTop",
      from: points.edgeTop,
      to: points.tipRight,
      via: points.tipRightTop,
    }),
    tipRightBottom: macro("round", {
      id: "tipRightBottom",
      from: points.tipRight,
      to: points.top,
      via: points.tipRightBottom,
    })
  }

  /*
   * 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()
    }
  }

  const rotateThese = [
    "edgeTopLeftCp",
    "edgeTop",
    "tipRight",
    "tipRightTop",
    "tipRightTopStart",
    "tipRightTopCp1",
    "tipRightTopCp2",
    "tipRightTopEnd",
    "tipRightBottomStart",
    "tipRightBottomCp1",
    "tipRightBottomCp2",
    "tipRightBottomEnd",
    "tipRightBottom",
    "top",
    "topCp2"
  ]
  while (points.tipRightBottomStart.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.tipLeftTopStart = points.tipRightTopStart.flipX()
  points.tipLeftTopCp1 = points.tipRightTopCp1.flipX()
  points.tipLeftTopCp2 = points.tipRightTopCp2.flipX()
  points.tipLeftTopEnd = points.tipRightTopEnd.flipX()
  points.tipLeftBottomStart = points.tipRightBottomStart.flipX()
  points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX()
  points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX()
  points.tipLeftBottomEnd = points.tipRightBottomEnd.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.tipLeftTopStart ) .curve( points.tipLeftTopCp1, points.tipLeftTopCp2, points.tipLeftTopEnd ) .curve( points.tipLeftBottomCp1, points.tipLeftBottomCp2, points.tipLeftBottomEnd ) .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.tipRightBottomEnd ) .curve( points.tipRightBottomCp2, points.tipRightBottomCp1, points.tipRightBottomStart ) .curve( points.tipRightTopCp2, points.tipRightTopCp1, points.tipRightTopStart ) .curve( points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft ) .close() .addClass("fabric") return part }