summaryrefslogtreecommitdiff
path: root/frontend/2d/_collisions/pill_line/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/2d/_collisions/pill_line/main.cpp')
-rw-r--r--frontend/2d/_collisions/pill_line/main.cpp111
1 files changed, 32 insertions, 79 deletions
diff --git a/frontend/2d/_collisions/pill_line/main.cpp b/frontend/2d/_collisions/pill_line/main.cpp
index 0476b98..8700649 100644
--- a/frontend/2d/_collisions/pill_line/main.cpp
+++ b/frontend/2d/_collisions/pill_line/main.cpp
@@ -19,12 +19,14 @@ struct Rigidbody {
float32 rotationalVelocity = 0.f;
float32 rotation = 0.f;
float32 mass = 1.f;
- float32 cofOfRestition = 0.7f;
+ float32 cofOfRestition = 1.f;
float32 momentOfInertia = 0.f;
void reset() {
force = { 0, 0 };
velocity = { 0, 0 };
+ rotationalVelocity = 0.f;
+ rotation = 0.f;
}
void applyForce(Vector2 f) {
@@ -164,15 +166,11 @@ struct LineSegment {
shape.unload();
}
- bool isPointOnLine(Vector2 p) {
- // If the dot product is nearly zero, that means it is in the direction of the line
- if (ABS((end - start).dot(p - start)) <= 0.001) {
-
- // We're on the general line, now let's see if we're within the proper bounds:
- return p.x >= start.x && p.x <= end.x && p.x >= start.y && p.y <= start.y;
- }
-
- return false;
+ Vector2 getPointOnLine(float32 t) {
+ return {
+ start.x + (end.x - start.x) * t,
+ start.y + (end.y - start.y) * t,
+ };
}
};
@@ -211,8 +209,8 @@ void load() {
renderer.load(&context);
pill.body.position = Vector2 { context.width / 2.f, context.height / 2.f };
- pill.body.rotationalVelocity = 0.3f;
pill.load(&renderer, 64, 100.f, 50.f);
+ pill.body.rotationalVelocity = 0.3f;
segmentList[0].load(&renderer, Vector4().fromColor(191, 251, 146, 255.f), Vector2 { 50.f, 0.f }, Vector2 { 50.f, static_cast<float>(context.height) });
segmentList[1].load(&renderer, Vector4().fromColor(159, 224, 210, 255.f), Vector2 { context.width - 50.f, 0.f }, Vector2 { context.width - 50.f, static_cast<float>(context.height) });
@@ -229,64 +227,13 @@ float32 areaOfTriangle(Vector2 a, Vector2 b, Vector2 c) {
IntersectionResult getIntersection(Pill* pill, LineSegment* segment) {
IntersectionResult result;
-
- /**
-
- Formula for finding equation of pill:
- 1) Using the parametrized equation of a line:
- x(t) = x1 + (x2 - x1) * t
- y(t) = y1 + (y2 - y1) * t
- 2) Knowing the equation of a translated and rotated ellipse:
-
- Define x and y as follows:
-
- x = x_1 + l, where l is the translation in x
- y = y_1 + h, where h is the translation in y
-
- Therefore, the general equation of a rotated ellipse is:
-
- (x * cos(theta) + y * sin(theta)) / (a * a)
- + (y * cos(theta) - x * sin(theta)) / b * b = 1
-
- ( + l + x * cos(theta) + y * sin(theta)) / (a * a)
- + (y + h + y * cos(theta) + y * sin(theta)) / (a * a)
-
- 3) Plug in the parametrized equation of our line for x_1 and y_2.
-
- 4) If the determinant >= 0, we have an intersection, otherwise, nothing.
-
- **/
-
-
- /*float32 rotationAngleOfPill = pill->body.rotation;
- Vector2 translationOfPill = pill->body.position;
-
- float32 cosRotation = cosf(rotationAngleOfPill);
- float32 sinRotation = sinf(rotationAngleOfPill);
- float32 cosRotationSquared = cosRotation * cosRotation;
- float32 sinRotationSquared = sinRotation * sinRotation;
- float32 aSquared = pill->a * pill->a;
- float32 bSquared = pill->b * pill->b;
-
- float32 x = (segment->end.x - segment->start.x) - translationOfPill.x;
- float32 xSquared = x * x;
- float32 y = (segment->end.y - segment->start.y) - translationOfPill.y;
- float32 ySquared = y * y;
-
- float32 A_XPart = (segment->end.x - segment->start.x - translationOfPill.x) * cosRotationSquared;
- float32 A_YPart = (segment->end.y - segment->start.y - translationOfPill.y) * sinRotationSquared;
- float32 A = ((A_XPart * A_XPart) / aSquared) + ((A_YPart * A_YPart) / bSquared);
-
- float32 B_XPart = 2 * (segment->start.x - translationOfPill.x) * (segment->end.x - segment->start.x - translationOfPill.x);
- float32 B = 2 * cosRotation * sinRotation * (1.f / aSquared - 1.f / bSquared) * (x * y);
- float32 C = (sinRotationSquared / aSquared + cosRotationSquared / bSquared) * ySquared;*/
-
Mat4x4 inverseModel = pill->shape.model.inverse();
Vector2 start = inverseModel * segment->start;
Vector2 end = inverseModel * segment->end;
- float32 A = pow((end.x - start.x), 2.f) / pow(pill->a, 2) + pow((end.y - start.y), 2.f) / pow(pill->b, 2);
- float32 B = ((2 * start.x) * (end.x - start.x)) / pow(pill->a, 2) + ((2 * start.y) * (end.y - start.y)) / pow(pill->b, 2);
- float32 C = pow(start.x, 2) / pow(pill->a, 2) + pow(start.y, 2) / pow(pill->b, 2) - 1.f;
+ Vector2 diff = end - start;
+ float32 A = (diff.x * diff.x) / (pill->a * pill->a) + (diff.y * diff.y) / (pill->b * pill->b);
+ float32 B = ((2 * start.x) * (end.x - start.x)) / (pill->a * pill->a) + ((2 * start.y) * (end.y - start.y)) / (pill->b * pill->b);
+ float32 C = (start.x * start.x) / (pill->a * pill->a) + (start.y * start.y) / (pill->b * pill->b) - 1.f;
float32 determinant = B * B - 4 * A * C;
if (determinant < 0.f) {
@@ -294,17 +241,24 @@ IntersectionResult getIntersection(Pill* pill, LineSegment* segment) {
return result;
}
- float32 t1 = -B + determinant / (2 * A);
- float32 t2 = -B - determinant / (2 * A);
+ float32 t1 = (-B + sqrtf(determinant)) / (2 * A);
+ float32 t2 = (-B - sqrtf(determinant)) / (2 * A);
- Vector2 pointAtT1 = pill->shape.model * Vector2 { segment->start.x + (t1 * (segment->end.x - segment->start.x)), segment->start.y + (t1 * (segment->end.y - segment->start.y)) };
- Vector2 pointAtT2 = { segment->start.x + (t2 * (segment->end.x - segment->start.x)), segment->start.y + (t2 * (segment->end.y - segment->start.y)) };
+ Vector2 pointOnLine = segment->getPointOnLine(t1); // This point is in world space and line space, since the line is in world space
+ Vector2 pointOnEllipse = pointOnLine - pill->body.position; // This point is in ellipse space
+ pointOnEllipse.printDebug("Point on ellipse");
+
+ float32 parametricTEllipse = atan2f( pointOnEllipse.y / pill->b , pointOnEllipse.x / pill->a );
+ Vector2 tangent = { -pill->a * sinf(parametricTEllipse), pill->b * cosf(parametricTEllipse) };
+ Vector2 normal = tangent.getPerp();
+ normal.printDebug("Normal");
+ // or: Vector2 normal = { pointOnEllipse.x * (pill->b / pill->a), pointOnEllipse.y * (pill->a / pill->b) };
result.intersect = true;
result.relativeVelocity = pill->body.velocity - segment->body.velocity;;
- result.collisionNormal = (pointAtT1 - pill->body.position).normalize();
- result.firstPointOfApplication = pointAtT1 - pill->body.position;
- result.secondPointOfApplication = pointAtT1 - ((segment->end - segment->start) / 2.f);
+ result.collisionNormal = normal.normalize();
+ result.firstPointOfApplication = pointOnEllipse;
+ result.secondPointOfApplication = pointOnLine;
return result;
}
@@ -318,16 +272,15 @@ void resolveCollision(Rigidbody* first, Rigidbody* second, IntersectionResult* i
float32 cofOfRestition = (first->cofOfRestition + second->cofOfRestition) / 2.f;
float32 lNumerator = (relativeVelocity * -(1.0 + cofOfRestition)).dot(collisionNormal);
float32 lLinearDenomPart = collisionNormal.dot(collisionNormal * (1 / first->mass + 1 / second->mass));
- float32 lRotationalDenomPart = powf(firstPerp.dot(collisionNormal), 2) / first->momentOfInertia
- + powf(secondPerp.dot(collisionNormal), 2) / second->momentOfInertia;
+ float32 lRotationalDenomPart = powf(firstPerp.dot(collisionNormal), 2) / first->momentOfInertia + powf(secondPerp.dot(collisionNormal), 2) / second->momentOfInertia;
- float32 lImpulseMagnitude = lNumerator / (lLinearDenomPart);// + lRotationalDenomPart);
+ float32 lImpulseMagnitude = lNumerator / (lLinearDenomPart + lRotationalDenomPart);
first->velocity = first->velocity + (collisionNormal * (lImpulseMagnitude / first->mass));
second->velocity = second->velocity - (collisionNormal * (lImpulseMagnitude / second->mass));
- //first->rotationalVelocity = first->rotationalVelocity + firstPerp.dot(collisionNormal * lImpulseMagnitude) / first->momentOfInertia;
- //second->rotationalVelocity = second->rotationalVelocity - secondPerp.dot(collisionNormal * lImpulseMagnitude) / second->momentOfInertia;
+ first->rotationalVelocity = first->rotationalVelocity + firstPerp.dot(collisionNormal * lImpulseMagnitude) / first->momentOfInertia;
+ second->rotationalVelocity = second->rotationalVelocity - secondPerp.dot(collisionNormal * lImpulseMagnitude) / second->momentOfInertia;
}
void update(float32 deltaTimeSeconds, void* userData) {
@@ -399,4 +352,4 @@ EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, voi
printf("Stop clicked\n");
unload();
return true;
-} \ No newline at end of file
+}