mirror of
https://github.com/tengge1/ShadowEditor.git
synced 2025-12-08 19:26:19 +00:00
142 lines
3.1 KiB
Go
142 lines
3.1 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"
|
|
|
|
// NewSphere :
|
|
func NewSphere(center Vector3, radius float64) *Sphere {
|
|
return &Sphere{center, radius}
|
|
}
|
|
|
|
// Sphere :
|
|
type Sphere struct {
|
|
Center Vector3
|
|
Radius float64
|
|
}
|
|
|
|
// Set :
|
|
func (s Sphere) Set(center Vector3, radius float64) *Sphere {
|
|
s.Center.Copy(center)
|
|
s.Radius = radius
|
|
return &s
|
|
}
|
|
|
|
// SetFromPoints :
|
|
func (s Sphere) SetFromPoints(points []Vector3, optionalCenter Vector3) *Sphere {
|
|
center := s.Center
|
|
center.Copy(optionalCenter)
|
|
|
|
maxRadiusSq := float64(0)
|
|
|
|
for i, il := 0, len(points); i < il; i++ {
|
|
maxRadiusSq = math.Max(maxRadiusSq, center.DistanceToSquared(points[i]))
|
|
}
|
|
|
|
s.Radius = math.Sqrt(maxRadiusSq)
|
|
return &s
|
|
}
|
|
|
|
// Clone :
|
|
func (s Sphere) Clone() *Sphere {
|
|
return NewSphere(s.Center, s.Radius).Copy(s)
|
|
}
|
|
|
|
// Copy :
|
|
func (s Sphere) Copy(sphere Sphere) *Sphere {
|
|
s.Center.Copy(sphere.Center)
|
|
s.Radius = sphere.Radius
|
|
return &s
|
|
}
|
|
|
|
// IsEmpty :
|
|
func (s Sphere) IsEmpty() bool {
|
|
return s.Radius < 0
|
|
}
|
|
|
|
// MakeEmpty :
|
|
func (s Sphere) MakeEmpty() *Sphere {
|
|
s.Center.Set(0, 0, 0)
|
|
s.Radius = -1
|
|
return &s
|
|
}
|
|
|
|
// ContainsPoint :
|
|
func (s Sphere) ContainsPoint(point Vector3) bool {
|
|
return point.DistanceToSquared(s.Center) <= s.Radius*s.Radius
|
|
}
|
|
|
|
// DistanceToPoint :
|
|
func (s Sphere) DistanceToPoint(point Vector3) float64 {
|
|
return point.DistanceTo(s.Center) - s.Radius
|
|
}
|
|
|
|
// IntersectsSphere :
|
|
func (s Sphere) IntersectsSphere(sphere Sphere) bool {
|
|
radiusSum := s.Radius + sphere.Radius
|
|
return sphere.Center.DistanceToSquared(s.Center) <= radiusSum*radiusSum
|
|
}
|
|
|
|
// IntersectsBox :
|
|
func (s Sphere) IntersectsBox(box Box3) bool {
|
|
return box.IntersectsSphere(s)
|
|
}
|
|
|
|
// IntersectsPlane :
|
|
func (s Sphere) IntersectsPlane(plane Plane) bool {
|
|
return math.Abs(plane.DistanceToPoint(s.Center)) <= s.Radius
|
|
}
|
|
|
|
// ClampPoint :
|
|
func (s Sphere) ClampPoint(point, target Vector3) *Vector3 {
|
|
deltaLengthSq := s.Center.DistanceToSquared(point)
|
|
target.Copy(point)
|
|
|
|
if deltaLengthSq > s.Radius*s.Radius {
|
|
target.Sub(s.Center).Normalize()
|
|
target.MultiplyScalar(s.Radius).Add(s.Center)
|
|
}
|
|
|
|
return &target
|
|
}
|
|
|
|
// GetBoundingBox :
|
|
func (s Sphere) GetBoundingBox(target Box3) *Box3 {
|
|
if s.IsEmpty() {
|
|
// Empty sphere produces empty bounding box
|
|
target.MakeEmpty()
|
|
return &target
|
|
}
|
|
|
|
target.Set(s.Center, s.Center)
|
|
target.ExpandByScalar(s.Radius)
|
|
|
|
return &target
|
|
}
|
|
|
|
// ApplyMatrix4 :
|
|
func (s Sphere) ApplyMatrix4(matrix Matrix4) *Sphere {
|
|
s.Center.ApplyMatrix4(matrix)
|
|
s.Radius = s.Radius * matrix.GetMaxScaleOnAxis()
|
|
return &s
|
|
}
|
|
|
|
// Translate :
|
|
func (s Sphere) Translate(offset Vector3) *Sphere {
|
|
s.Center.Add(offset)
|
|
return &s
|
|
}
|
|
|
|
// Equals :
|
|
func (s Sphere) Equals(sphere Sphere) bool {
|
|
return sphere.Center.Equals(s.Center) && sphere.Radius == s.Radius
|
|
}
|