You should create a point struct this makes things a bit easier. It has an double x, double y, double z coordinate. This point will be immensely useful, as we can define a line segment as a pair<point,point>, a triangular section of a plane as a vector<point> of 3 points, and a sphere as a center + a radius. The point is the most basic unit in geometry, and it is a good idea to package it compactly in a struct.
In the next 5 chapters, we will show how to handle cases where an object falls onto another object, but these objects are simpler: points, lines (When I refer to a line, I mean a line segment), planes (I really refer to a triangular section of a plane), or spheres. Note that a cube or tetrahedron is just composed of a bunch of these simple shapes.
It turns out there are only 10 types of collisions you need to consider:
- A point falling onto a plane [CH 2]
- A plane falling onto a point [CH 2]
- A line falling onto another line [CH 3]
- A point falling onto sphere [CH 4]
- A sphere falling onto a point [CH 4]
- A line falling onto a sphere [CH 5]
- A sphere falling onto a line [CH 5]
- A plane falling onto a sphere [CH 6]
- A sphere falling onto a plane [CH 6]
- A sphere falling onto a sphere [CH 7].
The you can convince yourself that you don't have to consider other things. For example: a line falling onto a plane is encapsulated by a line falling onto a line if it falls onto an edge of the plane, or a point falling onto a plane if the line lands on the plane.
We have methods with parameters (center, object 1, object 2). object 1 and the center are in their own coordinate system and are rigid and will fall together. Then, we place object 1 with the center in object 2's coordinate system at a very tall height and make it fall. As object 1 falls, it's center will also fall that exact distance, until, object 1 collides with object 2. (The center has no collision). Then, the method will output the center's z coordinate in object 2's coordinate system. If object 1 falls through object 2, then the method returns -1.
For example, if the center is $$$(0, 0, 3)$$$, object 1 is a point $$$(0, 0, 2)$$$, and object 2 is the plane $$$(-1, -1, 0)$$$, $$$(-1, 1, 0)$$$, $$$(1, 0, 0)$$$. (this is a flat triangle on the x-y plane that encloses the origin), the method should return 1, since object 1 will fall onto the origin, and the center, always being $$$(3-2) = 1$$$ higher in the z-direction, would be at the point $$$(0, 0, 1)$$$, with a z coordinate of 1.
There are several helper methods to implement that will be helpful:
point add(point a, point b). This method returns a new point with the sum of the x, y, z coordinates of 2 points. This is adding 2 points $$$a+b$$$.
point sub(point a, point b). This method returns a new point with $$$x = a_x - b_x$$$, and similarly for y and z. This is subtracting 2 points $$$a-b$$$.
point mul(point a, double b). This method returns a new point with $$$x = a_x \cdot b$$$. This is multiplying $$$a \cdot b$$$.
point cross(point a, point b). This treats a and b like vectors, and returns their cross product. (Refer to https://en.wikipedia.org/wiki/Cross_product)
int pointLoc(point a, point b, point c). This method determines if you stand at a, look at b, whether c would be collinear, to the left of you, or to the right of you. (1 if to the left, 0 if collinear, -1 if to the right).
This is fairly simple. You can check the quantity $$$(c_y - a_y)(b_x - a_x) - (b_y - c_y)(c_x - a_x)$$$ whether it is positive, negative or zero. Positive means that C is to the left of AB. negative means C is to the right of AB, and zero means C is collinear with AB. I am not sure why this works. Perhaps it is an interesting property of the cross product, but you don't need to know to implement point location test.
double dist2D(point a, point b). Returns the distance of the projection of the points on the 2d plane, ignores the z coordinates. The distance is $$$\sqrt{(a_x - b_x)^2 + (a_y - b_y)^2}$$$.