mirror of
https://github.com/tengge1/ShadowEditor.git
synced 2025-12-08 19:26:19 +00:00
417 lines
7.0 KiB
Go
417 lines
7.0 KiB
Go
// Copyright 2017-2020 The ShadowEditor Authors. All rights reserved.
|
|
// Use of this source code is governed by a MIT-style
|
|
// license that can be found in the LICENSE file.
|
|
//
|
|
// For more information, please visit: https://github.com/tengge1/ShadowEditor
|
|
// You can also visit: https://gitee.com/tengge1/ShadowEditor
|
|
//
|
|
// This package is translated from three.js, visit `https://github.com/mrdoob/three.js`
|
|
// for more information.
|
|
|
|
package three
|
|
|
|
import (
|
|
"math"
|
|
"math/rand"
|
|
"strconv"
|
|
)
|
|
|
|
// NewVector2 :
|
|
func NewVector2(x, y float64) *Vector2 {
|
|
return &Vector2{x, y, true}
|
|
}
|
|
|
|
// Vector2 :
|
|
type Vector2 struct {
|
|
X float64
|
|
Y float64
|
|
IsVector2 bool
|
|
}
|
|
|
|
// Width :
|
|
func (v Vector2) Width() float64 {
|
|
return v.X
|
|
}
|
|
|
|
// SetWidth :
|
|
func (v Vector2) SetWidth(value float64) {
|
|
v.X = value
|
|
}
|
|
|
|
// Height :
|
|
func (v Vector2) Height() float64 {
|
|
return v.Y
|
|
}
|
|
|
|
// SetHeight :
|
|
func (v Vector2) SetHeight(value float64) {
|
|
v.Y = value
|
|
}
|
|
|
|
// Set :
|
|
func (v Vector2) Set(x, y float64) *Vector2 {
|
|
v.X = x
|
|
v.Y = y
|
|
return &v
|
|
}
|
|
|
|
// SetScalar :
|
|
func (v Vector2) SetScalar(scalar float64) *Vector2 {
|
|
v.X = scalar
|
|
v.Y = scalar
|
|
return &v
|
|
}
|
|
|
|
// SetX :
|
|
func (v Vector2) SetX(x float64) *Vector2 {
|
|
v.X = x
|
|
return &v
|
|
}
|
|
|
|
// SetY :
|
|
func (v Vector2) SetY(y float64) *Vector2 {
|
|
v.Y = y
|
|
return &v
|
|
}
|
|
|
|
// SetComponent :
|
|
func (v Vector2) SetComponent(index int, value float64) *Vector2 {
|
|
switch index {
|
|
default:
|
|
panic("index is out of range: " + strconv.Itoa(index))
|
|
case 0:
|
|
v.X = value
|
|
case 1:
|
|
v.Y = value
|
|
}
|
|
return &v
|
|
}
|
|
|
|
// GetComponent :
|
|
func (v Vector2) GetComponent(index int) float64 {
|
|
switch index {
|
|
default:
|
|
panic("index is out of range: " + strconv.Itoa(index))
|
|
case 0:
|
|
return v.X
|
|
case 1:
|
|
return v.Y
|
|
}
|
|
}
|
|
|
|
// Clone :
|
|
func (v Vector2) Clone() *Vector2 {
|
|
return NewVector2(v.X, v.Y)
|
|
}
|
|
|
|
// Copy :
|
|
func (v Vector2) Copy(w Vector2) *Vector2 {
|
|
v.X = w.X
|
|
v.Y = w.Y
|
|
return &v
|
|
}
|
|
|
|
// Add :
|
|
func (v Vector2) Add(w Vector2) *Vector2 {
|
|
v.X += w.X
|
|
v.Y += w.Y
|
|
return &v
|
|
}
|
|
|
|
// AddScalar :
|
|
func (v Vector2) AddScalar(s float64) *Vector2 {
|
|
v.X += s
|
|
v.Y += s
|
|
return &v
|
|
}
|
|
|
|
// AddVectors :
|
|
func (v Vector2) AddVectors(a, b Vector2) *Vector2 {
|
|
v.X = a.X + b.X
|
|
v.Y = a.Y + b.Y
|
|
return &v
|
|
}
|
|
|
|
// AddScaledVector :
|
|
func (v Vector2) AddScaledVector(w Vector2, s float64) *Vector2 {
|
|
v.X += w.X * s
|
|
v.Y += w.Y * s
|
|
return &v
|
|
}
|
|
|
|
// Sub :
|
|
func (v Vector2) Sub(w Vector2) *Vector2 {
|
|
v.X -= w.X
|
|
v.Y -= w.Y
|
|
return &v
|
|
}
|
|
|
|
// SubScalar :
|
|
func (v Vector2) SubScalar(s float64) *Vector2 {
|
|
v.X -= s
|
|
v.Y -= s
|
|
return &v
|
|
}
|
|
|
|
// SubVectors :
|
|
func (v Vector2) SubVectors(a, b Vector2) *Vector2 {
|
|
v.X = a.X - b.X
|
|
v.Y = a.Y - b.Y
|
|
return &v
|
|
}
|
|
|
|
// Multiply :
|
|
func (v Vector2) Multiply(w Vector2) *Vector2 {
|
|
v.X *= w.X
|
|
v.Y *= w.Y
|
|
return &v
|
|
}
|
|
|
|
// MultiplyScalar :
|
|
func (v Vector2) MultiplyScalar(scalar float64) *Vector2 {
|
|
v.X *= scalar
|
|
v.Y *= scalar
|
|
return &v
|
|
}
|
|
|
|
// Divide :
|
|
func (v Vector2) Divide(w Vector2) *Vector2 {
|
|
v.X /= w.X
|
|
v.Y /= w.Y
|
|
return &v
|
|
}
|
|
|
|
// DivideScalar :
|
|
func (v Vector2) DivideScalar(scalar float64) *Vector2 {
|
|
return v.MultiplyScalar(1 / scalar)
|
|
}
|
|
|
|
// ApplyMatrix3 :
|
|
func (v Vector2) ApplyMatrix3(m Matrix3) *Vector2 {
|
|
x, y := v.X, v.Y
|
|
e := m.Elements
|
|
|
|
v.X = e[0]*x + e[3]*y + e[6]
|
|
v.Y = e[1]*x + e[4]*y + e[7]
|
|
|
|
return &v
|
|
}
|
|
|
|
// Min :
|
|
func (v Vector2) Min(w Vector2) *Vector2 {
|
|
v.X = math.Min(v.X, w.X)
|
|
v.Y = math.Min(v.Y, w.Y)
|
|
|
|
return &v
|
|
}
|
|
|
|
// Max :
|
|
func (v Vector2) Max(w Vector2) *Vector2 {
|
|
v.X = math.Max(v.X, w.X)
|
|
v.Y = math.Max(v.Y, w.Y)
|
|
|
|
return &v
|
|
}
|
|
|
|
// Clamp :
|
|
func (v Vector2) Clamp(min, max Vector2) *Vector2 {
|
|
// assumes min < max, componentwise
|
|
v.X = math.Max(min.X, math.Min(max.X, v.X))
|
|
v.Y = math.Max(min.Y, math.Min(max.Y, v.Y))
|
|
|
|
return &v
|
|
}
|
|
|
|
// ClampScalar :
|
|
func (v Vector2) ClampScalar(minVal, maxVal float64) *Vector2 {
|
|
v.X = math.Max(minVal, math.Min(maxVal, v.X))
|
|
v.Y = math.Max(minVal, math.Min(maxVal, v.Y))
|
|
|
|
return &v
|
|
}
|
|
|
|
// ClampLength :
|
|
func (v Vector2) ClampLength(min, max float64) *Vector2 {
|
|
length := v.Length()
|
|
if length == 0 {
|
|
length = 1
|
|
}
|
|
|
|
return v.DivideScalar(length).MultiplyScalar(math.Max(min, math.Min(max, length)))
|
|
}
|
|
|
|
// Floor :
|
|
func (v Vector2) Floor() *Vector2 {
|
|
v.X = math.Floor(v.X)
|
|
v.Y = math.Floor(v.Y)
|
|
|
|
return &v
|
|
}
|
|
|
|
// Ceil :
|
|
func (v Vector2) Ceil() *Vector2 {
|
|
v.X = math.Ceil(v.X)
|
|
v.Y = math.Ceil(v.Y)
|
|
|
|
return &v
|
|
}
|
|
|
|
// Round :
|
|
func (v Vector2) Round() *Vector2 {
|
|
v.X = math.Round(v.X)
|
|
v.Y = math.Round(v.Y)
|
|
|
|
return &v
|
|
}
|
|
|
|
// RoundToZero :
|
|
func (v Vector2) RoundToZero() *Vector2 {
|
|
if v.X < 0 {
|
|
v.X = math.Ceil(v.X)
|
|
} else {
|
|
v.X = math.Floor(v.X)
|
|
}
|
|
|
|
if v.Y < 0 {
|
|
v.Y = math.Ceil(v.X)
|
|
} else {
|
|
v.Y = math.Floor(v.X)
|
|
}
|
|
|
|
return &v
|
|
}
|
|
|
|
// Negate :
|
|
func (v Vector2) Negate() *Vector2 {
|
|
v.X = -v.X
|
|
v.Y = -v.Y
|
|
|
|
return &v
|
|
}
|
|
|
|
// Dot :
|
|
func (v Vector2) Dot(w Vector2) float64 {
|
|
return v.X*w.X + v.Y*w.Y
|
|
}
|
|
|
|
// Cross :
|
|
func (v Vector2) Cross(w Vector2) float64 {
|
|
return v.X*w.Y - v.Y*w.X
|
|
}
|
|
|
|
// LengthSq :
|
|
func (v Vector2) LengthSq() float64 {
|
|
return v.X*v.X + v.Y*v.Y
|
|
}
|
|
|
|
// Length :
|
|
func (v Vector2) Length() float64 {
|
|
return math.Sqrt(v.X*v.X + v.Y*v.Y)
|
|
}
|
|
|
|
// ManhattanLength :
|
|
func (v Vector2) ManhattanLength() float64 {
|
|
return math.Abs(v.X) + math.Abs(v.Y)
|
|
}
|
|
|
|
// Normalize :
|
|
func (v Vector2) Normalize() *Vector2 {
|
|
length := v.Length()
|
|
if length == 0 {
|
|
length = 1
|
|
}
|
|
return v.DivideScalar(length)
|
|
}
|
|
|
|
// Angle :
|
|
func (v Vector2) Angle() float64 {
|
|
// computes the angle in radians with respect to the positive x-axis
|
|
var angle = math.Atan2(-v.Y, -v.X) + math.Pi
|
|
|
|
return angle
|
|
}
|
|
|
|
// DistanceTo :
|
|
func (v Vector2) DistanceTo(w Vector2) float64 {
|
|
return math.Sqrt(v.DistanceToSquared(w))
|
|
}
|
|
|
|
// DistanceToSquared :
|
|
func (v Vector2) DistanceToSquared(w Vector2) float64 {
|
|
dx, dy := v.X-w.X, v.Y-w.Y
|
|
return dx*dx + dy*dy
|
|
}
|
|
|
|
// ManhattanDistanceTo :
|
|
func (v Vector2) ManhattanDistanceTo(w Vector2) float64 {
|
|
return math.Abs(v.X-w.X) + math.Abs(v.Y-w.Y)
|
|
}
|
|
|
|
// SetLength :
|
|
func (v Vector2) SetLength(length float64) *Vector2 {
|
|
return v.Normalize().MultiplyScalar(length)
|
|
}
|
|
|
|
// Lerp :
|
|
func (v Vector2) Lerp(w Vector2, alpha float64) *Vector2 {
|
|
v.X += (w.X - v.X) * alpha
|
|
v.Y += (w.Y - v.Y) * alpha
|
|
|
|
return &v
|
|
}
|
|
|
|
// LerpVectors :
|
|
func (v Vector2) LerpVectors(v1, v2 Vector2, alpha float64) *Vector2 {
|
|
v.X = v1.X + (v2.X-v1.X)*alpha
|
|
v.Y = v1.Y + (v2.Y-v1.Y)*alpha
|
|
|
|
return &v
|
|
}
|
|
|
|
// Equals :
|
|
func (v Vector2) Equals(w Vector2) bool {
|
|
return ((w.X == v.X) && (w.Y == v.Y))
|
|
}
|
|
|
|
// FromArray :
|
|
func (v Vector2) FromArray(array []float64, offset int) *Vector2 {
|
|
if len(array) < offset+2 {
|
|
panic("array length should be greater than offset+2")
|
|
}
|
|
v.X = array[offset]
|
|
v.Y = array[offset+1]
|
|
|
|
return &v
|
|
}
|
|
|
|
// ToArray :
|
|
func (v Vector2) ToArray(array []float64, offset int) []float64 {
|
|
if len(array) < offset+2 {
|
|
panic("array length should be greater than offset+2")
|
|
}
|
|
array[offset] = v.X
|
|
array[offset+1] = v.Y
|
|
return array
|
|
}
|
|
|
|
// RotateAround :
|
|
func (v Vector2) RotateAround(center Vector2, angle float64) *Vector2 {
|
|
c, s := math.Cos(angle), math.Sin(angle)
|
|
|
|
var x = v.X - center.X
|
|
var y = v.Y - center.Y
|
|
|
|
v.X = x*c - y*s + center.X
|
|
v.Y = x*s + y*c + center.Y
|
|
|
|
return &v
|
|
}
|
|
|
|
// Random :
|
|
func (v Vector2) Random() *Vector2 {
|
|
v.X = rand.Float64()
|
|
v.Y = rand.Float64()
|
|
|
|
return &v
|
|
}
|