mirror of
https://github.com/jehiah/TrafficSpeed.git
synced 2025-10-07 01:03:15 +08:00
115 lines
2.2 KiB
Go
115 lines
2.2 KiB
Go
package project
|
|
|
|
import (
|
|
"fmt"
|
|
"image"
|
|
"log"
|
|
"math"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type BBox struct {
|
|
A Point `json:"a"`
|
|
B Point `json:"b"`
|
|
}
|
|
|
|
func ParseBBox(s string) (b *BBox) {
|
|
s = strings.TrimSpace(s)
|
|
if !strings.Contains(s, "x") || !strings.Contains(s, " ") {
|
|
return nil
|
|
}
|
|
b = &BBox{}
|
|
c := strings.SplitN(s, " ", 2)
|
|
p1 := ParsePoint(c[0])
|
|
p2 := ParsePoint(c[1])
|
|
// for a bounding box, always top left and bottom right
|
|
b.A.X = math.Min(p1.X, p2.X)
|
|
b.A.Y = math.Min(p1.Y, p2.Y)
|
|
b.B.X = math.Max(p1.X, p2.X)
|
|
b.B.Y = math.Max(p1.Y, p2.Y)
|
|
return
|
|
}
|
|
|
|
func (b *BBox) IsZero() bool {
|
|
if b.A.X == 0 && b.A.Y == 0 && b.B.X == 0 && b.B.Y == 0 {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (b *BBox) String() string {
|
|
if b == nil {
|
|
return ""
|
|
}
|
|
return fmt.Sprintf("%s %s", b.A, b.B)
|
|
}
|
|
func (b BBox) Height() float64 {
|
|
return b.B.Y - b.A.Y
|
|
}
|
|
func (b BBox) Width() float64 {
|
|
return b.B.X - b.A.X
|
|
}
|
|
func (b BBox) Dy() int {
|
|
return int(b.Height())
|
|
}
|
|
func (b BBox) Dx() int {
|
|
return int(b.Width())
|
|
}
|
|
func (b BBox) Rect() image.Rectangle {
|
|
return image.Rect(
|
|
int(b.A.X),
|
|
int(b.A.Y),
|
|
int(b.B.X),
|
|
int(b.B.Y),
|
|
)
|
|
}
|
|
|
|
type Point struct {
|
|
X float64 `json:"x"`
|
|
Y float64 `json:"y"`
|
|
}
|
|
|
|
func (p Point) String() string {
|
|
return fmt.Sprintf("%dx%d", int64(p.X), int64(p.Y))
|
|
}
|
|
|
|
func ParsePoint(s string) (p Point) {
|
|
s = strings.TrimSpace(s)
|
|
if !strings.Contains(s, "x") {
|
|
return
|
|
}
|
|
c := strings.SplitN(s, "x", 2)
|
|
x, _ := strconv.Atoi(c[0])
|
|
y, _ := strconv.Atoi(c[1])
|
|
return Point{float64(x), float64(y)}
|
|
}
|
|
|
|
const SkipRotate = 0.00001
|
|
|
|
func RadiansToDegrees(rad float64) (deg float64) {
|
|
deg = rad * 180.0 / math.Pi
|
|
return
|
|
}
|
|
|
|
const rightAngelRadians = 1.570796 // 90 degrees
|
|
|
|
func Radians(a, b Point) float64 {
|
|
if a.Y == b.Y {
|
|
return SkipRotate
|
|
}
|
|
|
|
adjacent := math.Max(a.X, b.X) - math.Min(a.X, b.X)
|
|
opposite := math.Max(a.Y, b.Y) - math.Min(a.Y, b.Y)
|
|
radians := math.Atan(adjacent / opposite)
|
|
log.Printf("adjacent: %v opposite %v radians %v", adjacent, opposite, radians)
|
|
if a.Y > b.Y {
|
|
adjusted := (-1 * radians) + rightAngelRadians
|
|
log.Printf("adjusting to %v because %v < %v", adjusted, a, b)
|
|
return adjusted
|
|
}
|
|
adjusted := radians - rightAngelRadians
|
|
log.Printf("adjusting to %v because %v > %v", adjusted, a, b)
|
|
return adjusted
|
|
}
|