73 lines
2.1 KiB
Go
73 lines
2.1 KiB
Go
package gozxing
|
|
|
|
import (
|
|
"github.com/makiuchi-d/gozxing/common/util"
|
|
)
|
|
|
|
type ResultPoint interface {
|
|
GetX() float64
|
|
GetY() float64
|
|
}
|
|
|
|
type ResultPointBase struct {
|
|
x float64
|
|
y float64
|
|
}
|
|
|
|
func NewResultPoint(x, y float64) ResultPoint {
|
|
return ResultPointBase{x, y}
|
|
}
|
|
|
|
func (rp ResultPointBase) GetX() float64 {
|
|
return rp.x
|
|
}
|
|
|
|
func (rp ResultPointBase) GetY() float64 {
|
|
return rp.y
|
|
}
|
|
|
|
// Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC
|
|
// and BC is less than AC, and the angle between BC and BA is less than 180 degrees.
|
|
// @param patterns array of three {@code ResultPoint} to order
|
|
func ResultPoint_OrderBestPatterns(pattern0, pattern1, pattern2 ResultPoint) (pointA, pointB, pointC ResultPoint) {
|
|
// Find distances between pattern centers
|
|
zeroOneDistance := ResultPoint_Distance(pattern0, pattern1)
|
|
oneTwoDistance := ResultPoint_Distance(pattern1, pattern2)
|
|
zeroTwoDistance := ResultPoint_Distance(pattern0, pattern2)
|
|
|
|
// Assume one closest to other two is B; A and C will just be guesses at first
|
|
if oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance {
|
|
pointB = pattern0
|
|
pointA = pattern1
|
|
pointC = pattern2
|
|
} else if zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance {
|
|
pointB = pattern1
|
|
pointA = pattern0
|
|
pointC = pattern2
|
|
} else {
|
|
pointB = pattern2
|
|
pointA = pattern0
|
|
pointC = pattern1
|
|
}
|
|
|
|
// Use cross product to figure out whether A and C are correct or flipped.
|
|
// This asks whether BC x BA has a positive z component, which is the arrangement
|
|
// we want for A, B, C. If it's negative, then we've got it flipped around and
|
|
// should swap A and C.
|
|
if crossProductZ(pointA, pointB, pointC) < 0.0 {
|
|
pointA, pointC = pointC, pointA
|
|
}
|
|
|
|
return pointA, pointB, pointC
|
|
}
|
|
|
|
func ResultPoint_Distance(pattern1, pattern2 ResultPoint) float64 {
|
|
return util.MathUtils_DistanceFloat(pattern1.GetX(), pattern1.GetY(), pattern2.GetX(), pattern2.GetY())
|
|
}
|
|
|
|
func crossProductZ(pointA, pointB, pointC ResultPoint) float64 {
|
|
bX := pointB.GetX()
|
|
bY := pointB.GetY()
|
|
return ((pointC.GetX() - bX) * (pointA.GetY() - bY)) - ((pointC.GetY() - bY) * (pointA.GetX() - bX))
|
|
}
|