123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- /* Copyright (c) 2010 Beoran
- * Copyright (c) 2007 Scott Lembcke
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
- package tamias
- import "fmt"
- // import "math"
- // type Float float;
- type Vect struct {
- X Float
- Y Float
- }
- var VZERO=Vect{0.0,0.0};
- func V(x Float, y Float) (Vect) {
- result := Vect{X:x, Y:y}
- return result
- }
- func VF(x float, y float) (Vect) {
- return V(Float(x), Float(y))
- }
- func (v1 Vect) Equals(o interface {}) (bool) {
- v2, ok := o.(Vect)
- if !ok { return false; }
- return (v1.X == v2.X) && (v1.Y == v2.Y)
- }
- // non-inlined functions
- /*
- cpFloat cpvlength(const cpVect v);
- cpVect cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t);
- cpVect cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a);
- cpVect cpvforangle(const cpFloat a); // convert radians to a normalized vector
- cpFloat cpvtoangle(const cpVect v); // convert a vector to radians
- char *cpvstr(const cpVect v); // get a string representation of a vector
- */
- func (v1 Vect) Add(v2 Vect) (Vect) {
- return V(v1.X + v2.X, v1.Y + v2.Y)
- }
- func (v Vect) Neg() (Vect) {
- return V(-v.X, -v.Y)
- }
- func (v1 Vect) Sub(v2 Vect) (Vect) {
- return V(v1.X - v2.X, v1.Y - v2.Y)
- }
- func (v1 Vect) Mult(s Float) (Vect) {
- return V(v1.X * s, v1.Y * s)
- }
- func (v1 Vect) Dot(v2 Vect) (Float) {
- return v1.X * v2.X + v1.Y * v2.Y
- }
- func (v1 Vect) Cross(v2 Vect) (Float) {
- return v1.X * v2.Y - v1.Y * v2.X
- }
- func (v Vect) Perp() (Vect) {
- return V(-v.Y, v.X)
- }
- func (v Vect) Rperp() (Vect) {
- return V(v.Y, -v.X)
- }
- func (v1 Vect) Project(v2 Vect) (Vect) {
- return v2.Mult(v1.Dot(v2) / v2.Dot(v2))
- }
- func (v1 Vect) Rotate(v2 Vect) (Vect) {
- return V(v1.X*v2.X - v1.Y*v2.Y, v1.X*v2.Y + v1.Y*v2.X)
- }
- func (v1 Vect) Unrotate(v2 Vect) (Vect) {
- return V(v1.X*v2.X + v1.Y*v2.Y, v1.Y*v2.X - v1.X*v2.Y)
- }
- func (v Vect) Lengthsq() (Float) {
- return v.Dot(v)
- }
- func (v Vect) Length() (Float) {
- return v.Lengthsq().Sqrt()
- }
- func (v1 Vect) Lerp(v2 Vect, t Float) (Vect) {
- aid1 := v1.Mult(1.0 - t)
- aid2 := v2.Mult(t)
- return aid1.Add(aid2)
- }
- func (v Vect) Normalize() (Vect) {
- return v.Mult(1.0 / v.Length())
- }
- func (v Vect) NormalizeSafe() (Vect) {
- if v.X == 0.0 && v.Y == 0.0 {
- return VZERO
- }
- return v.Normalize()
- }
- func (v Vect) Clamp(len Float) (Vect) {
- if v.Lengthsq() > (len * len) {
- return v.Normalize().Mult(len)
- }
- return v
- }
- func (v1 Vect) Lerpconst(v2 Vect, d Float) (Vect) {
- return v1.Add(v2.Sub(v1).Clamp(d));
- }
- func (v1 Vect) Dist(v2 Vect) (Float) {
- return v1.Sub(v2).Length()
- }
- func (v1 Vect) Distsq(v2 Vect) (Float) {
- return v1.Sub(v2).Lengthsq()
- }
- func (v1 Vect) Near(v2 Vect, dist Float) (bool) {
- return v1.Distsq(v2) < dist*dist
- }
- func (v1 Vect) Slerp(v2 Vect, t Float) (Vect) {
- omega := v1.Dot(v2).Acos();
- if(omega != 0.0){
- denom := 1.0 / omega.Sin();
- par1 := ((1.0 - t)*omega).Sin() *denom
- par2 := ((t)*omega).Sin() *denom
- aid1 := v1.Mult(par1)
- aid2 := v2.Mult(par2)
- return aid1.Add(aid2)
- }
- // else
- return v1;
- }
- func (v1 Vect) Slerpconst(v2 Vect, a Float) (Vect) {
- angle := v1.Dot(v2).Acos()
- return v1.Slerp(v2, a.Min(angle) / angle)
- }
- func ForAngle(a Float) (Vect) {
- return V(a.Cos(), a.Sin());
- }
- func (v Vect) ToAngle() (Float) {
- return v.Y.Atan2(v.X)
- }
- func (v Vect) String() (string) {
- return fmt.Sprintf("(%.3f, %.3f)", v.X, v.Y)
- }
|