When we rotate any object like Image then its x and y will also change according to the
roation angle.
I just want to know how we can calculate the outer rectangle x and y ( pointed with red
circle in the image ) while rotating the image. We have image width, height and
rotation angle ?
x - your x coordinate
height - height of your image
angle - rotation angle
Then you need (x - height * sin(angle))
One usually uses a Rotation Matrix for such a thing.
In linear algebra, a rotation matrix is a matrix that is used to
perform a rotation in Euclidean space
This web page contains a section on rotation which should be useful to explain the concept.
Related
I'm currently creating a drawing software using WPF Shapes on canvas.
I've created a system allowing the user to move and rotate shapes on a Canvas using a transparent canvas upon the shape (which rotate with the shape) :
The green point is used to rotate the shape, the blue zone upon the rectangle is used to move the shape. I'd like to use my 4 red points to re-size the shape.
But the shape is rotatable, so corners coordinates aren't completely relevant to resize the shape. It seems, in my opinion, to be relevant only if the rotation is equals to 0, because the Left-Top Corner can be the Bottom-Right one after a 180 degree rotation.
Right now I'm using a RotateTransform to achieve the rotation with a 0.5, 0.5 RenderTransformOrigin. I'd like to avoid the use of a ScaleTransform because I want to keep the StrokeThickness at the size it is.
All red dots are pseudo-draggable (using MouseDown, MouseMove, MouseUp events). I use a buffer point which gives me the delta in X and Y between two mouse events.
How can use the deltas to resize the shape, even if it is rotated or moved ?
You can use the deltas to resize the shape if it is rotated. The only thing you have to do is rotating the mousemovement either. As you can see:
The movement of the mouse from origin to location describes a 2-D-vector. You can rotate this vector mathematically by using this formula:
x' = cos(theta) * x - sin(theta) * y
y' = sin(theta) * x + cos(theta) * y
where x/y is the current location of the mouse relative to the origin of the resize and theta the angle of rotation which can be found in the RotateTransform-object (Angle-Property) of the shape. At this point I don't know exactly if you have to use -theta, because the vector has to rotate in the opposite direction.
You can pick x'/y' for calculating the deltas and resize the shape like if it wasn't rotated.
I did not implement this myself. This is just a general idea. Maybe I can serve with a little code if you try this and give feedback or specify the problem more deeply or update your question with some code.
Appendix:
Resizing the shape using the deltas should be easy if you can access the width- and height-property of the shape. You simply add/subtract the x-delta to/from width and/or add/subtract the y-delta to/from height, depending on the grabbed point. This isn't affected by the location of the shape within the canvas.
Maybe you have to adjust the Canvas.Left/Canvas.Top-Property of the shape. I.e. if the user grabs the left upper point and resizes it to left/up, you should subtract the deltas from left and top porperty as well. Otherwise it will expand to right/down.
I have a circle with the up vector direction is Vector(0, -1) and a point, B which could be anywhere on that circle. I know its exact position inside the circle. The (0,0) point is located on the top left of the image.
How can I find the angle x between the point B and the up vector, relative to center of the circle?
I am developing a game in XNA and C#.
Update: I do not understand why this question is marked as not about programming. Anyway here's what I have done so far.
I can find the radian between two vectors
private float radianBetweenVectors(Vector2 a, Vector2 b)
{
return (float)Math.Atan2(b.Y - a.Y, b.X - a.X);
}
But I do not want to know about the location of the up vector on the sprite image if possible. The location here is the point at which it starts at 0 degree on the circle's circumference .
Update 2:
Once I have the angle, I want to obtain the rotation matrix:
Matrix rotMatrix = Matrix.CreateRotationZ(angle);
Now I have this matrix containing the rotation, I can ask XNA to transform the Up vector with this rotation:
moveDirection = Vector2.Transform(up, rotMatrix);
This I hope will take the original up direction, transform it with the rotation around the Z axis. I am still trying to figure out if this is the correct approach.
Find relative x and y coordinates of point B from center of the circle. (You can do this if you know the radius of the circle). If the circle diameter is the width of the sprite, just divide width by two to get radius. Then use arc tangent.
I'll try to help you out since I started XNA when I was relatively young and before I had any experience with vectors and you might be in the same position I was in 5 years ago.
If you don't understand the math behind it, you just treat point B as a point on a triangle that is formed from the 3 lines. I'll use (0,0) as the center of the circle, you can calculate the relative position of the center of the circle from the absolute position given radius. (If you can't do this part, you'll need to pay more attention in math class).
(0,0) to (0, B.y) will be the vertical leg.
(0, B.y) to (B.x, B.y) will be the horizontal leg
(B.x, B.y) to (0,0) will be the hypotenuse.
Then you use tangent with the rule tangent = opposite/adjacent. So you will know the distance of the opposite leg from the angle X is the distance from (0, B.y) to (B.x, B.y), the horizontal leg. The adjacent leg distance is (0,0) to (0, B.y). No need for distance formula, just subtract the coordinates. Now you have the value of tangent and want to find the value of X, so we'll use arctan. Math.Atan2(opposite/adjacent). That will give you your answer in radians.
Edit: Oh and I remember you can draw the sprite so the center of the sprite will be rendered at the center of the sprite bitmap using the origin argument of draw. That way you don't have to worry about calcuating the center of the circle.
Speaking mathematically, if you have two vectors, lets supose A(0, -1) and B(222, 90) the angle X between the two vectors can be computed as cos(X)=(A.B)/(||A||.||B||).
A x B = (a1 x b1) + (a2 x b2) = 0x222 + (-1x90) = 0 - 90 = -90.
2.I. ||A|| = squareroot[0^2+(-1)^2] = sqrt[(-1)^2] = 1
2.II. ||B|| = squareroot[222^2+90^2] = sqrt(57384) ~= 239.55 (~= is approximately)
2.III. ||A||.||B|| = 1 x 239.55 ~= 239.55
Result: cos(X) ~= (-90)/(239.55) ~= X ~= cos^-1(X) ~= 1.955 radian.
For the vectors you gave above, the angle you looking for is approximately 1.955 radian.
Note: using a calculator, you will obtain the exact value, which is very close to the aproximate value.
I am drawing a rectangle with primitives in XNA. The width is:
width = GraphicsDevice.Viewport.Width
and the height is
height = GraphicsDevice.Viewport.Height
I am trying to fit this rectangle in the screen (using different screens and devices) but I am not sure where to put the camera on the Z-axis. Sometimes the camera is too close and sometimes to far.
This is what I am using to get the camera distance:
//Height of piramid
float alpha = 0;
float beta = 0;
float gamma = 0;
alpha = (float)Math.Sqrt((width / 2 * width/2) + (height / 2 * height / 2));
beta = height / ((float)Math.Cos(MathHelper.ToRadians(67.5f)) * 2);
gamma = (float)Math.Sqrt(beta*beta - alpha*alpha);
position = new Vector3(0, 0, gamma);
Any idea where to put the camera on the Z-axis?
The trick to doing this is to draw the rectangle directly in raster space. This is the space that the GPU works in when actually rendering stuff.
Normally your model starts in its own model space, you apply a world transform to get it into world space. You then apply a view transform to move the points in the world around the camera (to get the effect of the camera moving around the world). Then you apply a projection matrix to get all those points into the space that the GPU uses for drawing.
It just so happens that this space is always - no matter the screen size - from (-1,-1) in the bottom left corner of the viewport, to (1,1) in the top right (and from 0 to 1 on the Z axis for depth).
So the trick is to set all your matrices (world, view, project) to Matrix.Identity, and then draw a rectangle from (-1,-1,0) to (1,1,0). You probably also want to set DepthStencilState.None so that it doesn't affect the depth buffer.
An alternative method is to just use SpriteBatch and draw to a rectangle that is the same size as the Viewport.
Is there a code formula for this? I am using C# and XNA, and in my class I have an array of three vectors (representing the vertices of the triangle), as well as a separate vector coordinate.
I plan to update these positions in the loop as it escalates further towards the top of the screen.
I'd ask maths.stackexchange.com, but seeing as how this applies to programming (and I personally am better at reading code as opposed to math itself - I'm still taking Algebra in school), I think it would make more sense for me to ask it here.
Edit
Yes, I am looking for an equilateral triangle. Or any triangle, for that matter. It doesn't matter what it is. All I am looking for is a formula; is that so hard to ask for?
Teh Problem
Basically, the problem I am trying to solve is to shoot a triangle out of my player (think Space Invaders; i.e., the triangle acts as a ray from the ray gun). What I need is a formula of code which will allow the triangle to be rendered based on its center position and radius, as the triangle will move upwards on its Y coordinate. I have the draw calls, and they work, but the problem is that the triangle when put in a for loop draw iteration (where the center vector position - on the Y coordinate - is incremented by N) simply sits next to the player's position when being drawn.
I think this is what you are looking for...
the angle is the orientation of the triangle...
this build a triangle....
void BuildTriangle(Vector2 Center, float Radius, float Angle, Vector2[] tri)
{
for (int i=0; i<3; i++)
{
t[i].X = Center.X + Radius * (float) Math.Cos(Angle + i * 2 * MathHelper.PI/3);
t[i].Y = Center.Y + Radius * (float) Math.Sin(Angle + i * 2 * MathHelper.PI/3);
}
}
if you want to move it, add to the center a velocity vector and rebuild it...
If I have a Rectangle class in C# how can I get a rectangle which encompasses it when it's rotated?
Basically I want to find the rectangle for a rotated rectangle.
I'm curious how do you keep your Rectangle as a data structure, I mean, a rectangle is 2D and XNA makes me think about 3D.
However, even in 2D and 3D, i think what you want is called AABB (axis aligned bounding box), which is very easy to find because it is defined by the two points formed by the minimums and, respective, maximums on each axis of each point of the original rectangle transformed with your rotation.
LATER EDIT:
For a Rectangle structure that contains X, Y, Width and Height, the rectangle has this two points:
(x1, y1) = (X, Y) and
(x2, y2) = (X + Width, Y + Width).
When you rotate the rectangle, you practically rotate this two points and obtain:
(xr1, yr1) = rotate(x1, y1)
(xr2, yr2) = rotate(x2, y2).
Now, the rectangle you want is defined by the points of these coordinates:
p1 = new Point(Min(xr1, xr2), Min(yr1, yr2))
p2 = new Point(Max(xr1, xr2), Max(yr1, yr2))
rotate is the method that rotates your rectangle by an angle around a certain point.
How are you rotating the rectangle to start with? to get the bounding box you need to look at the four resulting points and find the min and max for Y and X,