|
@@ -0,0 +1,260 @@
|
|
|
+package main
|
|
|
+
|
|
|
+import (
|
|
|
+ "fmt"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
+)
|
|
|
+
|
|
|
+type Vec2 struct {
|
|
|
+ X int64
|
|
|
+ Y int64
|
|
|
+}
|
|
|
+
|
|
|
+func NewVec2(axis ...int64) *Vec2 {
|
|
|
+ if len(axis) == 0 {
|
|
|
+ return &Vec2{}
|
|
|
+ } else if len(axis) == 1 {
|
|
|
+ return &Vec2{axis[0], axis[0]}
|
|
|
+ } else {
|
|
|
+ return &Vec2{axis[0], axis[1]}
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) Clone() *Vec2 {
|
|
|
+ if v == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ return &Vec2{v.X, v.Y}
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) Translate(axis ...int64) *Vec2 {
|
|
|
+ if v == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ if len(axis) == 0 {
|
|
|
+ return v
|
|
|
+ } else if len(axis) == 1 {
|
|
|
+ v.X += axis[0]
|
|
|
+ v.Y += axis[0]
|
|
|
+ return v
|
|
|
+ } else {
|
|
|
+ v.X += axis[0]
|
|
|
+ v.Y += axis[1]
|
|
|
+ return v
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) TranslateBy(o *Vec2) *Vec2 {
|
|
|
+ if v == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ if o == nil {
|
|
|
+ return v
|
|
|
+ }
|
|
|
+ v.X += o.X
|
|
|
+ v.Y += o.Y
|
|
|
+ return v
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) Assign(axis ...int64) *Vec2 {
|
|
|
+ if v == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ if len(axis) == 0 {
|
|
|
+ v.X = 0
|
|
|
+ v.Y = 0
|
|
|
+ return v
|
|
|
+ } else if len(axis) == 1 {
|
|
|
+ v.X = axis[0]
|
|
|
+ v.Y = axis[0]
|
|
|
+ return v
|
|
|
+ } else {
|
|
|
+ v.X = axis[0]
|
|
|
+ v.Y = axis[1]
|
|
|
+ return v
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) AssignTo(o *Vec2) *Vec2 {
|
|
|
+ if v == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ if o == nil {
|
|
|
+ return v
|
|
|
+ }
|
|
|
+ v.X = o.X
|
|
|
+ v.Y = o.Y
|
|
|
+ return v
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) Equal(axis ...int64) bool {
|
|
|
+ if v == nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ if len(axis) == 0 {
|
|
|
+ return v.X == 0 && v.Y == 0
|
|
|
+ } else if len(axis) == 1 {
|
|
|
+ return v.X == axis[0] && v.Y == axis[0]
|
|
|
+ } else {
|
|
|
+ return v.X == axis[0] && v.Y == axis[1]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) EqualTo(o *Vec2) bool {
|
|
|
+ if v == nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ if o == nil {
|
|
|
+ return v.X == 0 && v.Y == 0
|
|
|
+ }
|
|
|
+ return v.X == o.X && v.Y == o.Y
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) Less(axis ...int64) bool {
|
|
|
+ if v == nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ if len(axis) == 0 {
|
|
|
+ return v.X <= 0 && v.Y <= 0
|
|
|
+ } else if len(axis) == 1 {
|
|
|
+ return v.X <= axis[0] && v.Y == axis[0]
|
|
|
+ } else {
|
|
|
+ return v.X <= axis[0] && v.Y == axis[1]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) LessThan(o *Vec2) bool {
|
|
|
+ if v == nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ if o == nil {
|
|
|
+ return v.Less()
|
|
|
+ }
|
|
|
+ return v.X <= o.X && v.Y <= o.Y
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) Greater(axis ...int64) bool {
|
|
|
+ if v == nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ if len(axis) == 0 {
|
|
|
+ return v.X >= 0 && v.Y >= 0
|
|
|
+ } else if len(axis) == 1 {
|
|
|
+ return v.X >= axis[0] && v.Y >= axis[0]
|
|
|
+ } else {
|
|
|
+ return v.X >= axis[0] && v.Y >= axis[1]
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) GreaterThan(o *Vec2) bool {
|
|
|
+ if v == nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ if o == nil {
|
|
|
+ return v.Greater()
|
|
|
+ }
|
|
|
+ return v.X >= o.X && v.Y >= o.Y
|
|
|
+}
|
|
|
+
|
|
|
+func SortVec2(v1, v2 *Vec2) (*Vec2, *Vec2) {
|
|
|
+ if v1.GreaterThan(v2) {
|
|
|
+ return v2, v1
|
|
|
+ }
|
|
|
+ return v1, v2
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) Distance(axis ...int64) int64 {
|
|
|
+ if v == nil {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ if len(axis) == 0 {
|
|
|
+ return v.X + v.Y
|
|
|
+ } else if len(axis) == 1 {
|
|
|
+ x := v.X - axis[0]
|
|
|
+ y := v.Y - axis[0]
|
|
|
+ if x < 0 {
|
|
|
+ x = -x
|
|
|
+ }
|
|
|
+ if y < 0 {
|
|
|
+ y = -y
|
|
|
+ }
|
|
|
+ return x + y
|
|
|
+ } else {
|
|
|
+ x := v.X - axis[0]
|
|
|
+ y := v.Y - axis[1]
|
|
|
+ if x < 0 {
|
|
|
+ x = -x
|
|
|
+ }
|
|
|
+ if y < 0 {
|
|
|
+ y = -y
|
|
|
+ }
|
|
|
+ return x + y
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) DistanceTo(o *Vec2) int64 {
|
|
|
+ if v == nil {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ if o == nil {
|
|
|
+ return v.Distance()
|
|
|
+ }
|
|
|
+ x := v.X - o.X
|
|
|
+ y := v.Y - o.Y
|
|
|
+ if x < 0 {
|
|
|
+ x = -x
|
|
|
+ }
|
|
|
+ if y < 0 {
|
|
|
+ y = -y
|
|
|
+ }
|
|
|
+ return x + y
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) Abs() *Vec2 {
|
|
|
+ if v == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ if v.X < 0 {
|
|
|
+ v.X = -v.X
|
|
|
+ }
|
|
|
+ if v.Y < 0 {
|
|
|
+ v.Y = -v.Y
|
|
|
+ }
|
|
|
+ return v
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) Negate() *Vec2 {
|
|
|
+ if v == nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ v.X = -v.X
|
|
|
+ v.Y = -v.Y
|
|
|
+ return v
|
|
|
+}
|
|
|
+
|
|
|
+func (v *Vec2) String() string {
|
|
|
+ if v == nil {
|
|
|
+ return "nil"
|
|
|
+ }
|
|
|
+ return fmt.Sprintf("(%d, %d)", v.X, v.Y)
|
|
|
+}
|
|
|
+
|
|
|
+func Vec2FromString(s string) (*Vec2, string) {
|
|
|
+ if !strings.ContainsAny(s, "(),") {
|
|
|
+ return nil, "missing '(),' characters"
|
|
|
+ }
|
|
|
+ work := strings.Split(strings.ReplaceAll(strings.ReplaceAll(s, ")", ""), "(", ""), ", ")
|
|
|
+ if len(work) != 2 {
|
|
|
+ return nil, fmt.Sprintf("missing parts, got %d, need 2", len(work))
|
|
|
+ }
|
|
|
+ x, err := strconv.ParseInt(work[0], 10, 64)
|
|
|
+ if err != nil {
|
|
|
+ return nil, fmt.Sprintf("failed parsing x axis, %v", err)
|
|
|
+ }
|
|
|
+ y, err := strconv.ParseInt(work[1], 10, 64)
|
|
|
+ if err != nil {
|
|
|
+ return nil, fmt.Sprintf("failed parsing y axis, %v", err)
|
|
|
+ }
|
|
|
+ return NewVec2(x, y), ""
|
|
|
+}
|