public Triangle(Vector2 a, float ab, float ac, float alpha) { // https://www.mathsisfun.com/algebra/trig-solving-sas-triangles.html Vertices = new Vector2[3]; Angles = new float[3]; Vertices[0] = a; Angles[0] = alpha; float radAlpha = alpha * Mathf.Rad2Deg; float bc = Mathf.Sqrt(Mathf.Pow(ac, 2) + Mathf.Pow(ab, 2) - 2 * ab * ac * Mathf.Cos(radAlpha)); Angles[1] = Mathf.Asin((Mathf.Sin(radAlpha) * ac) / bc) * Mathf.Deg2Rad; Angles[2] = 180 - Angles[1] - Angles[0]; Vertices[2] = Vertices[0] + Vector2.right * ac; Vertices[1] = Hedra.Rotate(Vertices[0], Vertices[2], Angles[0]).normalized *ab; CalculateCenter(); CreateEdges(); CreateNormals(); StoreHeights(); CalculateArea(); rotation = 0; }
// Revisar #region FurthestPointFrom /// <summary> /// Returns the furthest point of this polygon to a point. /// </summary> /// <param name="point"></param> /// <returns>The furthest point of this polygon to another point.</returns> public virtual Vector2 FurthestPointFrom(Vector2 point) { Line2D line = new Line2D(Center, point); List <Vector2> intersections = IntersectionPoints(line); return(Hedra.FurthestPoint(point, intersections)); }
/// <summary> /// Calculates the intersection points of a line against this ellipse. /// </summary> /// <param name="lineP1">Origin point of the line.</param> /// <param name="lineP2">End point of the line.</param> /// <param name="inSegment">Choose only those intersection points in the segment P1-P2.</param> /// <returns></returns> public List <Vector2> Intersect(Vector3 lineP1, Vector3 lineP2, bool inSegment) { // Source: //http://csharphelper.com/blog/2017/08/calculate-where-a-line-segment-and-an-ellipse-intersect-in-c/ float xVector2 = Mathf.Pow((lineP2.x - lineP1.x), 2); float yVector2 = Mathf.Pow((lineP2.y - lineP1.y), 2); float horizontalValue = (xVector2 / HorizontalRadius) / HorizontalRadius; float verticalValue = (yVector2 / VerticalRadius) / VerticalRadius; float A = horizontalValue + verticalValue; float B = 2 * lineP1.x * horizontalValue + 2 * lineP1.y * verticalValue; float C = lineP1.x * horizontalValue + lineP1.y * verticalValue - 1; float[] t = Hedra.QuadraticFormula(A, B, C); List <Vector2> intersectionPoints = new List <Vector2>(); for (int i = 0; i < t.Length; i++) { if (!inSegment || ((t[i] >= 0f) && (t[i] <= 1f))) { Vector2 point = new Vector2(); point.x = lineP1.x + (lineP2.x - lineP1.x) * t[i] + Center.x; point.y = lineP1.y + (lineP2.y - lineP1.y) * t[i] + Center.y; intersectionPoints.Add(point); } } return(intersectionPoints); }
/// <summary> /// Returns the furthest edge of this box to a point. /// </summary> /// <param name="point"></param> /// <returns>The furthest edge of this box to a point.</returns> public virtual Segment2D FurthestEdgeFrom(Vector2 point) { List <Vector2> perpendicularPoints = PerpendicularPointsTo(point); Vector2 closestPoint = Hedra.FurthestPoint(point, perpendicularPoints); int closestEdgeIndex = perpendicularPoints.IndexOf(closestPoint); return(Edges[closestEdgeIndex]); }
protected bool EqualVertices(Vector2 v1, Vector2 v2, int precision = 3) { Vector2 a1 = Hedra.Truncate(v1, precision); Vector2 a2 = Hedra.Truncate(v2, precision); Vector2 difference = a1 - a2; return(difference.magnitude < EPSILON); }
protected override void CreateVertices() { Vertices = Hedra.Circle(Center, Radius, vertexCount).ToArray(); for (int i = 0; i < Vertices.Length; i++) { Vertices[i] = Hedra.Rotate(Center, Vertices[i], rotation); } SortVertices(); }
public SlopeInterceptEquation(Vector2 pointA, Vector2 pointB) { Vector2 direction = pointB - pointA; if (direction.y == 0) { M = 0; } else { M = Hedra.RoundDecimals(direction.y, 3) / Hedra.RoundDecimals(direction.x, 3); } B = pointA.y - M * pointA.x; }
/// <summary> /// Returns the unsigned shortest distance from a point to this line. Also called triangle height. /// </summary> /// <param name="point"></param> /// <returns></returns> public float PerpendicularDistance(Vector2 point) { float a = (PointB - point).magnitude; Vector2 BP = point - PointB; Vector2 BA = -Vector; float angleB = Hedra.Angle(BP, BA) * Mathf.Deg2Rad; float height = a * Mathf.Sin(angleB); return Mathf.Abs(height); }
Polygon GetTriangle(Transform transform) { vertices = 3; List <Vector2> circle = Hedra.Circle(transform.position, size, vertices); Polygon polygon = new Triangle(circle[0], circle[1], circle[2]); polygon.Rotation = transform.rotation.eulerAngles.z; polygon.Center = (Vector2)transform.position + center; return(polygon); }
protected override void CreateVertices() { Vector2 halfSize = size / 2f; Vertices = new Vector2[4]; Vertices[0] = Hedra.Rotate(Center, new Vector2(Center.x - halfSize.x, Center.y + halfSize.y), Rotation); Vertices[1] = Hedra.Rotate(Center, new Vector2(Center.x + halfSize.x, Center.y + halfSize.y), Rotation); Vertices[2] = Hedra.Rotate(Center, new Vector2(Center.x + halfSize.x, Center.y - halfSize.y), Rotation); Vertices[3] = Hedra.Rotate(Center, new Vector2(Center.x - halfSize.x, Center.y - halfSize.y), Rotation); SortVertices(); }
public RegularPolygon(Vector2 position, int vertices, float radius, float rotation) { this.Radius = radius; center = position; this.rotation = rotation; vertexCount = vertices; Init(); Angle = Hedra.Angle(Edges[0], Edges[1]); }
/// <summary> /// Returns the distance from the point A of this line to the intersecting perpendicular point relative to a given point. /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <param name="point"></param> /// <returns></returns> public float PerpendicularBase(Vector2 point) { // Pythagoras theorem: h2 = a2 + b2 Vector2 AP = point - PointA; float hypotenuse = AP.magnitude; float perpendicularDistance = PerpendicularDistance(point); float baseIntersectionLength = Mathf.Sqrt(Mathf.Pow(hypotenuse, 2) - Mathf.Pow(perpendicularDistance, 2)); float sign = Hedra.HardClamp(Vector2.Dot(AP.normalized, Vector.normalized), -1, 1); return baseIntersectionLength * sign; }
public Triangle(Vector2 position, float radius) { Vector2 a = position + Vector2.up * radius; Vector2 b = Hedra.Rotate(position, a, 120f); Vector2 c = Hedra.Rotate(position, a, -120f); Vertices = new Vector2[] { a, b, c }; rotation = 0; Init(); }
public RegularPolygon(RegularPolygon other) { this.Radius = other.Radius; this.center = other.Center; this.rotation = other.Rotation; this.Collider = other.Collider; vertexCount = other.Vertices.Length; Init(); Angle = Hedra.Angle(Edges[0], Edges[1]); }
/// <summary> /// Returns true if the point is contained in this segment. /// </summary> /// <param name="point"></param> /// <returns></returns> public override bool Contains(Vector2 point) { if (point == PointA || point == PointB) { return(true); } float value = Vector2.Distance(PointA, point) + Vector2.Distance(point, PointB) - Vector2.Distance(PointA, PointB); value = Hedra.Truncate(value, 3); return(-EPSILON <= value && value <= EPSILON); }
public virtual void DrawVector(float angle = 35, float size = 0.2f, bool oppositeDirection = false) { Gizmos.DrawLine(PointA, PointB); Vector2 origin = oppositeDirection ? PointA : PointB; Vector2 vector = oppositeDirection ? Vector.normalized : -Vector.normalized; Vector2 flapPoint = origin + vector * size; Vector2 flapA = Hedra.Rotate(origin, flapPoint, angle); Vector2 flapB = Hedra.Rotate(origin, flapPoint, -angle); Gizmos.DrawLine(origin, flapA); Gizmos.DrawLine(origin, flapB); }
public RegularPolygon(CircleCollider2D collider, int vertices) { Transform owner = collider.gameObject.transform; Collider = collider; Radius = collider.radius; rotation = owner.rotation.eulerAngles.z; center = collider.bounds.center; vertexCount = vertices; Init(); Angle = Hedra.Angle(Edges[0], Edges[1]); }
protected List <Vector2> RemoveVertexDuplicates(List <Vector2> original, int precision = 3) { List <Vector2> copy = new List <Vector2>(); for (int i = 0; i < original.Count; i++) { Vector2 v1 = Hedra.Round(original[i], precision); if (!copy.Contains(v1)) { copy.Add(v1); } } return(copy); }
// Revisar - Closest Point debería ser el punto con menos distancia, no la intersección al centro. #region ClosestPointTo /// <summary> /// Returns the closest point of this polygon to a point. /// </summary> /// <param name="point"></param> /// <returns>The closest point of this polygon to a point.</returns> public virtual Vector2 ClosestPointTo(Vector2 point) { Segment2D cast = new Segment2D(Center, point); List <Vector2> intersections = IntersectionPoints(cast); if (intersections.Count == 0) // Point is inside polygon { Line2D line = new Line2D(Center, point); intersections = IntersectionPoints(line); return(Hedra.ClosestPoint(point, intersections)); } else if (intersections.Count == 1) { return(intersections[0]); } return(Hedra.ClosestPoint(point, intersections)); }
protected virtual void CreateNormals() { if (Edges.Length <= 0) { return; } Normals = new Segment2D[Edges.Length]; for (int i = 0; i < Edges.Length; i++) { Vector2 middlePoint = Edges[i].MiddlePoint; // We look for the normal value furthest from the Center Vector2 normal = Hedra.FurthestObject(Edges[i].Normals.ToList(), (vector => { return(Vector2.Distance(middlePoint + vector, Center)); })); Normals[i] = new Segment2D(middlePoint, middlePoint + normal); } }
public virtual void Rotate(float degrees) { rotation += degrees; for (int i = 0; i < Vertices.Length; i++) { Vertices[i] = Hedra.Rotate(Center, Vertices[i], degrees); } for (int i = 0; i < Edges.Length; i++) { Edges[i].Rotate(Center, degrees); } for (int i = 0; i < Normals.Length; i++) { Normals[i].Rotate(Center, degrees); } }
void OnDrawGizmos() { if (!Application.isPlaying) { StoreColliders(); } Gizmos.color = color; for (int i = 0; i < colliders.Length; i++) { Collider2D collider = colliders[i]; if (collider != null) { if (collider is BoxCollider2D) { Hedra.DrawWireCube(collider.bounds.center, ((BoxCollider2D)collider).size, collider.transform.rotation); } else { Hedra.DrawWireCube(collider.bounds.center, collider.bounds.size, collider.transform.rotation); } } } }
/// <summary> /// Returns the deepest Vertex of this box in another box. /// </summary> /// <param name="other"></param> /// <returns>The closest Vertex of this box to another box.</returns> public virtual Vector2 DeepestVertexIn(Polygon other) { Vector2 furthestVertex = FurthestVertexFrom(other); return(Hedra.FurthestPoint(furthestVertex, Vertices.ToList())); }
protected override void Init() { vertices = Hedra.Clamp(vertices, MIN_VERTICES, MAX_VERTICES); polygon = new RegularPolygon(GetComponent <CircleCollider2D>(), vertices); base.Init(); }
public override void Translate(Vector2 direction) { base.Translate(direction); MiddlePoint = Hedra.MidPoint(PointA, PointB); }
public Segment2D(Vector2 pointA, Vector2 pointB) : base(pointA, pointB) { MiddlePoint = Hedra.MidPoint(pointA, pointB); }
public List <Vector2> GeneratePoints(int points, float amplitude, float rotation) { return(Hedra.Arc(Center, amplitude, HorizontalRadius, VerticalRadius, points, rotation)); }
public virtual void Rotate(Vector2 pivotPoint, float degrees) { PointA = Hedra.Rotate(pivotPoint, PointA, degrees); PointB = Hedra.Rotate(pivotPoint, PointB, degrees); Init(); }
/// <summary> /// Returns the furthest Vertex of this polygon to another polygon. /// </summary> /// <param name="other"></param> /// <returns>The furthest Vertex of this polygon to another polygon.</returns> public virtual Vector2 FurthestVertexFrom(Polygon other) { return(Hedra.FurthestPoint(other.Center, Vertices.ToList())); }
public Segment2D(Vector2[] points) : base(points[0], points[1]) { MiddlePoint = Hedra.MidPoint(points[0], points[1]); }