Not logged in, Join Here! or Log In Below:  
News Articles Search    

 Home / 3D Theory & Graphics / rotating question Account Manager
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.

March 23, 2005, 03:39 PM


I am trying to rotate points around an edge of a 3d mesh.
I add new points around existing points on the mesh. It can be that the newly added point is not in the face of an existing point. So i search the most nearby edge to this new point. I look up the adjacent face. I rotate that new point around this common edge. The rotation angle is the acos of the dotproduct between the two normals. But sometimes it rotates to the wrong direction.
How can that be and how can you solve something like this?
For Example: We are at the top of a box. So the new point has to rotate downwards but it rotates it up in the sky :)


March 23, 2005, 04:01 PM

I am not sure I got your strategy on how to rotate. Basically you find the best rotation axis (a vector) and then you rotate around it due to a given angle. If this is right and your rotation only has the wrong direction then your rotation axis only point 180 degree to the wrong direction. Probably a wrong order in witch you multiply. If you use the neighbour faces then the order in witch they are found might not always be the same so it only screws up in some cases.

However this sounds almost too obvious to be the case. Maybe you need to be more specific about how you rotate.


March 23, 2005, 04:22 PM

Could it be that some normals point inside the object instead of outside the object?

this is how i calculate the normals.

  2. void Mesh::calculateNormals()
  3. {
  4.         m_faceNormals.reserve(m_faces.size());
  6.         for(std::vector<Vertex>::const_iterator vIt=m_vertices.begin(); vIt!=m_vertices.end(); ++vIt)
  7.                 m_vertexNormals.push_back(Vector3D(0,0,0));
  9.         for(int i=0; i<m_faces.size(); ++i)
  10.         {
  11.                 Vertex v0=getVertex(m_faces[i].getVertex(0)),
  12.                            v1=getVertex(m_faces[i].getVertex(1)),
  13.                            v2=getVertex(m_faces[i].getVertex(2));
  15.                 Vector3D p0=v1.getPosition()-v0.getPosition(),
  16.                                  p1=v2.getPosition()-v0.getPosition();
  18.                 Vector3D normal;
  19.                 normal.crossProduct(p0, p1);
  20.                 normal.normalize();
  22.                 // face normal
  23.                 m_faces[i].setNormal(i);
  24.                 m_faceNormals.push_back(normal);
  26.         }
  27.         m_bNormalsUpTodate=true;
  28. }

And this is how i rotate around an edge.
  2. void Vector3D::rotateAroundAxis(const Vector3D& p, const Vector3D& axis, float a)
  3. {
  4.         // axis is normalised
  5.         float s=sinf(a);
  6.     float c=cosf(a);
  8.         Vector3D vpar=axis*dotProduct(p,axis);
  9.         Vector3D vprp=p-vpar;
  10.         Vector3D vcrs;
  11.         vcrs.crossProduct(axis,p);
  13.         m_values[0]=vpar[0]+c*vprp[0]+s*vcrs[0];
  14.         m_values[1]=vpar[1]+c*vprp[1]+s*vcrs[1];
  15.         m_values[2]=vpar[2]+c*vprp[2]+s*vcrs[2];
  16. }
  18. void Vector3D::rotateAroundLine(const Vector3D& p, const Vector3D& p0, const Vector3D& p1, float a)
  19. {
  20.         Vector3D axis=p1-p0;
  21.         axis.normalize();
  23.         rotateAroundAxis(p-p0,axis,a);
  25.         m_values[0]+=p0[0];
  26.         m_values[1]+=p0[1];
  27.         m_values[2]+=p0[2];
  28. }


March 24, 2005, 02:20 PM

Could it be that some normals point inside the object instead of outside the object?

If you want to check for it then you can look at your model in a simple model viewer. Just enable flat shading and backface culling. In case your mesh shows some holes it indicates this triangle has the wrong order (clock wise instead of counter clock wise orientation). If thatís the case, your normal will be pointing into the wrong direction.

The way you compute the normals seams ok to me. Couldnít quite spot a bug in your rotation code eitherÖ sorry itís not much of help.

Maybe some thoughts will help you in spite of this.

Say you have something like:
Vector3D pointToRotate;
Vector3D pointLineStart;
Vector3D pointLineEnd;
Float fAngle;

Then you could do:
rotateAroundLine(pointToRotate, pointLineStart, pointLineEnd, fAngle);
or you could do:
rotateAroundLine(pointToRotate, pointLineEnd, pointLineStart, fAngle);

So if your pointLineStart and pointLineEnd represent the edge of a face you can create a vector in two different directions. Thatís also what I meant in my previous post.

I donít really see what you need the normals for when you are rotating. I assume you pass the normals as pointLineStart and pointLineEnd also it doesnít really make sense because you handle it as start and end points of a line but a normal represents a vector (direction) not a point.

It seams you are not using a gfx library. Are you building a software rasterizer?

However it might help if I mention a strategy I would use witch would take advantage of direct 3D:
  2. Void RotateAroundAxis( D3DXVECTOR3* vPoint, const D3DXVECTOR3* axis, float fAngle)
  3. {
  4.     D3DXMATRIX matRotation;
  5.     D3DXMatrixRotationAxis( &matRotation, axis, fAngle);
  6.     D3DXVec3TransformCoord( vPoint, vPoint, &matRotation);
  8.     return;
  9. }

This would update your vPoint position due to the rotation. I havenít checked/tested it but it should be ok.

Note that it rotates in world space. So if you have some matrices representing the position and orientation of a mesh, you need to take it into account before rotating around an axis.

Hope it helps.

This thread contains 4 messages.
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.