Speed up with horizintal line intersect.
This commit is contained in:
parent
b9402e592d
commit
367a86b566
|
@ -2103,6 +2103,17 @@ when defined(pixieSweeps):
|
||||||
line.winding = s[1]
|
line.winding = s[1]
|
||||||
return line
|
return line
|
||||||
|
|
||||||
|
proc intersectsYLine(y: float32, s: Segment, atx: var float32): bool {.inline.} =
|
||||||
|
let
|
||||||
|
s2y = s.to.y - s.at.y
|
||||||
|
denominator = -s2y
|
||||||
|
numerator = s.at.y - y
|
||||||
|
u = numerator / denominator
|
||||||
|
if u >= 0 and u <= 1:
|
||||||
|
let at = s.at + (u * vec2(s.to.x - s.at.x, s2y))
|
||||||
|
atx = at.x
|
||||||
|
return true
|
||||||
|
|
||||||
proc binaryInsert(arr: var seq[float32], v: float32) =
|
proc binaryInsert(arr: var seq[float32], v: float32) =
|
||||||
if arr.len == 0:
|
if arr.len == 0:
|
||||||
arr.add(v)
|
arr.add(v)
|
||||||
|
@ -2202,7 +2213,7 @@ when defined(pixieSweeps):
|
||||||
bounds = computeBounds(segments).snapToPixels()
|
bounds = computeBounds(segments).snapToPixels()
|
||||||
startX = max(0, bounds.x.int)
|
startX = max(0, bounds.x.int)
|
||||||
|
|
||||||
if segments.len == 0:
|
if segments.len == 0 or bounds.w.int == 0 or bounds.h.int == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Create sorted segments.
|
# Create sorted segments.
|
||||||
|
@ -2227,14 +2238,13 @@ when defined(pixieSweeps):
|
||||||
let s = segments[lastSeg]
|
let s = segments[lastSeg]
|
||||||
|
|
||||||
if s[0].to.y != cutLines[i + 1]:
|
if s[0].to.y != cutLines[i + 1]:
|
||||||
var at: Vec2
|
var atx: float32
|
||||||
var seg = s[0]
|
var seg = s[0]
|
||||||
for j in i ..< sweeps.len:
|
for j in i ..< sweeps.len:
|
||||||
let y = cutLines[j + 1]
|
let y = cutLines[j + 1]
|
||||||
#TODO: speed up with horizintal line intersect
|
if intersectsYLine(y, seg, atx):
|
||||||
if intersects(line(vec2(0, y), vec2(1, y)), seg, at):
|
sweeps[j].add(toLine((segment(seg.at, vec2(atx, y)), s[1])))
|
||||||
sweeps[j].add(toLine((segment(seg.at, at), s[1])))
|
seg = segment(vec2(atx, y), seg.to)
|
||||||
seg = segment(at, seg.to)
|
|
||||||
else:
|
else:
|
||||||
if seg.at.y != seg.to.y:
|
if seg.at.y != seg.to.y:
|
||||||
sweeps[j].add(toLine(s))
|
sweeps[j].add(toLine(s))
|
||||||
|
@ -2288,6 +2298,41 @@ when defined(pixieSweeps):
|
||||||
break
|
break
|
||||||
inc i
|
inc i
|
||||||
|
|
||||||
|
# i = 0
|
||||||
|
# while i < sweeps.len:
|
||||||
|
# # TODO: Maybe finds all cuts first, add them to array, cut all lines at once.
|
||||||
|
# for t in 0 ..< 10: # TODO: maybe while true:
|
||||||
|
# # keep cutting sweep
|
||||||
|
# var needsCut = false
|
||||||
|
# var cutterLine: float32 = 0
|
||||||
|
# block doubleFor:
|
||||||
|
# for a in sweeps[i]:
|
||||||
|
# let aSeg = segment(vec2(a.atx, cutLines[i]), vec2(a.tox, cutLines[i+1]))
|
||||||
|
# for b in sweeps[i]:
|
||||||
|
# let bSeg = segment(vec2(b.atx, cutLines[i]), vec2(b.tox, cutLines[i+1]))
|
||||||
|
# var at: Vec2
|
||||||
|
# if intersectsInner(aSeg, bSeg, at):
|
||||||
|
# needsCut = true
|
||||||
|
# cutterLine = at.y
|
||||||
|
# break doubleFor
|
||||||
|
# # TODO enable?
|
||||||
|
# if false and needsCut:
|
||||||
|
# # Doing a cut.
|
||||||
|
# var
|
||||||
|
# thisSweep = sweeps[i]
|
||||||
|
# sweeps[i].setLen(0)
|
||||||
|
# sweeps.insert(newSeq[SweepLine](), i + 1)
|
||||||
|
# for a in thisSweep:
|
||||||
|
# let seg = segment(vec2(a.atx, cutLines[i]), vec2(a.tox, cutLines[i+1]))
|
||||||
|
# var at: Vec2
|
||||||
|
# if intersects(line(vec2(0, cutterLine), vec2(1, cutterLine)), seg, at):
|
||||||
|
# sweeps[i+0].add(toLine((segment(seg.at, at), a.winding)))
|
||||||
|
# sweeps[i+1].add(toLine((segment(at, seg.to), a.winding)))
|
||||||
|
# cutLines.binaryInsert(cutterLine)
|
||||||
|
# else:
|
||||||
|
# break
|
||||||
|
# inc i
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
while i < sweeps.len:
|
while i < sweeps.len:
|
||||||
# Sort the sweep by X
|
# Sort the sweep by X
|
||||||
|
@ -2347,11 +2392,11 @@ when defined(pixieSweeps):
|
||||||
swX = mix(sweep[i+0].atx, sweep[i+0].tox, yFracBottom)
|
swX = mix(sweep[i+0].atx, sweep[i+0].tox, yFracBottom)
|
||||||
seX = mix(sweep[i+1].atx, sweep[i+1].tox, yFracBottom)
|
seX = mix(sweep[i+1].atx, sweep[i+1].tox, yFracBottom)
|
||||||
|
|
||||||
minWi = min(nwX, swX).int
|
minWi = min(nwX, swX).int#.clamp(startX, coverages.len + startX)
|
||||||
maxWi = max(nwX, swX).ceil.int
|
maxWi = max(nwX, swX).ceil.int#.clamp(startX, coverages.len + startX)
|
||||||
|
|
||||||
minEi = min(neX, seX).int
|
minEi = min(neX, seX).int#.clamp(startX, coverages.len + startX)
|
||||||
maxEi = max(neX, seX).ceil.int
|
maxEi = max(neX, seX).ceil.int#.clamp(startX, coverages.len + startX)
|
||||||
|
|
||||||
let
|
let
|
||||||
nw = vec2(sweep[i+0].atx, cutLines[currCutLine])
|
nw = vec2(sweep[i+0].atx, cutLines[currCutLine])
|
||||||
|
@ -2388,7 +2433,7 @@ when defined(pixieSweeps):
|
||||||
currCutLine = 0
|
currCutLine = 0
|
||||||
coverages16 = newSeq[uint16](bounds.w.int)
|
coverages16 = newSeq[uint16](bounds.w.int)
|
||||||
coverages8 = newSeq[uint8](bounds.w.int)
|
coverages8 = newSeq[uint8](bounds.w.int)
|
||||||
for scanLine in cutLines[0].int ..< cutLines[^1].ceil.int:
|
for scanLine in max(cutLines[0].int, 0) ..< min(cutLines[^1].ceil.int, image.height):
|
||||||
|
|
||||||
zeroMem(coverages16[0].addr, coverages16.len * 2)
|
zeroMem(coverages16[0].addr, coverages16.len * 2)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue