Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
Ellipse.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <Jolt/Math/Float2.h>
8
10
14{
15public:
17
19 Ellipse(float inA, float inB) : mA(inA), mB(inB) { JPH_ASSERT(inA > 0.0f); JPH_ASSERT(inB > 0.0f); }
20
22 bool IsInside(const Float2 &inPoint) const
23 {
24 return Square(inPoint.x / mA) + Square(inPoint.y / mB) <= 1.0f;
25 }
26
30 Float2 GetClosestPoint(const Float2 &inPoint) const
31 {
32 float a_sq = Square(mA);
33 float b_sq = Square(mB);
34
35 // Equation of ellipse: f(x, y) = (x/a)^2 + (y/b)^2 - 1 = 0 [1]
36 // Normal on surface: (df/dx, df/dy) = (2 x / a^2, 2 y / b^2)
37 // Closest point (x', y') on ellipse to point (x, y): (x', y') + t (x / a^2, y / b^2) = (x, y)
38 // <=> (x', y') = (a^2 x / (t + a^2), b^2 y / (t + b^2))
39 // Requiring point to be on ellipse (substituting into [1]): g(t) = (a x / (t + a^2))^2 + (b y / (t + b^2))^2 - 1 = 0
40
41 // Newton raphson iteration, starting at t = 0
42 float t = 0.0f;
43 for (;;)
44 {
45 // Calculate g(t)
46 float t_plus_a_sq = t + a_sq;
47 float t_plus_b_sq = t + b_sq;
48 float gt = Square(mA * inPoint.x / t_plus_a_sq) + Square(mB * inPoint.y / t_plus_b_sq) - 1.0f;
49
50 // Check if g(t) it is close enough to zero
51 if (abs(gt) < 1.0e-6f)
52 return Float2(a_sq * inPoint.x / t_plus_a_sq, b_sq * inPoint.y / t_plus_b_sq);
53
54 // Get derivative dg/dt = g'(t) = -2 (b^2 y^2 / (t + b^2)^3 + a^2 x^2 / (t + a^2)^3)
55 float gt_accent = -2.0f *
56 (a_sq * Square(inPoint.x) / Cubed(t_plus_a_sq)
57 + b_sq * Square(inPoint.y) / Cubed(t_plus_b_sq));
58
59 // Calculate t for next iteration: tn+1 = tn - g(t) / g'(t)
60 float tn = t - gt / gt_accent;
61 t = tn;
62 }
63 }
64
66 Float2 GetNormal(const Float2 &inPoint) const
67 {
68 // Calculated by [d/dx f(x, y), d/dy f(x, y)], where f(x, y) is the ellipse equation from above
69 return Float2(inPoint.x / Square(mA), inPoint.y / Square(mB));
70 }
71
72private:
73 float mA;
74 float mB;
75};
76
#define JPH_NAMESPACE_END
Definition: Core.h:367
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:361
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
constexpr T Cubed(T inV)
Returns .
Definition: Math.h:59
constexpr T Square(T inV)
Square a value.
Definition: Math.h:52
#define JPH_OVERRIDE_NEW_DELETE
Macro to override the new and delete functions.
Definition: Memory.h:29
Definition: Ellipse.h:14
Float2 GetClosestPoint(const Float2 &inPoint) const
Definition: Ellipse.h:30
JPH_OVERRIDE_NEW_DELETE Ellipse(float inA, float inB)
Construct ellipse with radius A along the X-axis and B along the Y-axis.
Definition: Ellipse.h:19
bool IsInside(const Float2 &inPoint) const
Check if inPoint is inside the ellipse.
Definition: Ellipse.h:22
Float2 GetNormal(const Float2 &inPoint) const
Get normal at point inPoint (non-normalized vector)
Definition: Ellipse.h:66
Class that holds 2 floats, used as a storage class mainly.
Definition: Float2.h:11
float y
Definition: Float2.h:31
float x
Definition: Float2.h:30