Browse Source

Significantly improved speed, accuracy, and precision of line tracing

master
Patrick Gaskin 2 years ago
parent
commit
69c41a82d2
Signed by: geek1011 GPG Key ID: A2FD79F68A2AB707
  1. 40
      graph/graph.go

40
graph/graph.go

@ -83,22 +83,37 @@ func Parse(img image.Image, maxPrice, minPrice float64, startDate, endDate time.
// traceLine traces the grid line.
func traceLine(img image.Image, graphBounds image.Rectangle, line colorMatcherFunc, cb func(x, y int, isDotted bool)) error {
curDotted := false
lastY := graphBounds.Min.Y
for x := graphBounds.Min.X; x < graphBounds.Max.X; x++ {
// find the topmost Y for the line color, going outwards from the last Y
// for performance and error tolerance
curY := -1
for y := graphBounds.Min.Y; y < graphBounds.Max.Y; y++ {
onLine := line(img.At(x, y))
if x > 2 && x < graphBounds.Max.X-2 {
if line(img.At(x-2, y)) && line(img.At(x+2, y)) {
if onLine {
curDotted = false
} else {
onLine = true
curDotted = true
}
if lastY < graphBounds.Min.Y || lastY > graphBounds.Max.Y {
panic("lastY is out of bounds")
}
for dyMaxNeg, dyMaxPos, dy := lastY-graphBounds.Min.Y, graphBounds.Max.Y-lastY, 0; dy < dyMaxPos || dy < dyMaxNeg; dy++ {
checkY := func(cond bool, y int) (found bool) {
if !cond {
return
}
onLeft, onCur, onRight := line(img.At(x-2, y)), line(img.At(x, y)), line(img.At(x+2, y))
if onLeft && onRight && onCur {
curDotted = false
curY = y
} else if onLeft && onRight && !onCur {
curDotted = true
curY = y
} else if onCur {
curY = y
} else {
return false
}
if line(img.At(x, curY-1)) && !line(img.At(x, curY-2)) {
curY-- // always use top of current line (2px thick)
}
return true
}
if onLine {
curY = y
if checkY(dy < dyMaxNeg, lastY-dy) || checkY(dy < dyMaxPos, lastY+dy) {
break
}
}
@ -108,6 +123,7 @@ func traceLine(img image.Image, graphBounds image.Rectangle, line colorMatcherFu
}
break
}
lastY = curY
cb(x, curY, curDotted)
}
return nil