I have:
A semicircle defined by a point (M), an angle (Θ) and a radius (r)
A rectangle defined by four points (A, B, C, D)
The semicircle can be entirely inside the rectangle and vice versa.
Is there a way/algorithm (preferably in javascript) to detect collision between these 2 shapes ?
Related
I have two 3D points (x,y,z), namely A and B and a bunch of other 3D points. Point A is at (0,0,0).
I would like to set point B to (0,0,0) so that all other points including A and B are translated and rotated in a way that is appropriate (so that A is no longer at (0,0,0)).
I know that there are some translations and rotations involved, but nothing more than that.
UPGRADE:
Point B is also constrained by three vectors: x', y', z' that represent x, y, and z axis of B's coordinate system. I think these should be somehow considered for the rotation part.
As you have given two points, one (A) at the origin and one (B) somewhere else, and you want to shift (translate) B to the origin, I don't see the necessity for any rotation.
If you don't have any other contraints, just shift all coordinates by the initial coordinates of B.
You can construct a transformation matrix as given, e.g., https://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations for 2D, but if you simply translate, R' = R + T, where R' is the vector after transformation, R the vector before and T the translation vector.
For more general transformations including rotations, you have to specify the rotation angle and axis. Then, you can come up with more general transformation, see above link.
Suppose I have a bullet as shown below where the measurements are in units of bullet diameters (this thing is 3 dimensional, so imagine rotating it about the x axis here)
If this bullet were to be tilted upwards by an angle θ, how could I numerically find its projected area?
I'm trying to find the area that such a bullet would present to the air as it moves through it and so if it is not tilted away from the direction of motion this area is simply a circle. I know for small tilts, it will simply present the projected area of a cylinder but I am unsure about how to deal with tilts large enough that one needs to care about the tip of the bullet for purposes of finding the area. Anyone have ideas about how to deal with this?
Hint:
The boundary curves of the bullet are the apparent outline of the inner surface of a self-intersecting torus. They can be found by expressing that the normal vector is parallel to the projection plane.
With z being the axis of the bullet, the parametric equation of the surface is
x= (R + r sinφ) cosΘ
y= (R + r sinφ) sinΘ
z= r cosφ
and the normal is obtained by setting R=0,
x= r sinφ cosΘ
y= r sinφ sinΘ
z= r cosφ
Now for some projection plane with a normal in direction (cosα, 0, sinα), the outline is such that
r sinφ cosΘ cosα + r cosφ sinα = 0.
From this you can draw Θ as a function of φ or conversely and construct points along the curve.
When α increases, the tip of the bullet starts entering the ellipse resulting from the projection of the basis of the cylindre. This ellipse corresponds to the angle φ such that z=0.
The surface is known as a lemon shape: http://mathworld.wolfram.com/Lemon.html
Question:
I need to calculate intersection shape (purple) of plane defined by Ax + By + Cz + D = 0 and frustum defined by 4 rays emitting from corners of rectangle (red arrows). The result shoud be quadrilateral (4 points) and important requirement is that result shape must be in plane's local space. Plane is created with transformation matrix T (planes' normal is vec3(0, 0, 1) in T's space).
Explanation:
This is perspective form of my rectangle projection to another space (transformation / matrix / node). I am able to calculate intersection shape of any rectangle without perspective rays (all rays are parallel) by plane-line intersection algorithm (pseudocode):
Definitions:
// Plane defined by normal (A, B, C) and D
struct Plane { vec3 n; float d; };
// Line defined by 2 points
struct Line { vec3 a, b; };
Intersection:
vec3 PlaneLineIntersection(Plane plane, Line line) {
vec3 ba = normalize(line.b, line.a);
float dotA = dot(plane.n, l.a);
float dotBA = dot(plane.n, ba);
float t = (plane.d - dotA) / dotBA;
return line.a + ba * t;
}
Perspective form comes with some problems, because some of rays could be parallel with plane (intersection point is in infinite) or final shape is self-intersecting. Its works in some cases, but it's not enough for arbitary transformation. How to get correct intersection part of plane wtih perspective?
Simply, I need to get visible part of arbitary plane by arbitary perspective "camera".
Thank you for suggestions.
Intersection between a plane (one Ax+By+Cx+D equation) and a line (two planes equations) is a matter of solving the 3x3 matrix for x,y,z.
Doing all calculations on T-space (origin is at the top of the pyramid) is easier as some A,B,C are 0.
What I don't know if you are aware of is that perspective is a kind of projection that distorts the z ("depth", far from the origin). So if the plane that contains the rectangle is not perpendicular to the axis of the fustrum (z-axis) then it's not a rectangle when projected into the plane, but a trapezoid.
Anyhow, using the projection perspective matrix you can get projected coordinates for the four rectangle corners.
To tell if a point is in one side of a plane or in the other just put the point coordinates in the plane equation and get the sign, as shown here
Your question seems inherently mathematic so excuse my mathematical solution on StackOverflow. If your four arrows emit from a single point and the formed side planes share a common angle, then you are looking for a solution to the frustum projection problem. Your requirements simplify the problem quite a bit because you define the plane with a normal, not two bounded vectors, thus if you agree to the definitions...
then I can provide you with the mathematical solution here (Internet Explorer .mht file, possibly requiring modern Windows OS). If you are thinking about an actual implementation then I can only direct you to a very similar frustum projection implementation that I have implemented/uploaded here (Lua): https://github.com/quiret/mta_lua_3d_math
The roadmap for the implementation could be as follows: creation of condition container classes for all sub-problems (0 < k1*a1 + k2, etc) plus the and/or chains, writing algorithms for the comparisions across and-chains as well as normal-form creation, optimization of object construction/memory allocation. Since each check for frustum intersection requires just a fixed amount of algebraic objects you can implement an efficient cache.
I have :
Arc : defined by p1x, p1y - p2x,p2y , radius, center, initial - final ang.
Line : defined by ax,ay - bx,by.
As you can see at the image I want to figure out an arc tangent to arc and linea and passing by the end point of first arc .
I think there is a unique solution. (or maybe two, R + and R - )
I'm trying so see how to implement an algorithm, without results...
Any idea would be appreciated...
What you are trying to do is to find a circle tangent to an infinite line "L", and tangent to a circle at a particular point on the circle. The key observation is that, since the tangent vector to any circle at a given angle is perpendicular to the radius vector for that angle, what we need to find are the point "TC" ("Tangent Center") and distance "d" at which a line offset from the given line by the distance d intersects a normal drawn outward from the circle for the same distance (forgive my bad art):
The easiest way to solve for "d" is as follows:
Construct the normalized normal vector "R" at point "P" by taking P-C and normalizing. (This constructs the outer tangent to the circle. If you want an inner tangent, you can flip.)
Construct the normalized perpendicular vector "N" to the line "L". I'm not really sure what your variables "ax,ay - bx,by" mean, so let's define the line by a start point "A = (ax, ay)" and a direction vector "DA = (dax, day)". In that case the normal is +/- (-day, dax)/sqrt(day*day+dax*dax). (The normalized cross with the (0,0,1) vector in 3d.)
Choose the sign of "N" so that it points away from P, i.e. if the dot product of (P-A) and N is positive, flip N. if the dot product is (nearly) zero, then the tangent circle would have radius (nearly) zero, and so is not defined.
Now consider a point TC defined by P2 = P + d*(R + N) for some d. If P2 lies on the line L, then d is the radius of the tangent circle we seek! P2 lies on the line if and only if the dot product of (P2 - A) and N is zero. This defines a linear equation in one variable -- d -- so you can solve for it. Note that if R + N is (nearly) of length zero, then P is 180 degrees away from the closest point between the circle and the line; you will need to check for this explicitly and handle it.
Once you have d, you can get the center of the circle TC=P + d*R.
This method should have good numerical stability when the tangent to the circle at P is parallel or nearly parallel to the line.
You didn't specify a language, but hopefully this can get you started. My primary language is c#.
I'm trying to find the best way to get the most distant point of a circle from a specified point in 2D space. What I have found so far, is how to get the distance between the point and the circle position, but I'm not entirely sure how to expand this to find the most distant point of the circle.
The known variables are:
Point a
Point b (circle position)
Radius r (circle radius)
To find the distance between the point and the circle position, I have found this:
xd = x2 - x1
yd = y2 - y1
Distance = SquareRoot(xd * xd + yd * yd)
It seems to me, this is part of the solution. How would this be expanded to get the position of Point x in the below image?
As an additional but optional part of the question: I have read in some places that it would be possible to get the distance portion without using the Square Root, which is very performance intensive and should be avoided if fast code is necessary. In my case, I would be doing this calculation quite often; Any comments on this within the context of the main question would be welcome too.
What about this?
Calculate A-B.
We now have a vector pointing from the center of the circle towards A (if B is the origin, skip this and just consider point A a vector).
Normalize.
Now we have a well defined length (the length is 1)
If the circle is not of unit radius, multiply by radius. If it is unit radius, skip this.
Now we have the correct length.
Invert sign (can be done in one step with 3., just multiply with the negative radius)
Now our vector points in the correct direction.
Add B (if B is the origin, skip this).
Now our vector is offset correctly so its endpoint is the point we want.
(Alternatively, you could calculate B-A to save the negation, but then you have to do one more operation to offset the origin correctly.)
By the way, it works the same in 3D, except the circle would be a sphere, and the vectors would have 3 components (or 4, if you use homogenous coords, in this case remember -- for correctness -- setting w to 0 when "turning points into vectors" and to 1 at the end when making a point from the vector).
EDIT:
(in reply of pseudocode)
Assuming you have a vec2 class which is a struct of two float numbers with operators for vector subtraction and scalar multiplicaion (pretty trivial, around a dozen lines of code) and a function normalize which needs to be no more than a shorthand for multiplying with inv_sqrt(x*x+y*y), the pseudocode (my pseudocode here is something like a C++/GLSL mix) could look something like this:
vec2 most_distant_on_circle(vec2 const& B, float r, vec2 const& A)
{
vec2 P(A - B);
normalize(P);
return -r * P + B;
}
Most math libraries that you'd use should have all of these functions and types built-in. HLSL and GLSL have them as first type primitives and intrinsic functions. Some GPUs even have a dedicated normalize instruction.