How to determine the orientation / rotation of a triangle? - c#

I'm using Emgu CV to find an isosceles triangle in an image, from this triangle that's been detected I'm attempting to determine the orientation (front, left, right, and back side) and what the rotation of the triangle is (ex: -30 degrees).
I'm able to detect where this triangle is and what each of the three coordinates are, I'm just not sure how to continue on finding orientation and angle of rotation. Would this be a function of Emgu CV, or just simple math; and how would I go about it?

Find the two sets of co-ordinates closest together (Pythagoras's theorem makes that simple).
That's your short side.
The point not used on that side is the front.
Left and right are just the lines clockwise and anticlockwise from the front.
The angle can be found using simple trigonometry between the first line you just found and a hypothetical line you are measuring the angle from.
You will need to look up the relevant math but each of those steps is reasonably straightforwards on its own once you break it down like that.

Related

Sphere vs Rotation Box Custom Collision Problem (C#, Unity)

I'm not really like to post questions about problems without doing the research, but I'm close to give up, so I thought I give it a shot and ask you about my problem.
I want to create a custom collision detection in Unity ( So please don't advice "use rigidbody and\or colliders" because I don't want to use them by purpose).
The main idea: I want to detect Basic Sphere and Basic Box collision. I already find AABB vs Sphere theme with the following solution:
bool intersect(sphere, box) {
var x = Math.max(box.minX, Math.min(sphere.x, box.maxX));
var y = Math.max(box.minY, Math.min(sphere.y, box.maxY));
var z = Math.max(box.minZ, Math.min(sphere.z, box.maxZ));
var distance = Math.sqrt((x - sphere.x) * (x - sphere.x) +
(y - sphere.y) * (y - sphere.y) +
(z - sphere.z) * (z - sphere.z));
return distance < sphere.radius;
}
And this code does the job, the box bounding and the sphere center point with radius works fine, I can detect the Sphere collision on Box.
The problem is, I want to Rotating the Cube in Runtime, so that will screw up everything, the bounding will split away and the collision will gone (or collide on random places). I've read about some comments where they said, bounding not works with rotation, but I'm not sure what else can I use to solve this problem.
Can you help me with this topic please? I'll take every advice I can get (except Colliders & Rigidbodies of course).
Thank you very much.
You might try using the separating axis theorem. Essentially, for a polyhedron, you use the normal of each face to create an axis. Project the two shapes you are comparing onto each axis and look for an intersection. If there is no intersection along any of the axes, there is no intersection of shapes. For a sphere, you will just need to project onto the polyhedron's axes. There is a great 2D intro to this from metanet.
Edit: hey, check it out-- a Unity implementation.
A good method to find if an AABB (axis aligned bounding box) and sphere are intersecting is to find the closest point on the box to the sphere's center and determine if that point is within the sphere's radius. If so, then they are intersecting, if not then not.
I believe you can do the same thing with this more complicated scenario. You can represent a rotated AABB with a geometrical shape called a parallelepiped. You would then find the closest point on the parallelepiped to the center of the sphere and again check if that point exists within the sphere's radius. If so, then they intersect. If not, then not.
The difficult part is finding the closest point on the parallelepiped. You can represent a parallelepiped in code with 4 3d vectors: center, extentRight, extentUp, and extentForward. This is similar to how you can represent an AABB with a 3d vector for center along with 3 floats: extentRight, extentUp, and extentForward. The difference is that for the parallelepiped those 3 extents are not 1 dimensional scalars, but are full vectors.
When finding the closest point on an AABB surface to a given point, you are basically taking that given point and clamping it to the AABB's volume. You would, for example, call Math.Clamp(point.x, AABB.Min.x, AABB.Max.x) and so on for Y and Z.
The resulting X,Y,Z would be the closest point on the AABB surface to the given point.
To do this for a parallelepiped you need to solve the "linear combination" (math keyword) of extentRight(ER), extentUp(EU), and extentForward(EF) to get the given point. In other words, what scalars do you have to multiply ER, EU, and EF by to get to the given point? When you find those scalars you need to clamp them between 0 and 1 and then multiply them again by ER, EU, and EF respectively to get that closest point on the surface of the parallelepiped. Be sure to offset the given point by the Parallelepiped's min position so that the whole calculation is done in its local space.
I didn't want to spend any extra time learning how to solve for a linear combination (it seems it involves things like using an "augmented matrix" and "gaussian elimination") otherwise I'd include that here too. This should get you or anyone else reading this off to the right track hopefully.
Edit:
Actually I think its a lot simpler and you don't need a parallelepiped. If you have access to the rotation (Vector3 or Quaternion) that rotated the cube you could get the inverse of that and use that inverse rotation to orbit the sphere around the cube so that the new scenario is just the normal axis aligned cube and the orbited sphere. Then you can do a normal AABB - sphere collision detection.

How to calculate whether the point in cube is Visibility in WPF 3D

I want to show a Perspective cube, so I should calculate whether the point in cube is Visibility.
Like the picture, the red vertex should be invisible, while the others should be visible.
Can anyone give me a formula to calculate it?
The cube may be Rotated that I have no way to do it.
I try use HitTest to do it but it have a Poor performance.
I want to know a formula to calculate whether the point and face and line is visibility.
Edit:
The point is any point on the line.
I build it with Media3D.
If any of the faces connected to the vertex has a normal facing the camera (see back face culling), the vertex is visible. This should be pretty quick to calculate.
Try taking the dot product of the "camera vector" (this is usually (0,0,1)) and all of the normal vectors of the cube faces that the vertex in question touches.
If any of the dot products return a negative value, then the angle between the camera vector and the normal vector of the respective cube face is greater that 90 degrees and is therefore "facing" the camera.
If the point of interest is a vertex, you'll be running three dot products. If the point of interest is along a line between vertices, you will only calculate two.

Snaping circle to rectangle/line

I am trying to implement some kind of snapping functionality in WPF for a circle (which represents my mouse) and it should snap to another object (normally this would be a line or a rectangle).
Is there a way to do this kind of functionality with WPF without doing all the calculations on my own and if not is there an easy way (library?) to get this kind of information?
Edit: I want to snap the border of the circle to the border of the rectangle/line.
As a first step, you should find the point on the rectangle that is the closest to the cursor, and the distance between the two: extending the edges of the rectangle, you partition the plane into 9 regions. Depending on the region where the cursor lies, the searched distance will be the distance to a corner (Euclidean distance formula) or the distance to an edge (difference of abscissas or ordinates).
Subtract the circle radius from this distance. This will tell you if you are close enough for a snap.
When a snap is possible, move the cursor along the line from the current cursor position to the closest point until you hit the corner or edge. You will need to use the parametric equation of the line segment.
The complete discussion requires some care but only involves simple math.
A similar approach is possible to snap to a line segment. Here is a trick: if you rotate the line segment to make it horizontal, you can consider the line segment as a degenerate rectangle and use the same snapping algorithm. Rotate the line segment and the cursor, apply the snapping logics and then counter-rotate the updated cursor.
That kind of functionality only takes a few lines of code to replicate... I doubt that you'll find a 'library' of code to do it for you. The method is as follows:
Keep a collection that contains the 4 Points that form each shape's bounding box. You then need to handle to MouseMove event on the Canvas, or shape container. In this event, you simply need to ascertain whether the current mouse position is within a certain distance from any of the shape edges... you'll have a little bit more work to do with non-rectangular shapes to calculate their edges, but the principal is the same.
If you detect the presence of a nearby shape, then you simply need to change the value of the nearest dimension to that of the nearby shape... the snap. That's it... much easier than you think.

Get points for a semi circle

The title says it.
This link(Wikipedia Midpoint Circle Algorithm) shows how to get points for a full circle, now I need it to be for a semi circle(an arc?).
It semi circle should be facing up, like in this image(Check this image)
But the bottom of the circle should be open!
For those who might think this is homework, it's not.
I'm working on a game in Xna and I want the 'rocket' that comes out of the rocket launcher to go through a certain path, a semicircle.
I don't think that algorithm is the right way to do what you want to do: describe a path. That algorithm is for plotting pixels along the path rather than describing it as such. Instead, trigonometry is probably what you want. Increase the angle from one point to another, step by step. A circle is 2π radians, so half a circle is π radians.
This should provide what you need to describe the arc. http://mathworld.wolfram.com/Trigonometry.html
Just use the Midpoint Circle Algorithm for values where y > 0 (assuming that the circle's midpoint is at (0, 0)). Anything below that is "open"

Image processing - rotate scanned document to align text

I have an OCR C# project where I get a scanned document with text in it, and I need to return the text in the document.
I already have the solution for parsing the text, however we are stuck in the part where the scanned document is rotated (to the right or to the left).
Suppose there is no noise in the image (All pixels are white or black), can anyone help us with an algorithm to rotate the image in runtime (Without a human eye)?
Thanks
Use Hough Transform to detect the strongest line orientation which should be the horizontal text orientation. The basic premise of the Hough Transform is to convert x-y coordinate to a r-theta coordinate system where r is the distance from origin and theta is the orientation.
Once the image is transformed, bin same thetas to find the strongest orientation.
Because this method uses voting within discrete r and thetas. The resolution of the theta is only as good as number of bins used. So instead of using -180 to +180 degree in one degree increment, you might want to bound it for either more accurate angle or speed.
(I not an expert but by curiosity write this post)
IMHO, this problem can be solved cost effectively with brute force trial and error approach. Because there can be not too many wrong orientation.
I think your can easily determine the bounding box of text. This bounding box can have wrong orientation only in two way. Rotated clock wisely or Rotated counter clock wisely. So with maximum two rotation of image (rotation that make bounding box upright) you can find correct orientation.
That is, you could find correct document orientation without further processing of image to determine text align. And determining the text align will be rather large processing I think.
UPDATE
I'm suggesting that we don't have to find exact rotation angle. If the bonding box is upright it can be in the right angle or 180 degree rotated angle.
1) make bonding box upright
2) run OCR, check the result, if ok its done
3) rotate 180 degree
2) run OCR. this time it must be in the right angle
If we really have to find the exact rotation angle, I think it must start with finding possible shape of character 'o', 'c', or 'm' (excluding italic font). Or, find relative location of the period('.'). This will require complicated operation, I think.

Categories