package dmmo import ( "fmt" ) // A 2d Point/Vector type Vec2 struct { // X-Axis (Left <-> Right) X int64 // Y-Axis (Up <-> Down) Y int64 } // Create a new Vector from 0 or 2+ arguments // // Rules: // // * 0 arguments returns a Vec of (0, 0) // // * 1 arguments returns a Vec of (X, X) // // * 2+ arguments returns a Vec of (X, Y) : Only the first 2 arguments are used func NewVec2(axis ...int64) *Vec2 { if len(axis) == 0 { return &Vec2{0, 0} } else if len(axis) == 1 { return &Vec2{axis[0], axis[0]} } else { return &Vec2{axis[0], axis[1]} } } // Returns a copy of the Vec // // Because almost all Vec directly modify the Vec, Cloning is needed func (v *Vec2) Clone() *Vec2 { if v == nil { return nil } return &Vec2{v.X, v.Y} } // Makes X-Axis and Y-Axis Positive 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 } // Flips the sign for X-Axis and Y-Axis func (v *Vec2) Negate() *Vec2 { if v == nil { return nil } v.X = -v.X v.Y = -v.Y return v } // Assigns 0 to 2+ arguments to Vector // // Rules: // // * 0 arguments will assign Vec to (0, 0) // // * 1 arguments will assign Vec to (X, X) // // * 2+ arguments will assign Vec to (X, Y) : Only the first 2 arguments are used func (v *Vec2) Set(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 } } // Assigns this Vec to another Vec // // No other Vec will assign to (0, 0) func (v *Vec2) SetBy(o *Vec2) *Vec2 { if v == nil { return nil } if o == nil { v.X = 0 v.Y = 0 return v } v.X = o.X v.Y = o.Y return v } // Translates Vec by 0 to 2+ arguments // // Rules: // // * 0 arguments is no operation // // * 1 argument for moving Vec (X, X) // // * 2+ arguments for moving Vec (X, Y) : Only first 2 arguments used func (v *Vec2) Add(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 } } // Translates this Vec by another Vec func (v *Vec2) AddBy(o *Vec2) *Vec2 { if v == nil { return nil } if o == nil { return v } v.X += o.X v.Y += o.Y return v } // Checks Equality of Vec by 0 to 2+ arguments // // Rules: // // * 0 for checking Vec is (0, 0) // // * 1 for checking Vec is (X, X) // // * 2+ for checking Vec is (X, Y) : Only first 2 arguments used func (v *Vec2) Eq(axis ...int64) bool { if v == nil { return len(axis) == 0 } 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] } } // Checks this Vec is equal to another Vec // // When no other Vec provided checks against (0, 0) func (v *Vec2) EqTo(o *Vec2) bool { if v == nil { return o == nil } if o == nil { return v.X == 0 && v.Y == 0 } return v.X == o.X && v.Y == o.Y } // Less Than or Equal To (<=) // // Rules: // // * 0, Vec <= (0, 0) // // * 1, Vec <= (X, X) // // * 2+, Vec <= (X, Y) : Only first 2 arguments used 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] } } // Greater Than or Equal To (>=) // // Rules: // // * 0, Vec >= (0, 0) // // * 1, Vec >= (X, X) // // * 2+, Vec >= (X, Y) : Only first 2 arguments used func (v *Vec2) Great(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] } } // Less Than or Equal to (<=) // // Compares this Vec to another Vec func (v *Vec2) LessThan(o *Vec2) bool { if v == nil { return false } if o == nil { return v.Less() } return v.Less(o.X, o.Y) } // Greater Than or Equal to (>=) // // Compares this Vec to another Vec func (v *Vec2) GreatThan(o *Vec2) bool { if v == nil { return false } if o == nil { return v.Great() } return v.Great(o.X, o.Y) } // Casts a Vec into a single integer // // X + Y func (v *Vec2) Int64() int64 { if v == nil { return 0 } return v.X + v.Y } // Casts a Vec to string // // "(X, Y)" func (v *Vec2) String() string { if v == nil { return "(0, 0)" } return fmt.Sprintf("(%d, %d)", v.X, v.Y) } // Distance from Vec to 0-2+ arguments // // Rules: // // * 0, Vec distance to (0, 0) // // * 1, Vec distance to (X, X) // // * 2+, Vec distance to (X, Y) : Only first 2 arguments used func (v *Vec2) Distance(axis ...int64) *Vec2 { if v == nil { return nil } if len(axis) == 0 { return v.Clone().Abs() } else if len(axis) == 1 { o := v.Clone() o.X -= axis[0] o.Y -= axis[0] return o.Abs() } else { o := v.Clone() o.X -= axis[0] o.Y -= axis[1] return o.Abs() } } // Distance from Vec to another Vec // // When no other Vec provided, Vec distance to (0, 0) func (v *Vec2) DistanceTo(o *Vec2) *Vec2 { if v == nil { return nil } if o == nil { return v.Distance() } return v.Distance(o.X, o.Y) }