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.
Related
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.
I am using the Farseer Physics library with MonoGame.
In my game I use compound polygon bodies, created with BodyFactory.CreateCompoundPolygon(...);, but they have problem.
Their origin is in the top left corner, rather then the centroid like most Box2d objects. Since I need to rotate the bodies around a different pivot point than the top left, I found I can change the center of mass of a body (Body.LocalCenter). This works fine and dandy, and I can rotate the body using Body.ApplyAngularImpulse(...); or by changing Body.AngularVelocity, but here comes the problem:
Changing the rotation of the body using the methods I mentioned before works fine, and the pivot point used is the center of mass, but if I try to rotate the body by directly changing it's rotation (Body.Rotation), it rotates around the top left corner rather than the center of mass.
So in effect, Body.Rotation += 1; rotates around a different pivot point than with Body.AngularVelocity = 1;
You might be wondering why this is a problem, why I don't just use the methods I mentioned before to rotate the body. The problem is I need to be able to check the current rotation of the body. I can't figure out a way to do this. I can't use Body.Rotation since it returns the rotation around a wrong point.
TL;DR: Body.Rotation doesn't return rotation around center of mass, how to combat this?
You can have the pivot and mass center correctly set if you create your compound polygon from a list of points relative to the center.
For a 20 units side square :
instead of : [0,0][20,0][20,20][-20,20]
use : [-10,-10][10,-10][10,10][-10,10]
This is something i've struggled with all week. I'm working on a 2D project, and what I want is for my enemies to move from the right to the left hand side of the screen (landscape). I'm moving them like this:
transform.Translate (new Vector3(1,0,0) * speed * Time.deltaTime);
At the same time, I want them to constantly rotate on a pivot in the middle of the sprite. As an example, imagine they are in space and are sort of floating uncontrollably, they would spin. I've asked this question a couple of times with no response so I guess my explanation isn't really very good. This is what I've tried:
Animating the objects. This didn't work because changing the Z rotation caused the sprites to spin in a tornado but not from one side of the screen to the other
This: transform.Rotate (0,0,50*Time.deltaTime); I messed around with the X,Y and Z properties but they pretty much all made a tornado type effect or rotated in 3d so disappeared when at 180 degrees.
I also imported a spritesheet where they are at different points in the "spin" so say at 10,20,30...360 degrees etc. but this wans't smooth at all
I hope this makes sense. I've spend quite a few hours on it now!! I can't get my head around it as I've moved from Xcode where this sort of stuff is 1 line of code. A point in the right direction would be amazing.
Note: if my question makes no sense please ask!
have you tried transform.rotation = Quaternion.lerp() ? I used this myself to rotate an object using an input though you could use it to do a random rotation on the z plane easily enough
I'm asking a question that has been asked a million times before, but I still haven't found a good answer after going through these and also resorting to other sites:
How to rotate a graphic over global axes, and not to local axes?
rotating objects in opengl
How to rotate vertices exactly like with glRotatef() in OpenGL?
Rotate object about 3 axes in OpenGL
Rotate an object on its own axes in OpenGL
Is it possible to rotate an object around its own axis and not around the base coordinate's axis?
OpenGL Rotation - Local vs Global Axes
Task is relatively simple, I am making an sensor module with accelerometer and gyro onboard, and I need to display rotation.
I have a 3D model of the object in STL format, I've made an STL parser and I can visualise the object perfectly well.
When I try to rotate it I get all kinds of strange results.
I am using SharpGL (the Scene component).
I tried to write an "effect" that (for now) is controlled with 3 separate trackbars, but this will be the data from the sensors.
I wanted to do it as an effect because (in theory) I could have more objects in the scene and I only need to rotate a specific one (and also for educational purposes as I am relatively new to OpenGL).
I tried to rotate the object using quaternions, multiplying them and generating a rotation matrix, then applying gl.MultMatrix(transformMatrix.AsColumnMajorArray).
I also tried gl.Rotate(angleX, 1, 0, 0) (and similar for Y and Z axes).
Depending on the order of quaternion multiplication or gl.Rotate(...) statements, I would get the object to rotate about the local axis (first), something weird (second), and the "world" third. For example, if I did it with quaternions qX*qY*qZ and got the rotation matrix from that, I would get (I think) the rotations about a local X, "arbitrary" Y, and the world Z axes.
The part I cannot understand is that when I apply gl.Rotate(dx, 1, 0, 0) (and others for Y and Z rotations) inside the trackbar's Scroll event, the entire scene rotates about the X, Y, and Z axes and in that order, and exactly as I expected the rotation to happen.
My only issue with this approach is that the entire scene rotates. So if I (hypothetically) wanted to draw a room around the object, the whole room would rotate too, which is not what I want.
I will post any code requested, but I feel there is too much and the aforementioned links have similar code to what I have.
At the end of the day, I want my object (Polygon in SharpGL terms) to rotate about its own axes (or about the "world" axes, but be consistent).
EDIT:
I've placed the project in my dropbox: https://goo.gl/1LzNhn
If someone wants to look at it, any help will be greatly appreciated.
In the MainForm, the TbRotXYZScroll function has trackbar code and the Rotation class is where the problem resides (or so I think).
Rotate X, Y, and Z by say 45 degrees in that order. All seems to work great. Now rotate X, Y, and Z further by another 30 or so degrees, try to visualise about which axis the rotation is happening as you rotate...
X seems to be always world and Z seems to be always local, while Y is something in between (changing the order of rotation changes this).
Going into TbRotXYZScroll function and changing method to 2 does what I want (except the rotation of the entire scene). Tried quaternions and they produce the exact same result, so I must be doing something wrong...
Changing it to 1 produces similar result, but that is applying the rotation to the polygons alone (not what's being rendered as that includes local coordinate axes too).
At the end of the day, I want my object (Polygon in SharpGL terms) to
rotate about its own axes (or about the "world" axes, but be
consistent).
I think this answer you put in your question is somehow explaining the situation. In order to perform rotation around object axis:
1. Perform Translation/Rotation to your object and make the object axis overlap with one of base axis (x,y or z)
2. Perform your rotation
3. Revert your object back to its original position. (simply revert the translation/rotations at step1)
Note: While doing that, one thing you should consider is openGL apply transformations from the reverse order.
Example :
glRotatef(90,1,0,0);
glTranslatef(-5,-10,5);
drawMyObject();
In this case, opengl will first translate your object and then rotate. So while writing your transformations consider that. Here is my answer that may give you an idea.
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?