Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

split the input polyline into multiple polylines when there is Nan/Nu… #49

Merged
merged 9 commits into from
Dec 26, 2020
43 changes: 38 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -516,13 +516,46 @@ Line2D.prototype.update = function (options) {
pos[ptr++] = y
}

let triangles = triangulate(pos, state.hole || [])

for (let i = 0, l = triangles.length; i < l; i++) {
if (ids[triangles[i]] != null) triangles[i] = ids[triangles[i]]
// use "ids" to track the boundary of segment
// the keys in "ids" is the end boundary of a segment, or split point
if(!(state.count-1 in ids))
ids[state.count] = state.count-1 // make sure there is at least one segment

let splits = Object.keys(ids).map(Number).sort(function(a, b){return a - b})


let split_triangles = []
let base = 0

// do not split holes
let hole_base = state.hole != null ? state.hole[0] : null
if(hole_base != null){
let last_id = splits.findIndex((e)=>e>=hole_base)
splits = splits.slice(0,last_id)
splits.push(hole_base)
}

for (let i = 0; i < splits.length; i++)
{
// create temporary pos array with only one segment and all the holes
let seg_pos = [].concat(
pos.slice(base*2, splits[i]*2),
hole_base?pos.slice(hole_base*2):[]
)
let hole = (state.hole || []).map((e)=>e-hole_base+(splits[i]-base))
let triangles = triangulate(seg_pos, hole)
// map triangle index back to the original pos buffer
triangles = triangles.map(
(e)=>(e < (splits[i] - base)) ? e + base : e - (splits[i] - base) + hole_base
)
split_triangles.push(...triangles)
base = splits[i] + 1 // skip split point
}
for (let i = 0, l = split_triangles.length; i < l; i++) {
if (ids[split_triangles[i]] != null) split_triangles[i] = ids[split_triangles[i]]
}

state.triangles = triangles
state.triangles = split_triangles
}

// update position buffers
Expand Down
26 changes: 25 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,37 @@ t('fill', t => {
strokeWidth: 6,
stroke: '#D07735',
close: false,
positions: translate(scale([0,40, 40,40, 40,80, 80,80, 80,120, 120,120, 120,160],.015,.015), 2, -1.5),
positions: translate(scale([0,40, 40,40, 40,80, 80,80, 80,120, 120,120, 120,160],.015,.015), 1.5, -1.5),
range
})

t.end()
})

t('fill segment', t => {
batch.push({
fill: '#F9F38C',
stroke: null,
close: false,
positions: translate(scale([0,40, 40,40, 40,80, NaN, NaN, 40,100, 80,100, 80,140, NaN, NaN, 80,150, 120,140, 120,160],.015,.015), 2.5, -1.5),
range
})
t.end()
})

t('fill segment with hole', t => {
batch.push({
fill: '#F9F38C',
stroke: null,
close: false,
positions: translate(scale([0,40, 40,40, 40,80, NaN, NaN, 40,100, 80,100, 80,140, 20,50, 30,50, 30,55, NaN, NaN, 80,150, 120,140, 120,160],.015,.015), 3.5, -1.5),
hole: [7,11],
range
})

t.end()
})

t('colorscale', t => {
let positions = translate(scale(flatten(curve([4, 4], [7, 10], [12, 2], [20, 4], 5)), .25, .25), -3, -1)
let colors = arrFrom({ length: positions.length / 2 }).map(x => palette[Math.floor(Math.random() * palette.length)])
Expand Down