Merge branch 'develop' into shuffle
This commit is contained in:
commit
5d8f070098
8 changed files with 137 additions and 53 deletions
|
@ -1,5 +1,5 @@
|
|||
export default function (part) {
|
||||
let {
|
||||
const {
|
||||
store,
|
||||
sa,
|
||||
Point,
|
||||
|
@ -55,7 +55,7 @@ export default function (part) {
|
|||
aboveMouth01_02d = aboveMouth01_02d + diff
|
||||
aboveMouth01_04d = aboveMouth01_04d + diff
|
||||
iteration++
|
||||
} while ((diff < -1 || diff > 1) && iteration < 100)
|
||||
} while (Math.abs(diff) > store.get('tolerance') && iteration < 100)
|
||||
|
||||
paths.seam = new Path()
|
||||
.move(points.aboveMouth01)
|
||||
|
|
|
@ -102,7 +102,7 @@ export default function (part) {
|
|||
.move(points.belly01)
|
||||
.curve(points.belly01cp1, points.belly02cp2, points.belly02)
|
||||
.length()
|
||||
} while ((diff < -1 || diff > 1) && iteration < 100)
|
||||
} while (Math.abs(diff) > store.get('tolerance') && iteration < 100)
|
||||
|
||||
let bellyTailLength = store.get('bellyTailLength')
|
||||
|
||||
|
@ -122,7 +122,7 @@ export default function (part) {
|
|||
.move(points.belly03)
|
||||
.curve(points.belly03cp1, points.belly04cp2, points.belly04)
|
||||
.length()
|
||||
} while ((diff < -1 || diff > 1) && iteration < 100)
|
||||
} while (Math.abs(diff) > store.get('tolerance') && iteration < 100)
|
||||
|
||||
points.belly05cp1 = points.belly05cp2.flipY()
|
||||
points.belly06 = points.belly04.flipY()
|
||||
|
|
|
@ -467,6 +467,9 @@ export default function (part) {
|
|||
new Path().move(points.body15).curve(points.body15cp1, points.body16cp2, points.body16).length()
|
||||
)
|
||||
|
||||
// Reduce precision as size goes up coz performance
|
||||
store.set('tolerance', (options.size < 1) ? 1 : options.size*100)
|
||||
|
||||
// Complete?
|
||||
if (complete) {
|
||||
points.bodyTailSnippet = new Path()
|
||||
|
|
|
@ -58,8 +58,7 @@ export default function (part) {
|
|||
|
||||
bottomFin01_03d = bottomFin01_03d + diff
|
||||
iteration++
|
||||
} while ((diff < -1 || diff > 1) && iteration < 100)
|
||||
console.log({ iteration1: iteration })
|
||||
} while (Math.abs(diff) > store.get('tolerance') && iteration < 100)
|
||||
|
||||
diff = 0
|
||||
iteration = 0
|
||||
|
@ -85,7 +84,7 @@ export default function (part) {
|
|||
|
||||
bottomFin01_02d = bottomFin01_02d + diff
|
||||
iteration++
|
||||
} while ((diff < -1 || diff > 1) && iteration < 100)
|
||||
} while (Math.abs(diff) > store.get('tolerance') && iteration < 100)
|
||||
|
||||
paths.seam = new Path()
|
||||
.move(points.bottomFin01)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { createTeeth } from './teeth.js'
|
||||
|
||||
export default function (part) {
|
||||
let {
|
||||
const {
|
||||
store,
|
||||
sa,
|
||||
Point,
|
||||
|
@ -21,17 +21,23 @@ export default function (part) {
|
|||
let lowerTeeth01_02a = 25.414236606099728 + 180
|
||||
let lowerTeeth02cp1d = 47.74891452755759 * options.size
|
||||
let lowerTeeth02cp1a = 42.59332849750379
|
||||
let lowerTeeth01cp2d = 17.774046078481962 * options.size
|
||||
let lowerTeeth01cp2d = 27.774046078481962 * options.size
|
||||
let lowerTeeth01cp2a = 180
|
||||
|
||||
points.lowerTeeth01 = new Point(0, 0)
|
||||
points.lowerTeeth02 = points.lowerTeeth01.shift(lowerTeeth01_02a, lowerTeeth01_02d)
|
||||
points.lowerTeeth01cp2 = points.lowerTeeth01.shift(lowerTeeth01cp2a, lowerTeeth01cp2d)
|
||||
points.lowerTeeth02cp1 = points.lowerTeeth02.shift(lowerTeeth02cp1a, lowerTeeth02cp1d)
|
||||
// Make seam symmetric to optimize generating teeth
|
||||
points.lowerTeeth02cp1 = points.lowerTeeth02.shiftTowards(
|
||||
points.lowerTeeth02cp1,
|
||||
points.lowerTeeth01cp2.dist(points.lowerTeeth01)
|
||||
)
|
||||
points.lowerTeeth03 = points.lowerTeeth02.flipX()
|
||||
points.lowerTeeth01cp1 = points.lowerTeeth01cp2.flipX()
|
||||
points.lowerTeeth03cp2 = points.lowerTeeth02cp1.flipX()
|
||||
|
||||
|
||||
paths.seam = new Path()
|
||||
.move(points.lowerTeeth02)
|
||||
.curve(points.lowerTeeth02cp1, points.lowerTeeth01cp2, points.lowerTeeth01)
|
||||
|
@ -39,9 +45,17 @@ export default function (part) {
|
|||
|
||||
store.set('lowerTeethLength', paths.seam.length())
|
||||
|
||||
paths.teeth = new Path().move(paths.seam.start())
|
||||
|
||||
createTeeth(paths.seam, 16 * options.size, 8 * options.size, 10, options.aggressive, paths.teeth)
|
||||
paths.teeth = createTeeth(
|
||||
[ // Array holding the points for half a mouth (bezier, not path)
|
||||
points.lowerTeeth02, // start
|
||||
points.lowerTeeth02cp1, // cp1
|
||||
points.lowerTeeth01cp2, // cp2
|
||||
points.lowerTeeth01, // end
|
||||
],
|
||||
10, // number of teeth
|
||||
16, // size
|
||||
part
|
||||
)
|
||||
|
||||
// Complete?
|
||||
if (complete) {
|
||||
|
@ -78,10 +92,8 @@ export default function (part) {
|
|||
noStartMarker: true,
|
||||
noEndMarker: true,
|
||||
})
|
||||
console.log({path:paths.teeth})
|
||||
console.log({point:paths.teeth.edge('top')})
|
||||
macro('vd', {
|
||||
from: points.lowerTeeth01,
|
||||
from: points.lowerTeeth01,
|
||||
to: paths.teeth.edge('top'),
|
||||
x: points.lowerTeeth02.x - sa - 10,
|
||||
noStartMarker: true,
|
||||
|
|
|
@ -1,37 +1,93 @@
|
|||
export function createTeeth(path, largeTeeth, smallTeeth, numberOfTeeth, aggressive, newPath) {
|
||||
let c = 0.55191502449351
|
||||
import { utils } from '@freesewing/core'
|
||||
const { Bezier } = utils
|
||||
|
||||
let pLength = path.length()
|
||||
let stepLength = pLength / numberOfTeeth
|
||||
/*
|
||||
* This method generates Hi's teeth.
|
||||
* Growing teeth is not easy and it was making the pattern slow.
|
||||
* So this method was optimized by @joostdeock to use the underlying
|
||||
* Bezier object * rather than the higher-level path object
|
||||
*/
|
||||
export function createTeeth(pnts, toothCount, toothSize, part) {
|
||||
|
||||
let teethStep = (largeTeeth - smallTeeth) / (numberOfTeeth / 2 - 1)
|
||||
let teethDirection = 1
|
||||
// Deconstruct what we need from the part via shorthand()
|
||||
const { Path, points, Point, options } = part.shorthand()
|
||||
|
||||
let teethSize = smallTeeth
|
||||
for (var i = 0; i < numberOfTeeth; i++) {
|
||||
if (i == numberOfTeeth / 2) teethDirection = 0
|
||||
if (i > numberOfTeeth / 2) teethDirection = -1
|
||||
// These 4 points make up our cubic bezier curve which in turn is half of the mouth
|
||||
const [ start, cp1, cp2, end ] = pnts
|
||||
|
||||
teethSize += teethStep * teethDirection
|
||||
let startP = path.shiftAlong(stepLength * i)
|
||||
let midP = path.shiftAlong(stepLength * (i + 0.5))
|
||||
let endP = path.shiftAlong(stepLength * (i + 1))
|
||||
let midPangle = midP.angle(path.shiftAlong(stepLength * (i + 0.5) + 0.1)) + 90
|
||||
midP = midP.shift(midPangle, teethSize)
|
||||
let startPcp = startP.shift(
|
||||
startP.angle(path.shiftAlong(stepLength * i + 0.1)) + 90,
|
||||
teethSize * c
|
||||
)
|
||||
let endPcp = endP.shift(
|
||||
endP.angle(path.shiftAlong(stepLength * (i + 1) - 0.1)) - 90,
|
||||
teethSize * c
|
||||
)
|
||||
let midPcp1 = midP.shift(midPangle - 90, stepLength * c * (aggressive ? 0.05 : 0.7))
|
||||
let midPcp2 = midP.shift(midPangle + 90, stepLength * c * (aggressive ? 0.05 : 0.7))
|
||||
// Create the Bezier object from the 4 points
|
||||
const halfMouth = new Bezier(...pnts)
|
||||
|
||||
newPath.curve(startPcp, midPcp2, midP)
|
||||
newPath.curve(midPcp1, endPcp, endP)
|
||||
// Center of the mouth
|
||||
const center = pnts[3]
|
||||
// Path that makes up the left half
|
||||
const left = new Path().move(pnts[0])
|
||||
// Path that makes up the right half
|
||||
const right = new Path().move(pnts[0].flipX(center))
|
||||
|
||||
// Get a lookup table (LUT) of points along the Bezier
|
||||
const lut = halfMouth.getLUT(toothCount + 2)
|
||||
|
||||
// Iterating over our LUT where p holds a number ID that we'll
|
||||
// use to 'look back' to the other side of the tooth
|
||||
for (const p in lut) {
|
||||
|
||||
// Tooth size varies across the curve
|
||||
const size = (toothSize*options.size) + (toothSize*options.size) * p/15
|
||||
|
||||
// Coordinates from the LUT
|
||||
const { x, y } = lut[p]
|
||||
// Create left half point at p
|
||||
points[`leftTooth${p}`] = new Point(x, y)
|
||||
// Mirror (flipX)to find right half point at p
|
||||
points[`rightTooth${p}`] = points[`leftTooth${p}`].flipX(center)
|
||||
|
||||
// This returns the normalized vector (nv) at p,
|
||||
// in other words, the tangent + 90 degrees
|
||||
const nv = halfMouth.normal(lut[p].t)
|
||||
|
||||
// Create control points for left half at p
|
||||
points[`leftTooth${p}Cp`] = new Point(x-size*nv.x, y-size*nv.y)
|
||||
// Mirror (flipX) to find control points for right half at p
|
||||
points[`rightTooth${p}Cp`] = points[`leftTooth${p}Cp`].flipX(center)
|
||||
|
||||
// Skip the start point, the every 2 points, draw a teeth
|
||||
// p = end of the tooth
|
||||
// p - 2 = start of the tooth
|
||||
if (p > 0 && p%2 === 0) {
|
||||
if (options.aggressive) {
|
||||
// For pointy tooth, find point between the two control points to form the tip
|
||||
points[`leftTooth${p}Tip`] = points[`leftTooth${(p - 2)}Cp`].shiftFractionTowards(points[`leftTooth${(p)}Cp`], 0.5)
|
||||
points[`rightTooth${p}Tip`] = points[`leftTooth${p}Tip`].flipX(center)
|
||||
// Now draw tooth with shared control points for that pointy look
|
||||
left.curve(
|
||||
points[`leftTooth${(p)}Tip`],
|
||||
points[`leftTooth${(p)}Tip`],
|
||||
points[`leftTooth${p}`]
|
||||
)
|
||||
// Do the same for the right half
|
||||
right.curve(
|
||||
points[`rightTooth${(p)}Tip`],
|
||||
points[`rightTooth${(p)}Tip`],
|
||||
points[`rightTooth${p}`]
|
||||
)
|
||||
} else {
|
||||
// Draw regular tooth in the left half
|
||||
left.curve(
|
||||
points[`leftTooth${(p - 2)}Cp`],
|
||||
points[`leftTooth${p}Cp`],
|
||||
points[`leftTooth${p}`]
|
||||
)
|
||||
// Do the same for the right half
|
||||
right.curve(
|
||||
points[`rightTooth${(p - 2)}Cp`],
|
||||
points[`rightTooth${p}Cp`],
|
||||
points[`rightTooth${p}`]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
// Return joined paths to get the full set of teeth
|
||||
return left.join(right.reverse())
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ export default function (part) {
|
|||
|
||||
topFinOpening = topFinOpening + diff
|
||||
iteration++
|
||||
} while ((diff < -1 || diff > 1) && iteration < 100)
|
||||
} while (Math.abs(diff) > store.get('tolerance') && iteration < 100)
|
||||
|
||||
paths.seam = new Path()
|
||||
.move(points.topFin01)
|
||||
|
@ -140,7 +140,7 @@ export default function (part) {
|
|||
to: points.topFin01,
|
||||
x: points.topFinLeft.x -sa - 20,
|
||||
})
|
||||
}
|
||||
}
|
||||
// if( options.size < 1.5 ) {
|
||||
// paths.smallTop.attr('data-text-class', 'text-xs')
|
||||
// paths.smallBottom.attr('data-text-class', 'text-xs')
|
||||
|
|
|
@ -19,15 +19,20 @@ export default function (part) {
|
|||
|
||||
let upperTeeth01_02d = 131.305041182736 * options.size
|
||||
let upperTeeth01_02a = 34.147056946748805 + 180
|
||||
let upperTeeth02cp1d = 84.30113337316406 * options.size
|
||||
let upperTeeth02cp1d = 64.30113337316406 * options.size
|
||||
let upperTeeth02cp1a = 55.1335930733262
|
||||
let upperTeeth01cp2d = 18.331000000000017 * options.size
|
||||
let upperTeeth01cp2d = 48.331000000000017 * options.size
|
||||
let upperTeeth01cp2a = 180
|
||||
|
||||
points.upperTeeth01 = new Point(0, 0)
|
||||
points.upperTeeth02 = points.upperTeeth01.shift(upperTeeth01_02a, upperTeeth01_02d)
|
||||
points.upperTeeth01cp2 = points.upperTeeth01.shift(upperTeeth01cp2a, upperTeeth01cp2d)
|
||||
points.upperTeeth02cp1 = points.upperTeeth02.shift(upperTeeth02cp1a, upperTeeth02cp1d)
|
||||
// Make seam symmetric to optimize generating teeth
|
||||
points.upperTeeth02cp1 = points.upperTeeth02.shiftTowards(
|
||||
points.upperTeeth02cp1,
|
||||
points.upperTeeth01cp2.dist(points.upperTeeth01)
|
||||
)
|
||||
points.upperTeeth03 = points.upperTeeth02.flipX()
|
||||
points.upperTeeth01cp1 = points.upperTeeth01cp2.flipX()
|
||||
points.upperTeeth03cp2 = points.upperTeeth02cp1.flipX()
|
||||
|
@ -39,9 +44,20 @@ export default function (part) {
|
|||
|
||||
store.set('upperTeethLength', paths.seam.length())
|
||||
|
||||
paths.teeth = new Path().move(paths.seam.start())
|
||||
//paths.teeth = new Path().move(paths.seam.start())
|
||||
|
||||
createTeeth(paths.seam, 18 * options.size, 9 * options.size, 15, options.aggressive, paths.teeth)
|
||||
paths.teeth = createTeeth(
|
||||
[ // Array holding the points for half a mouth (bezier, not path)
|
||||
points.upperTeeth02, // start
|
||||
points.upperTeeth02cp1, // cp1
|
||||
points.upperTeeth01cp2, // cp2
|
||||
points.upperTeeth01, // end
|
||||
],
|
||||
14, // number of teeth
|
||||
14, // size
|
||||
part
|
||||
)
|
||||
//createTeeth(paths.seam, 18 * options.size, 9 * options.size, 15, options.aggressive, paths.teeth)
|
||||
|
||||
// Complete?
|
||||
if (complete) {
|
||||
|
@ -78,10 +94,8 @@ export default function (part) {
|
|||
noStartMarker: true,
|
||||
noEndMarker: true,
|
||||
})
|
||||
console.log({path:paths.teeth})
|
||||
console.log({point:paths.teeth.edge('top')})
|
||||
macro('vd', {
|
||||
from: points.upperTeeth01,
|
||||
from: points.upperTeeth01,
|
||||
to: paths.teeth.edge('top'),
|
||||
x: points.upperTeeth02.x - sa - 10,
|
||||
noStartMarker: true,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue