Rotating a full 360 degrees in WPF 3D - c#

I have a ModelVisual3D of a cube and I want to animate it to rotate around its axis for 360 degrees. I make a RoationTransform3D which I tell to rotate 360 but it doesn't rotate at all, also if you say 270 degrees it rotates only 90 degrees but in the opposite direction. I guess he computer calculates the "shortest path" of the rotation. The best solution I have come up with is to make one animation turn 180 and after it finishes call another 180 to complete the full rotation. Is there a way to do it in one animation?
RotateTransform3D rotateTransform = new RotateTransform3D();
myCube.Model.Transform = rotateTransform;
AxisAngleRotation3D rotateAxis =
new AxisAngleRotation3D(new Vector3D(0, 1, 0), 180/*or 360*/);
Rotation3DAnimation rotateAnimation =
new Rotation3DAnimation(rotateAxis, TimeSpan.FromSeconds(2));
rotateTransform.BeginAnimation(RotateTransform3D.RotationProperty,
rotateAnimation);

My understanding is that the Rotation3DAnimation uses a Spherical Linear interpolation, so it will always find the shortest path.
One workaround is to use Rotation3DAnimationUsingKeyFrames: setup a key frame at 120, 240, and 360 and you should be good.
Sorry no code right now, I don't have WPF on this machine...
-Jason

I know this was already answered but in my search for a better way to do this I found this alternative:
You can set the rotation value to 180 (or half of what you want to rotate) and then set the repeat behavior to repeat twice and "IsCummulative" to true.

Related

Creating turning animation for up and down or rubiks cube

im creating a rubiks cube solver and simulator for my a level project and i have come across the problem of the top face of the cube not rotating properly. After a few tests of it i have come to the conclusion that the top face is rotating around the axis properly but in order for it to stay in line witht eh rest of the cube i also need to update the other axis. This is my code to rotate the face
for (int i = 0; i < 90 * n; i++)
{
cube[0].rotateY(degree); // degree is defined as Math.PI / 180 as its in radians
cube[3].rotateY(degree);
cube[6].rotateY(degree);
cube[9].rotateY(degree);
cube[12].rotateY(degree);
cube[14].rotateY(degree);
cube[17].rotateY(degree);
cube[20].rotateY(degree);
cube[23].rotateY(degree);
Invalidate();
}
I have tried also rotating the left and right side and they both work correctly while using the same function but for the other axis. i have definitions for the entire cubes rotation stored in rotation with x y and z properties. Initially i thought this wouldnt be a very hard fix so as well as rotating each cube on the y axis i rotated them along the x axis but for -rotation.x * 2 in order to counteract the problem however this didnt work and just transformed it into very weird positions. Im sure its just a simple maths expresion that i need to rotate it by but i cant work it out.
As i found it hard to explain my problem ive created this video to show it visually. You can see that the left and right rotations work although they are not yet animated and the top face rotates round and always snaps back into the original position but not the other 4 correctly. I am also aware that the colours dont come round the cube like they should but this is something i will work on once all the rotations work
Video of current coded soloution
the functions for the rotations simply update the rotation variable and redraws the cube and all the different cube's in the array are just there as i have created 26 smaller cubes to create 1 bigger cube so that rotations can work without just changing the colour.
If anyone has a nice maths equation to rotate this correctly that would be great but if not and you have another way of rotating the cubes in the cube then that would also be great.
Also just a side quest if anyone knows why my code doesnt rotate the side by 1 degree and then redraw it again inside the Invalidate command then id love to hear why.
Many thanks in advance.

How can we calculate Rotation3D Axis (Vector3D) by Line angle in 2D

I have some shapes in the 2D and also I have 3D models created exactly by 2D Shapes that I have , Now I want to rotate my 3d models by bottom line of them and I'm usinf from RotateTransform3D and also AxisAngleRotation3D , So I need Angle,CenterPoint and Vector3D of Axis x,y,z.
Angle to rotate model to up is always 90 degrees.
Also I can calculate angle of each line that I want to rotate 3d model by that line ( Red Lines in the example picture) and center point by 2d but my question is how can I calculate Axis to say it should rotate by which axis(or axises).
var myRotateTransform = new RotateTransform3D(
new AxisAngleRotation3D(
new Vector3D(?, ?, ?), angle),
new Point3D(getCenter.X, getCenter.Y, getCenter.Z));
Also in the picture I attached it here you can see and example to understand it better.
Example
I believe for 0 degree Vector3D must be (-1,0,0) or for 180 degree Vector3D must be (1,0,0), but how can I calculate it automatically?
If you want to rotate the object around the red lines, you need to calculate the direction of the line. I.e. calculate end - start. This direction can then be used as the rotation-axis. You might also want to use a point on said line as the rotation-center since this will make the rotation work similar to a hinge.
You do not specify how you are describing the lines, so it is difficult to provide more specific instructions.

Problems using camera in OpenGL

Hi, I am making an application which can make camera rotate around the model, I have successfully imported the obj format model
But I meet the problem when rotate the camera, the model will disappear as you can see
gl.Perspective(180, (double)Width / (double)Height, 100, 50000f);
The key code for rotating camera:
Calculate the center point of the model
currentX = Math.Sin(angle) * radius;
currentZ = Math.Cos(angle) * radius;
gl.LookAt(currentX,0,currentZ,
centerPoint.X, centerPoint.Y, centerPoint.Z,
0, 1, 0
);
Try modifying the near clipping plane to be much closer to the camera, and also lower the FoV angle. Try this:
gl.Perspective(90, (double)Width/(double)Height, 0.01f, 100.0f);
Check if the model is not closer than the near clipping plane. Check also the face culling: if your camera is inside the mesh, you are looking at the back faces of the polygons, which probably are not rendered.

(Unity) Issue with rotation when transform.up is aligning to a direction

I am testing out some ideas in Unity where a player can walk around a circle while staying on it (so the circle has its own gravity) and also being oriented properly. This game is currently being done in 2D, so all objects are sprites.
I do hope I can explain myself properly. Please ask if you need any further clarification...
It appeared that I succeeded with my idea until I noticed something odd.
So as expected, the player moves around the circle without falling off (custom gravity worked just fine) and its Z rotation is affected as it aligns itself with a direction:
// Align code:
// We reverse the direction so the object is standing up the right way.
private void Update()
{
transform.up = -(planet.position - transform.position);
}
It works... mostly. However, when the player object's rotation Z naturally reaches 180, it appears to flip horizontally (like a mirror effect) and then it returns to normal as rotation Z leaves 180. The visual flip happens because for some reason the object's Y becomes 180 at the same time too. At no other point does X or Y change in regards to rotation. Only Z. So the moment Z hits 180, Y is affected and the moment we leave Z 180, Y returns to 0.
I'm happy to provide a quick video of it happening in-game if anybody needs some visual understanding of what's going on.
The visibility of this bug tends to rely on how fast you're moving around the circle. If you're moving fast enough, you can probably skip over 180 and not see it happen at all, however if you move slow enough there's no denying it's there. It's also problematic for the fact that I simply make the camera a child of the player so when the player flips, so does the camera causing the entire scene to flip which can look extremely glitchy for a player to see.
I really have no idea how to tackle this issue as I have no clue why it would do such a thing. At every other rotation value it behaves just fine. It's only at Z = 180 (so the object is exactly upside down) does it decide to rotate in the wrong ways.
EDIT: Changed tag to Unity3D
It's probably because of converting quaternions (which is what's actually used internally for rotations) to euler angles for display. Can you try to use Quaternion.Slerp to rotate?

Tracking Rotating Sprite

I am messing about in XNA and have run into a problem. I have a 48 * 48 sprite that I can keep track of its location in the game world by the top left corner of the sprite.
I want to be able to rotate the square and still keep track of the same point. For instance if I rotate 90degrees clockwise and the orginal X position was 200 the new X position should be 200 + 48(the size of the width of the image). Its fine for 90 degrees I am able to work that out in my head but each one in between is the problem!
I know there is probably some kind of formula to work this out.
Any help would be great! Oh the square is rotating on its center.
I'm just using spriteBatch.Draw()
spriteBatch.Draw( animations[currentAnimation].Texture,
Camera.WorldToScreen(WorldRectangle),
animations[currentAnimation].FrameRectangle,
color, rotationScale , new Vector2((float)frameHeight/2, (float)frameWidth/2), effect, TileMap.characterDepth);
If you have to keep track of a moving rotating sprite you can't use the top left corner, but its centroid. You already draw your sprite using the centroid to rotate it.
The problem is that the second parameter of your Draw call is a Rectangle, you sholud use a Vector2 position, instead.
You're building your application on top of a 3D graphics library. 3D graphics libraries are very good at solving this kind of problem! Break it down into smaller operations and let the library do the work for you.
First: it's easiest to think about these kinds of questions when you're working in model space rather than world space. In other words: you don't need to worry about where the rotating point is in absolute terms, you only need to worry about where it is relative to the untransformed model (in this case, your sprite without any rotation or translation).
So where is that? Simple:
var pt = new Vector3(-frameWidth / 2f, -frameHeight / 2f, 0f);
Your point of origin is the center of your sprite, so the center of your sprite in model space is (0, 0). This means that the top left corner of your sprite is half the width of the sprite in the negative x direction, and half the height of the sprite along the negative y direction.
Now create an object that represents the desired transformation. You can do this by creating a rotation matrix using XNA's built-in methods:
var transformation = Matrix.CreateRotationZ(MathHelper.ToRadians(90f));
Now apply the transformation to your original point:
var transformedPt = Vector3.Transform(pt, transformation);
This is still in model space, remember, so to get world coordinates you'll need to transform it into world space:
var transformedWorldX = transformedPt.X + spritePosition.X;
var transformedWorldY = transformedPt.Y + spritePosition.Y;
And there you go.

Categories