using System;
using UnityEngine;
namespace ProceduralToolkit
{
///
/// Representation of a sphere
///
[Serializable]
public struct Sphere : IEquatable, IFormattable
{
public Vector3 center;
public float radius;
///
/// Returns the area of the sphere
///
public float area => 4*Mathf.PI*radius*radius;
///
/// Returns the volume of the sphere
///
public float volume => 4f/3f*Mathf.PI*radius*radius*radius;
public static Sphere unit => new Sphere(Vector3.zero, 1);
public Sphere(float radius)
{
center = Vector3.zero;
this.radius = radius;
}
public Sphere(Vector3 center, float radius)
{
this.center = center;
this.radius = radius;
}
///
/// Returns a point on the sphere at the given coordinates
///
/// Horizontal angle in degrees [0, 360]
/// Vertical angle in degrees [-90, 90]
public Vector3 GetPoint(float horizontalAngle, float verticalAngle)
{
return center + Geometry.PointOnSphere(radius, horizontalAngle, verticalAngle);
}
///
/// Returns true if the point intersects the sphere
///
public bool Contains(Vector3 point)
{
return Intersect.PointSphere(point, center, radius);
}
///
/// Linearly interpolates between two spheres
///
public static Sphere Lerp(Sphere a, Sphere b, float t)
{
t = Mathf.Clamp01(t);
return new Sphere(a.center + (b.center - a.center)*t, a.radius + (b.radius - a.radius)*t);
}
///
/// Linearly interpolates between two spheres without clamping the interpolant
///
public static Sphere LerpUnclamped(Sphere a, Sphere b, float t)
{
return new Sphere(a.center + (b.center - a.center)*t, a.radius + (b.radius - a.radius)*t);
}
public static explicit operator Circle2(Sphere sphere)
{
return new Circle2((Vector2) sphere.center, sphere.radius);
}
public static Sphere operator +(Sphere sphere, Vector3 vector)
{
return new Sphere(sphere.center + vector, sphere.radius);
}
public static Sphere operator -(Sphere sphere, Vector3 vector)
{
return new Sphere(sphere.center - vector, sphere.radius);
}
public static bool operator ==(Sphere a, Sphere b)
{
return a.center == b.center && a.radius == b.radius;
}
public static bool operator !=(Sphere a, Sphere b)
{
return !(a == b);
}
public override int GetHashCode()
{
return center.GetHashCode() ^ (radius.GetHashCode() << 2);
}
public override bool Equals(object other)
{
return other is Sphere && Equals((Sphere) other);
}
public bool Equals(Sphere other)
{
return center.Equals(other.center) && radius.Equals(other.radius);
}
public override string ToString()
{
return string.Format("Sphere(center: {0}, radius: {1})", center, radius);
}
public string ToString(string format)
{
return string.Format("Sphere(center: {0}, radius: {1})", center.ToString(format), radius.ToString(format));
}
public string ToString(string format, IFormatProvider formatProvider)
{
return string.Format("Sphere(center: {0}, radius: {1})", center.ToString(format, formatProvider),
radius.ToString(format, formatProvider));
}
}
}