ZeroVR/ZeroPacientVR/Assets/Octave3D World Builder/Scripts/Math/Ellipse2D.cs

172 lines
6.0 KiB
C#

#if UNITY_EDITOR
using UnityEngine;
using System.Collections.Generic;
namespace O3DWB
{
public struct Ellipse2D
{
#region Private Variables
private Vector2 _center;
private Vector2 _radii;
#endregion
#region Public Properties
public Vector2 Center { get { return _center; } set { _center = value; } }
public Vector2 Radii { get { return _radii; } set { _radii = value; } }
public float RadiusX { get { return _radii.x; } set { _radii.x = value; } }
public float RadiusY { get { return _radii.y; } set { _radii.y = value; } }
#endregion
#region Constructors
public Ellipse2D(Vector2 center, Vector2 radii)
{
_center = center;
_radii = radii;
}
public Ellipse2D(Vector2 center, float radiusX, float radiusY)
{
_center = center;
_radii = new Vector2(radiusX, radiusY);
}
public Ellipse2D(Rect enclosingRectangle)
{
_center = enclosingRectangle.center;
_radii = new Vector2(enclosingRectangle.width * 0.5f, enclosingRectangle.height * 0.5f);
}
public Ellipse2D(Circle2D circle)
{
_center = circle.Center;
_radii = new Vector2(circle.Radius, circle.Radius);
}
#endregion
#region Public Methods
public bool OverlapsRectangle(Rect rectangle)
{
if (ContainsAnyPoint(rectangle.GetCenterAndCornerPoints())) return true;
if (rectangle.ContainsAnyPoint(GetExtentsPoints())) return true;
if (IntersectsAnyRay(rectangle.GetEdgeRays())) return true;
return false;
}
public bool ContainsRectangle(Rect rectangle)
{
return ContainsAllPoints(rectangle.GetCornerPoints());
}
public bool ContainsAllPoints(List<Vector2> points)
{
Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y);
Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f);
foreach (Vector2 point in points)
{
Vector2 adjustedPoint = Vector2.Scale(point, invRadii);
if (!circle.ContainsPoint(adjustedPoint)) return false;
}
return true;
}
public bool ContainsAnyPoint(List<Vector2> points)
{
Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y);
Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f);
foreach (Vector2 point in points)
{
Vector2 adjustedPoint = Vector2.Scale(point, invRadii);
if (circle.ContainsPoint(adjustedPoint)) return true;
}
return false;
}
public bool ContainsPoint(Vector2 point)
{
Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y);
Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f);
Vector2 adjustedPoint = Vector2.Scale(point, invRadii);
return circle.ContainsPoint(adjustedPoint);
}
public bool IntersectsAnyRay(List<Ray2D> rays)
{
foreach(Ray2D ray in rays)
{
if (IntersectsRay(ray)) return true;
}
return false;
}
public bool IntersectsRay(Ray2D ray, out float t)
{
Vector2 invRadii = new Vector2(1.0f / Radii.x, 1.0f / Radii.y);
Ray2D adjustedRay = new Ray2D(Vector2.Scale(ray.Origin, invRadii), Vector2.Scale(ray.Direction, invRadii));
Circle2D circle = new Circle2D(Vector2.Scale(Center, invRadii), 1.0f);
return circle.Raycast(adjustedRay, out t);
}
public bool IntersectsRay(Ray2D ray)
{
float t;
return IntersectsRay(ray, out t);
}
public List<Vector2> GetExtentsPoints()
{
// Return the extent points in the following format: top, right, bottom, left.
return new List<Vector2>
{
_center + new Vector2(0.0f, _radii.y),
_center + new Vector2(_radii.x, 0.0f),
_center + new Vector2(0.0f, -_radii.y),
_center + new Vector2(-_radii.x, 0.0f)
};
}
public Vector3 GetWorldCenterPointInFrontOfCamera(Camera camera, float distanceFromCamNearPlane)
{
return _center.GetWorldPointInFrontOfCamera(camera, distanceFromCamNearPlane);
}
public List<Vector3> GetWorldExtentPointsInFrontOfCamera(Camera camera, float distanceFromCamNearPlane)
{
List<Vector2> extentPoints = GetExtentsPoints();
return Vector2Extensions.GetWorldPointsInFrontOfCamera(extentPoints, camera, distanceFromCamNearPlane);
}
public List<Vector3> GetWorldBorderLinesInFrontOfCamera(Camera camera, float distanceFromCamNearPlane, int numberOfEllipseSlices)
{
List<Vector3> worldExtentPoints = GetWorldExtentPointsInFrontOfCamera(camera, distanceFromCamNearPlane);
Vector3 worldCenterPoint = GetWorldCenterPointInFrontOfCamera(camera, distanceFromCamNearPlane);
Vector3 ellipseUp = worldExtentPoints[0] - worldCenterPoint;
Vector3 ellipseRight = worldExtentPoints[1] - worldCenterPoint;
float radiusX = ellipseRight.magnitude;
float radiusY = ellipseUp.magnitude;
ellipseUp.Normalize();
ellipseRight.Normalize();
return Vector3Extensions.Get3DEllipseCircumferencePoints(radiusX, radiusY, ellipseRight, ellipseUp, worldCenterPoint, numberOfEllipseSlices);
}
public bool FullyContainsOrientedBoxCenterAndCornerPointsInScreenSpace(OrientedBox orientedBox, Camera camera)
{
List<Vector2> boxCenterAndCornerScreenPoints = orientedBox.GetScreenCenterAndCornerPoints(camera);
return ContainsAllPoints(boxCenterAndCornerScreenPoints);
}
#endregion
}
}
#endif