I have two points on circle. I know degree from center and coordinates of one point. I want find coordinate of the other point. I think need multiply by rotation matrix to find point. How can i do in c++? Is there any function for it?
you can calculate it directly using
x cos(angle) - y sin (angle )
x sin(angle) + y cos (angle )
the cos and sin functions are available in math.h
note that the rotation will be in anti clockwise direction
and the rotation will be about the origin. 'angle' should be in radians.
if the center of the circle is not located at origin then you'll have to first shift the origin to the center of the circle , apply rotation and shift the origin back again to get the other point
Related
I am rendering a tile map to a fbo and then moving the resulted buffer to a texture and rendering it on a FSQ. Then from the mouse click events, I got the screen coordinates and move them to clip space [-1,1]:
glm::vec2 posMouseClipSpace((2.0f * myCursorPos.x) / myDeviceWidth -
1.0f, 1.0f - (2.0f * myCursorPos.y) / myDeviceHeight);
I have logic on my program that based on those coordinates, it selects a specific tile on the texture.
Now, moving to 3D, I am texturing a semi cylinder with the FBO I used in the previous step:
In this case I am using a ray-triangle intersection point that hits the cylinder with radius r and height h. The idea is moving this intersection point to space [-1,1] so I can keep the logic on my program to select tiles
I use the Möller–Trumbore algorithm to check points on the cylinder hit by a ray. Lets say the intersected point is (x,y) (not sure if the point is in triangle, object or world space. Apparently it's worldspace).
I want to translate that point to space x:[-1,1], y[-1,1].
I know the height of my cylinder, which is a quarter of the cylinder's arc length:
cylinderHeight = myRadius * (PI/2);
so the point in the Y axis can be set in [-1,1]space:
vec2.y = (2.f * (intersectedPoint.y - myCylinder->position().y) ) /
(myCylinder->height()) - 1.f
and That works perfectly.
However, How to compute the horizontal axis which depends on 2 variables x and z?
Currently, my cylinder's radius is 1, so by coincidence a semi cylinder set in the origin would go from (-1 ,1) on the X axis, which made me think it was [-1,1] space, but it turns out is not.
My next approach was using the arc length of a semi circle s =r * PI and then plug that value into the equation:
vec2.x = (2.f * (intersectedPoint.x - myCylinder->position().x) ) /
(myCylinder->arcLength()) - 1.f
but clearly it goes off by 1 unit on the negative direction.
I appreciate the help.
From your description, it seems that you want to convert the world space intersection coordinate to its corresponding normalized texture coordinate.
For this you need the Z coordinate as well, as there must be two "horizontal" coordinates. However you don't need the arc length.
Using the relative X and Z coordinates of intersectedPoint, calculate the polar angle using atan2, and divide by PI (the angular range of the semi-circle arc):
vec2.x = atan2(intersectedPoint.z - myCylinder->position().z,
myCylinder->position().x - intersectedPoint.x) / PI;
I need a method to find a set of homogenous transformation matrices that describes the position and orientation in a sphere.
The idea is that I have an object in the center of this sphere which has a radius of dz. Since I know the 3d coordinate of the object I know all the 3d coordinates of the sphere. Is it possible to determine the RPY of any point on the sphere such that the point always points toward the object in the center?
illustration:
At the origo of this sphere we have an object. The radius of the sphere is dz.
The red dot is a point on the sphere, and the vector from this point toward the object/origo.
The position should be relatively easy to extract, as a sphere can be described by a function, but how do I determine the vector, or rotation matrix that points such that it points toward origo.
You could, using the center of the sphere as the origin, compute the unit vector of the line formed by the origin to the point on the edge of the sphere, and then multiply that unit vector by -1 to obtain the vector pointing toward the center of the sphere from the point on the edge of the sphere.
Example:
vec pointToCenter(Point edge, Point origin) {
vec norm = edge - origin;
vec unitVec = norm / vecLength(norm);
return unitVec * -1;
}
Once you have the vector you can convert it to euler angles for the RPY, an example is here
Of the top of my head I would suggest using quaterneons to define the rotation of any point at the origin, relative to the point you want on the surface of the sphere:
Pick the desired point on the sphere's surface, say the north pole for example
Translate that point to the origin (assuming the radius of the sphere is known), using 3D Pythagorus: x_comp^2 + y_comp^2 + z_comp^2 = hypotenuse^2
Create a rotation that points an axis at the original surface point. This will just be a scaled multiple of the x, y and z components making up the hypotenuse. I would just make it into unit components. Capture the resulting axis and rotation in a quaterneon (q, x, y, z), where x, y, z are the components of your axis and q is the rotation about that axis. Hard code q to one. You want to use quaterneons because it will make your resulting rotation matricies easier to work with
Translate the point back to the sphere's surface and negate the values of the components of your axis, to get (q, -x, -y, -z).
This will give you your point on the surface of the sphere, with an axis pointing back to the origin. With the north pole as an example, you would have a quaternion of (1, 0, -1, 0) at point (0, radius_length, 0) on the sphere's surface. See quatrotation.c in my below github repository for the resulting rotation matrix.
I don't have time to write code for this but I wrote a little tutorial with compilable code examples in a github repository a while back, which should get you started:
https://github.com/brownwa/opengl
Do the mat_rotation tutorial first, then do the quatereons one. It's doable in a weekend, a day if you're focused.
If I had the following figure shown below and I wanted to scale the top rectangle by some factor such that the left side will still touch the circle like it does now, how would I go about doing that? This is being done in C++ where the rectangles are represented by four vertices and the circle is represented by a center and radius.
To scale, I simply multiply all the vertices by the scale factor but then I need to translate the rectangle back so it still touches the circle. I'm not sure how to do the translation.
Thanks.
First, find the point at which the circle is touching the rectangle. You can do this by working out the angle of one of the long rectangle edges that is parallel with the line from the center of the circle to the point where it touches the rectangle. Take the x and y values of the far corner and subtract the near corner x and y from them. Then the angle is
angle = atan2(y difference, x difference).
Then use that along with the circle center and circle radius to calculate the point where they touch:
touch.x = center.x + cos(angle) * radius;
touch.y = center.y + sin(angle) * radius;
Then, for each corner point of the rectangle:
Subtract the touch point from the rectangle corner point
Multiply by the scale value
Add the touch point
This scales the rectangle around the touch point, so the touch point is itself unaffected.
How do I get to orbit green circle around orange and blue around green ?
I found many solutions which works fine with rotating around static point(int this case orange circle) but didn't find any good maths equation which would work for both static and moving points.
angle += sunRot;
if(angle > 360.0f)
{
angle = 0.0f;
}
float radian = glm::radians(angle);
float radius = glm::distance(position, rotCenter);
float x = rotCenter.x + (radius * cosf(radian));
float z = rotCenter.z + (radius * sinf(radian));
glm::vec3 newPos = glm::vec3(x, 0, z);
setPosition(newPos);
Here is what I'm trying to achieve (Thanks to #George Profenza for sharing link)
Base all your calculations on the radius and angle of the current object where possible and store the radius and angle with the object.
In particular, do not calculate the radius based on the x/y coordinates in every iteration: If the base object has moved between steps, your calculated radius will be slightly off and the error will accumulate.
You should be able to nest coordinate spaces using opengl using glPushMatrix(), glPopMatrix() calls. Here's a basic example(press mouse to see coordinate spaces).
The syntax isn't c++, but it's easy to see what I mean.
You can do this multiple ways:
polar coordinate formula
manually multiplying transformation matrices
simply using push/pop matrix calls (along with translate/rotate where needed), which does the matrix multiplication for you behind the scenes.
Just in case you want to try the polar coordinate formula:
x = cos(angle) * radius
y = sin(angle) * radius
Where angle is the current rotation of a circle and the radius is it's distance from the centre of rotation.
I'm creating a C++ ifc importer.
I have a direction vector and I want to extrude a section from it. The section itself is a list of 2d points.
To calculate the extrusion direction I have to multiply a non-transformed direction with a transformation matrix.
The matrix has a transformation in x, y, and z (like Euler angles).
I must calculate the rotation angle around the extrude direction.
I have a matrix class that returns the Euler angles from a
matrix:
matrix.ExtractEulerXYZ(x,y,z)
The problem is that I can have a direction vector that has a rotation in x, y or z, how can I select the correct angle x, y, or z from the extrude direction?
A 2d point is at location (x, y) in 2d space and (x, y, 0) in 3d space.
Euler angles in 3d space define 3 rotations from the xyz axes to rotate the xyz axes to the specified point. That is, if you mark a point on the x axis that is the correct distance on the x axis to the point, you rotate the axes by a along the XY plane, b along the ZY plane and c along the ZX plane.
See the animation in the "Relationship with physical motions" section of http://en.wikipedia.org/wiki/Euler_angles -- particularly, follow the progress of the x axis that initially projects toward the bottom left corner.
If you just have a 2d point, the ZY and ZX rotations do not do anything -- you are just rotating around the XY axis. Therefore, you can use simple trigonometry (SOH CAH TOA) to find the angle of the line from the origin to the point; there is no need to use a matrix.