fckeuspy-go/vendor/github.com/makiuchi-d/gozxing/common/perspective_transform.go
2025-09-28 21:03:39 +02:00

96 lines
3.0 KiB
Go

package common
type PerspectiveTransform struct {
a11, a21, a31 float64
a12, a22, a32 float64
a13, a23, a33 float64
}
func PerspectiveTransform_QuadrilateralToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3,
x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p float64) *PerspectiveTransform {
qToS := PerspectiveTransform_QuadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3)
sToQ := PerspectiveTransform_SquareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p)
return sToQ.times(qToS)
}
func (p *PerspectiveTransform) TransformPoints(points []float64) {
maxI := len(points) - 1 // points.length must be even
for i := 0; i < maxI; i += 2 {
x := points[i]
y := points[i+1]
denominator := p.a13*x + p.a23*y + p.a33
points[i] = (p.a11*x + p.a21*y + p.a31) / denominator
points[i+1] = (p.a12*x + p.a22*y + p.a32) / denominator
}
}
func (p *PerspectiveTransform) TransformPointsXY(xValues, yValues []float64) {
n := len(xValues)
for i := 0; i < n; i++ {
x := xValues[i]
y := yValues[i]
denominator := p.a13*x + p.a23*y + p.a33
xValues[i] = (p.a11*x + p.a21*y + p.a31) / denominator
yValues[i] = (p.a12*x + p.a22*y + p.a32) / denominator
}
}
func PerspectiveTransform_SquareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3 float64) *PerspectiveTransform {
dx3 := x0 - x1 + x2 - x3
dy3 := y0 - y1 + y2 - y3
if dx3 == 0.0 && dy3 == 0.0 {
// Affine
return &PerspectiveTransform{
x1 - x0, x2 - x1, x0,
y1 - y0, y2 - y1, y0,
0.0, 0.0, 1.0}
} else {
dx1 := x1 - x2
dx2 := x3 - x2
dy1 := y1 - y2
dy2 := y3 - y2
denominator := dx1*dy2 - dx2*dy1
a13 := (dx3*dy2 - dx2*dy3) / denominator
a23 := (dx1*dy3 - dx3*dy1) / denominator
return &PerspectiveTransform{
x1 - x0 + a13*x1, x3 - x0 + a23*x3, x0,
y1 - y0 + a13*y1, y3 - y0 + a23*y3, y0,
a13, a23, 1.0}
}
}
func PerspectiveTransform_QuadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3 float64) *PerspectiveTransform {
// Here, the adjoint serves as the inverse:
return PerspectiveTransform_SquareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint()
}
func (p *PerspectiveTransform) buildAdjoint() *PerspectiveTransform {
// Adjoint is the transpose of the cofactor matrix:
return &PerspectiveTransform{
p.a22*p.a33 - p.a23*p.a32,
p.a23*p.a31 - p.a21*p.a33,
p.a21*p.a32 - p.a22*p.a31,
p.a13*p.a32 - p.a12*p.a33,
p.a11*p.a33 - p.a13*p.a31,
p.a12*p.a31 - p.a11*p.a32,
p.a12*p.a23 - p.a13*p.a22,
p.a13*p.a21 - p.a11*p.a23,
p.a11*p.a22 - p.a12*p.a21,
}
}
func (p *PerspectiveTransform) times(other *PerspectiveTransform) *PerspectiveTransform {
return &PerspectiveTransform{
p.a11*other.a11 + p.a21*other.a12 + p.a31*other.a13,
p.a11*other.a21 + p.a21*other.a22 + p.a31*other.a23,
p.a11*other.a31 + p.a21*other.a32 + p.a31*other.a33,
p.a12*other.a11 + p.a22*other.a12 + p.a32*other.a13,
p.a12*other.a21 + p.a22*other.a22 + p.a32*other.a23,
p.a12*other.a31 + p.a22*other.a32 + p.a32*other.a33,
p.a13*other.a11 + p.a23*other.a12 + p.a33*other.a13,
p.a13*other.a21 + p.a23*other.a22 + p.a33*other.a23,
p.a13*other.a31 + p.a23*other.a32 + p.a33*other.a33,
}
}