I am using camera to trace one black marker on blue ball as shown in image below.
I can detect marker position on top of ball image reliably but would need to know
how to calculate ball rotation angles based on marker location.
When marker is in the middle as shown both angles should be 0 degrees. When marker is only half visible at left edge as shown horizontal angle should be -90 degrees. I understand calculating angles from 2D-image is non-linear, near the edge similar movement in pixels means bigger change in rotation than in the middle but I just can't come up with the formula.
Rotation about vertical axis:
Phi = ArcSin((Marker.X - Center.X) / Radius)
In general, if you grab initial point with 2D coordinates (x0, y0) at the front surface of ball manipulator with radius 1 and drag it ti end point (x1,y1), then you rotate direction vector
d0 = (x0, y0, Sqrt(1 - x0^2 - y0^2))
to
d1 = (x1, y1, Sqrt(1 - x1^2 - y1^2))
What to do with these vectors? I depends on what approach are you going to use for rotation
Related
I am currently working on raytracing. I have problem with view Ray collisions. I cant figure out how to get intersection point of ray and plane, to be more precise, my problem is not figure out intersection point of ray vs plane, problem is to convert this coordinate into uv coordinate(this rectangle can be rotated anyhow in world) for texture mapping. I know One point on this rectangle, its normal and bounds.
We have 4 vertices of a rectangle lying on a sphere:
A - top left
B - top right
C - bottom right
D - bottom left
Center of the sphere:
O
And intersection point on the sphere inside rectangle ABCD:
I
The idea is to identify all sides of the triangle AID, because it will allow us to know the coordinates of the point I on the plane. So if we move the rectangle on the plane with A(0, rect.height) and D(0, 0) then point I could be found by solving the following system of equations:
x^2+y^2=DI^2 - circle equation with center in point D and radius DI
x^2+(y-rect.height)^2=AI^2 - circle equation with center in point A and radius AI
from which it follows that:
y = (DI^2-AI^2+rect.height) / (2*rect.height)
and x could have 2 values (positive and negative), however we are interested only in positive value, because only it will be inside the rect.
x = sqrt(DI^2-(DI^2-AI^2+rect.height)/(2*rect.height))
Then UV could be calculated the following way uv(x/rect.width, y/rect.height)
However length of AI and DI still not known, but could be calculated using formula of Great-circle distance
AI = (Radius of the Sphere) * (Angular orthodromy length must be in radians)
Radius of the Sphere = sqrt((O.x - A.x)^2+(O.y - A.y)^2+(O.z - A.z)^2)
Angular orthodromy length = arccos(sin(a1)*sin(a2)+cos(a1)*cos(a2)*cos(b2-b1))
a1 is angle AOA1, where A1(A.x, O.y, A.z)
b1 is angle O1OA1, where O1(O.x, O.y, A.z)
a2 is angle IOI1, where I1(I1.x, O.y, I.z)
b2 is angle O2OI1, where O2(O.x, O.y, I.z)
I have two rectangles: red and green. For each of them, I have the following information:
Center point (x and y coords).
Rotation angle
Width and height
The rectangles will always be moving in positive coordinates. Edit: No coordinate can ever be negative: the rectangles are always located in positive coordinates. Therefore, the center will never be (0,0).
Problem
I have an starting position. To simplify the example, let's say that my red and green rectangles are located as follows:
Now, I rotate the red rectangle using an angle phi which goes between 0º and 90º. However, the green rectangles needs to rotate and keep its position regarding the red rectangle. The green rectangle is not only rotating but also moving.
Let see an image (please excuse the sketch-quality):
My Question:
How can I obtain the new center coords for the green rectangle?
Rotation is about some point (rx, ry).
Edit: As comment says, rotation center (rx, ry) is red center. Formula remains the same.
If green center was at (gx, gy), then after rotation it has coordinates
gx' = rx + (gx - rx) * Cos(Phi) - (gy - ry) * Sin(Phi)
gy' = ry + (gx - rx) * Sin(Phi) + (gy - ry) * Cos(Phi)
I am developing a pool game , use box2d.
I have know the move vector(vtX,vtY) of ball, how to compute the rotation(x,y) when ball is moving.
The ball is 3D sphere, i need the rotations to rotate the ball when it is moving.
ps: in my case, i cant use the 3d physics engine.
You can express the resulting rotation as a combination of a rotation axis and an angle. I highly advise against using Euler angles as this will result in very complicated expressions if done correctly.
If your ball moves by distance (dx, dy), the rotation axis is normalize(cross(up, (dy, dy))), where up is the up-direction. Assuming that this is the z-axis, you get
axis = normalize(-dy, dx, 0)
And the angle is
angle = length(dx, dy) / r,
where r is the ball's radius and length(dx, dy) = sqrt(dx * dx + dy * dy). The angle will be in radians.
I'm not really sure how to phrase this question.
I'm looking for a way to calculate the new X/Y/Z point on the surface of a sphere(which has a known radius) from an known X/Y/Z point where the Y has been increased irrelevantly to the sphere. If I can get the radius of the plane of this Y within the sphere then this would be enough but I'm having a hard time visualizing this.
The closer the Y is to the top of the sphere, the greater the change in the radius. But I'm unsure how to calculate the radius of this circle on the plane within the sphere based only on the radius of the sphere and the height increased from the center.
In this image, if the bottom green slab is at Y=0; and the second is at Y=5 and the radius of the sphere is 10, what's the radius of the circle where the top green slab intercepts the circle.
If your sphere is centered on the origin, you can calculate the planar circle radius at offset y=b by considering the circle at the intersection of the xy plane at the origin. This gives you a circle of radius r. The point (a, b) lying on this circle indicates |a| will be the radius of the intersected circle you want. Using the triangle formed between the x axis and the line between the origin and (a,b), we know that a = r*cos(arcsin(b / r)).
I have a unit sphere (radius 1) that is drawn centred in orthogonal projection.
The sphere may rotate freely.
How can I determine the point on the sphere that the user clicks on?
Given:
the height and width of the monitor
the radius of the projected circle, in pixels
the coordinates of the point the user clicked on
And assuming that the top-left corner is (0,0), the x value increases as you travel to the right, and the y value increases as you travel down.
Translate the user's click point into the coordinate space of the globe.
userPoint.x -= monitor.width/2
userPoint.y -= monitor.height/2
userPoint.x /= circleRadius
userPoint.y /= circleRadius
Find the z coordinate of the point of intersection.
//solve for z
//x^2 + y^2 + z^2 = 1
//we know x and y, from userPoint
//z^2 = 1 - x^2 - y^2
x = userPoint.x
y = userPoint.y
if (x^2 + y^2 > 1){
//user clicked outside of sphere. flip out
return -1;
}
//The negative sqrt is closer to the screen than the positive one, so we prefer that.
z = -sqrt(1 - x^2 - y^2);
Now that you know the (x,y,z) point of intersection, you can find the lattitude and longitude.
Assuming that the center of the globe facing the user is 0E 0N,
longitude = 90 + toDegrees(atan2(z, x));
lattitude = toDegrees(atan2(y, sqrt(x^2 + z^2)))
If the sphere is rotated so that the 0E meridian is not directly facing the viewer, subtract the angle of rotation from the longitude.
One possible approach is to generate the sphere from triangles, consisting of rows and columns. They can be invisible too. And then hit-testing those triangles with a mouse pick ray.
See this picture's latitude/longitude grid, but apply it much denser. For each grid cell, you need 2 triangles.