Polygon Position

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 23/02/2010 at 02:54, xxxxxxxx wrote:

I want to move one object and have it sit on the polygon of another object and have it rotate to the normal of that polygon so that the object is sitting flush with that polygon.   SO I will need the center between all of the points of that polygon (which I have) and a point in space that points directly outward from that polygon?  There is no function in the sdk that provides the normal of a polygon?

so the vector from the center to the first point would create a plane upon which I could determine rotation?

how would I get that?

Here's how I determine the center of the polygon

  
                          //Caclulate the polygon position.  
                          if (selectedPoly[lngI].c == selectedPoly[lngI].d)   
                          {  
                              polyLocation = (points[lngA] + points[lngB] + points[lngC]) / 3; //Polygon is a Triangle  
                                
                          }  
                          else  
                          {  
                              polyLocation = (points[lngA] + points[lngB] + points[lngC] + points[lngD]) / 4; //Polygon is not a Triangle  
                          }  
  

how would I set up the rotation matrix with this info if points[lngA]  is the first point of the polygon?

Thanks,

~SHawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 23/02/2010 at 15:44, xxxxxxxx wrote:

Okay so I want to set up a rotation matrix for the selected polygon.  do I do this by mulitplying the vector of one point by the vector of a second point in the polygon?

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 23/02/2010 at 15:49, xxxxxxxx wrote:

Here's what I have so far......

  
  
C4DObjectList * objList = C4DObjectList::Alloc();   
  if (!objList) return FALSE;  
    
  //DECLARATIONS & DEFINITIONS  
  if (!doc) return FALSE;  
  
  BaseObject *op = doc->GetActiveObject();  
  if(!op) return TRUE;  
  
  PolygonObject *objPoly = ToPoly(op);  
  if (!objPoly) return FALSE;  
  
  BaseSelect *bsPoly = objPoly->GetPolygonS();  
  BaseSelect *bsPoint = objPoly->GetPointS();  
  BaseSelect *bsEdge = objPoly->GetEdgeS();  
     
  Real dx, dy, len = data.GetReal(1, 0.0);  
  BaseContainer device;  
  Real mousex = msg.GetLong(BFM_INPUT_X);  
  Real mousey = msg.GetLong(BFM_INPUT_Y);  
  win->MouseDragStart(KEY_MLEFT, mousex, mousey, MOUSEDRAG_NOMOVE);  
  
  
  LONG lngRad = 1;  //MAXIMUM SELECTION RADIUS  
  LONG lngEditorMode = doc->GetMode();  
  
  AutoAlloc<ViewportSelect> vps;  
  if(!vps) return FALSE;  
  
  LONG left, top, right, bottom, width, height;  
  bd->GetFrame(&left, &top, &right, &bottom);  
  width = right - left + 1;  
  height = bottom - top + 1;  
  
  if(!vps->Init(width, height, bd, op, doc->GetMode(), TRUE, VIEWPORT_IGNORE_HIDDEN_SEL)) return FALSE;  
  
  LONG lngX = mousex;  
  LONG lngY = mousey;  
  
  
  //DRAW CIRCLE TO SHOW HOTSPOT  
  
  vps->SetBrushRadius(data.GetLong(SELECTION_RADIUS)); //SET BRUSH RADIUS  
  
  while (win->MouseDrag(&dx, &dy, &device) == MOUSEDRAG_CONTINUE)  
   {  
        if (dx == 0 && dy == 0)  
        continue;  
  
        lngX += dx;  
        lngY += dy;  
  
        DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);  
        vps->ShowHotspot(win, lngX, lngY);  
   }  
  
   vps->ShowHotspot(win, lngX, lngY);  
  
  //SELECT THE POLYGON THAT IS CLICKED  
    
  BaseContainer state;  
  LONG lngKey = state.GetLong(BFM_INPUT_QUALIFIER);  
  ViewportPixel *vpPoly = vps->GetNearestPolygon(op,lngX,lngY,lngRad);  
  ViewportPixel *vpPoint = vps->GetNearestPoint(op,lngX,lngY,lngRad);  
  ViewportPixel *vpEdge = vps->GetNearestEdge(op,lngX,lngY,lngRad);  
  Bool shiftDown = GetInputEvent(BFM_INPUT_KEYBOARD, state);  
  LONG lngPolygonCount = objPoly->GetPolygonCount();  
  LONG lngPointCount = objPoly->GetPointCount();  
  const CPolygon * selectedPoly = objPoly->GetPolygonR();   
  const Vector * points = objPoly->GetPointR();  
  LONG lngI;  
  
  Matrix opMatrix  = op->GetMg();  
    
    
  switch (lngEditorMode)  
  {       
      //POLYGONS MODE      
      case Mpolygons:  
      {  
          if(vpPoly)  
          {  
              //FIRST SELECTION  
              if (secondSelection == FALSE)  
              {  
                  bsPoly->DeselectAll();  
                  bsPoly->Select(vpPoly->i);  
                  firstSelection = vpPoly->op;  
                  secondSelection = TRUE;  
              }  
  
              //SECOND SELECTION  
              else if (secondSelection == TRUE)  
              {  
                  bsPoly->DeselectAll();  
                  bsPoly->Select(vpPoly->i);  
                    
                  for (lngI=0; lngI < lngPolygonCount; lngI++)  
                  {  
                      if (bsPoly->IsSelected(lngI))  
                      {  
                          lngA = selectedPoly[lngI].a;  
                          lngB = selectedPoly[lngI].b;  
                          lngC = selectedPoly[lngI].c;  
                          lngD = selectedPoly[lngI].d;  
                            
                          //Caclulate the polygon position.  
                          if (selectedPoly[lngI].c == selectedPoly[lngI].d)   
                          {  
                              polyLocation = (points[lngA] + points[lngB] + points[lngC]) / 3; //Polygon is a Triangle  
                                
                          }  
                          else  
                          {  
                              polyLocation = (points[lngA] + points[lngB] + points[lngC] + points[lngD]) / 4; //Polygon is not a Triangle  
                          }  
  
                          //Align 1st Selection to the polygon of 2nd Selection (X AXIS)  
                          if (polyLocation.x > 0)  
                          {  
                              firstSelection->SetPos(op->GetPos() + polyLocation + Vector(firstSelection->GetRad().x,0,0));  
                              firstSelection->SetRot(CalcFaceNormal(points,selectedPoly[lngI]) * opMatrix);  
                                
                          }  
  
                          if (polyLocation.x < 0)  
                          {  
                              firstSelection->SetPos(op->GetPos() + polyLocation - Vector(firstSelection->GetRad().x,0,0));  
                              firstSelection->SetRot(CalcFaceNormal(points,selectedPoly[lngI]) * opMatrix);  
                                
                          }  
  
                          //Align 1st Selection to the polygon of 2nd Selection (Y AXIS)  
                          if (polyLocation.y > 0)  
                          {  
                              firstSelection->SetPos(op->GetPos() + polyLocation + Vector(0,firstSelection->GetRad().y,0));  
                              firstSelection->SetRot(op->GetRot());  
                          }  
  
                          if (polyLocation.y < 0)  
                          {  
                              firstSelection->SetPos(op->GetPos() + polyLocation - Vector(0,firstSelection->GetRad().y,0));  
                              firstSelection->SetRot(op->GetRot());  
                          }  
  
                          //Align 1st Selection to the polygon of 2nd Selection (Z AXIS)  
                          if (polyLocation.z > 0)  
                          {  
                              firstSelection->SetPos(op->GetPos() + polyLocation + Vector(0,0,firstSelection->GetRad().z));  
                              firstSelection->SetRot(op->GetRot());  
                          }  
  
                          if (polyLocation.z < 0)  
                          {  
                              firstSelection->SetPos(op->GetPos() + polyLocation - Vector(0,0,firstSelection->GetRad().z));  
                              firstSelection->SetRot(op->GetRot());  
                          }  
  
                            
                          bsPoly->DeselectAll();      
                      }  
                  }  
                  secondSelection = FALSE;      
              }  
        
              EventAdd(EVENT_FORCEREDRAW);  
              op->Message(MSG_CHANGE);  
              DrawViews(DA_ONLY_ACTIVE_VIEW|DA_NO_THREAD|DA_NO_ANIMATION);  
          }  

I am trying to get (firstSelection) to rotate to the normal of the selected polygon on (op).    I am using CalcFaceNormal() but that seems to return incorrect results.  Does anyone know how I could get this to rotate properly?

Thanks,

~SHawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 24/02/2010 at 02:43, xxxxxxxx wrote:

I recommend to read up on Vector and Matrix arithmetics.

http://www.flipcode.com/documents/matrfaq.html

Also the CINEMA 4D R9.5 COFFEE documentation has a very good tutorial on using matrices.

Especially vector cross products are essential to build your own cutom rotation matrices.

I can not debug or write your plugin, sorry.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 24/02/2010 at 02:48, xxxxxxxx wrote:

Thanks for the link Matthias.   LOL...  I don't want you to write it for me.   Where's the fun in that.   🙂

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 24/02/2010 at 07:31, xxxxxxxx wrote:

Great tutorial on Matrices.  Thanks for that.

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/02/2010 at 03:47, xxxxxxxx wrote:

Is there a c++ equivalent to the function you mention in the tutorial GetMulP()?

or would I just use

firstSelection->SetPos(opMatrix * points[lngA]);

first selection being my object,  and points[lngA] being the vector location of the point I am trying to move the object to.

Thanks,

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 25/02/2010 at 05:47, xxxxxxxx wrote:

Yes, multiplying a vector with a matrix transforms the vector into the matix' space.

The Matrix class has several overloaded operators for matrix-matrix and matrix-vector arithmetics.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 26/02/2010 at 09:38, xxxxxxxx wrote:

Okay... SO I think I kindof understand a rotation matrix now.   I need to find the vector from the center of the polygon which I did with

  
polyLocation = (points[lngA] + points[lngB] + points[lngC] + points[lngD]) / 4;  

This gives me a vector that represents the very center of the polygon

Then I need another point along the same plane which I use points[lngA].  This is the first point in the polygon.

So mathematically that gives me A & B.   Assuming my equation is C = A x B.     So to get the point which represents the Z axis or the point hovering directly above the polygon face, I simply multiply

  
Vector rotC =  polyLocation * points[lngA];  

And this should give me my rotation matrix correct?

So now my question is how do I then rotate my object to match that  rotation matrix?  Here is what I am trying.

  
  //ROTATION MATRIX  
                                
                              //GetPoints  
                              Vector p1 = polyLocation;   
                              Vector p2 = points[lngA];  
                                
                              //Contruct Matrix  
                              Matrix rotMatrix;  
  
                              rotMatrix.off = p1; //The base of the matrix  
                              rotMatrix.v1 = !(p2 - p1); //X axis points toward the second point  
                              rotMatrix.v2 = !(p2-p1%Vector(0,1,0)); //Y Axis is perpendicular to the X axis  
                              rotMatrix.v3 = rotMatrix.v1 * rotMatrix.v2;  
  
                              Vector scale = Vector(Len(rotMatrix.v1), Len(rotMatrix.v2), Len(rotMatrix.v3)); //Get Scale  
                              Vector pos = rotMatrix.off; ///Get the Position  
                                
                              //Create a vector which contains the rotation matrix.  
                              Vector rot1 = MatrixToHPB(rotMatrix);  
  
  
                              firstSelection->SetPos(opMatrix * polyLocation);  
                              firstSelection->SetRot((rot1));      
  

Please let me know if I am way off base here and am going about this completely wrong so that I know not to continue in this way.    Thanks lot for your help.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 01/03/2010 at 06:22, xxxxxxxx wrote:

Thanks for all your help Jack.  I have officially filled up your PM box.   I didn't notice that what you sent me was different.  Thanks for that.

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 03/03/2010 at 17:15, xxxxxxxx wrote:

Hey folks.  So I believe that I have created the rotation matrix correctly.  And when I click the polygon on the second object the object moves to that polygon correctly, however it does not rotate correctly.  Sometimes it rotates a bit but not the way it should.  I want the firstSelection object to rotate so that it is sitting flush with the polygon no matter what the rotation of the polygon is.    Does anyone see any reason in the following code why this wouldn't be happening?

Any help would be greatly appreciated.  This one's a bit frustrating.

for (lngI=0; lngI < lngPolygonCount; lngI++)
                    {
                        if (bsPoly->IsSelected(lngI))
                        {
                            lngA = selectedPoly[lngI].a;
                            lngB = selectedPoly[lngI].b;
                            lngC = selectedPoly[lngI].c;
                            lngD = selectedPoly[lngI].d;
							
							//Caclulate the polygon position.
							if (selectedPoly[lngI].c == selectedPoly[lngI].d) 
							{
								polyLocation = (points[lngA] + points[lngB] + points[lngC]) / 3; //Polygon is a Triangle
								
							}
							else
							{
								polyLocation = (points[lngA] + points[lngB] + points[lngC] + points[lngD]) / 4; //Polygon is not a Triangle
							}
  
							//Align 1st Selection to the polygon of 2nd Selection (X AXIS)
							if (polyLocation.x > 0)
							{
								//ROTATION MATRIX
								//GetPoints
								Vector p1 = polyLocation; 
								Vector p2 = points[lngA];
								
								Vector scale = Vector(Len(opMatrix.v1), Len(opMatrix.v2), Len(opMatrix.v3)); //Get Scale
								
								//Contruct Matrix
								Matrix rotMatrix;
  
								rotMatrix.off = p1; //The base of the matrix
								rotMatrix.v3 = !(p1); //Z Axis is along the normal
								rotMatrix.v1 = !(p2 - p1); //X axis points toward the second point
								rotMatrix.v2 = rotMatrix.v1%rotMatrix.v3;//Y Axis is perpendicular to the X axis
								rotMatrix.v1 = !(rotMatrix.v3%rotMatrix.v2);//recreated second axis..   using cross product.
																
								rotMatrix.v1 = !(rotMatrix.v1 * scale.x);
								rotMatrix.v2 = !(rotMatrix.v2 * scale.y);
								rotMatrix.v3 = !(rotMatrix.v3 * scale.z);
			
	
								Vector rot1 = MatrixToHPB(rotMatrix);
					
								firstSelection->SetMg(rotMatrix);
								firstSelection->SetPos((opMatrix * polyLocation) + firstSelection->GetRad().x);
								//firstSelection->SetRot(rot1);
	
							}
  
  

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 03/03/2010 at 18:21, xxxxxxxx wrote:

Do I need the world coordinates of the points I am using for this to work properly?

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 09/03/2010 at 17:20, xxxxxxxx wrote:

I feel like I have done the rotation matrix correctly here.  But my object is not rotating to the normal of the polygon.  Does anyone see anything that I am doing wrong creating the rotation matrix?

I would GREATLY, appreciate any help anyone could offer.  This one is irritating me because everything I have read about rotation matrices says that I am doing it right.  I am using a vector that represents the center of the polygon (polygonLocation)   I am using another point in the polygon to determine the plane upon which the polygon rests.  I am then using the cross product of those vectors to determine the up vector that is perpendicular to the plane.  So, if my understanding of rotation matrices is correct, this should create a rotation matrix that can then be adapted by an object and that object should rotate to the normal of the polygon.

However, that is not happening with what I have pasted above.   I am at a loss.  Does anyone see anything that I am doing wrong?

Thanks so much for anyone who has the time to help me out.

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 15/03/2010 at 01:25, xxxxxxxx wrote:

Originally posted by xxxxxxxx

I am using a vector that represents the center of the polygon (polygonLocation)   I am using another point in the polygon to determine the plane upon which the polygon rests.  I am then using the cross product of those vectors to determine the up vector that is perpendicular to the plane.

This part is wrong.

Assume that A is the midpoint of your polygon and B is one of the polygon points.
N is the polygon normal.

You have to build the cross product of (B-A) and N for one of the matrix axes, let's say for V1.
Then build the cross product of this new axis and the normal for the second matrix axis, V2.
The normal is the third axis of the matrix, V3.
The polygon midpoint is the matrix offset, V0 or off.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 15/03/2010 at 02:41, xxxxxxxx wrote:

Thanks Matthias,

I must not fully understand how to get the normal then.   I thought that the normal was A - B.   How to I get the value for N then?

THanks,

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 15/03/2010 at 02:47, xxxxxxxx wrote:

Would I use

CalcFaceNormal()_<_h4_>_

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 15/03/2010 at 02:49, xxxxxxxx wrote:

For triangles the normal is the cross product of two edges of the triangle. For quadrangles it's not exactly defined. The easiest way which gives a good result is too use the cross product of the diagonales.

PS. please read up on 3D geometry basics, it will help you in the long run. Most of it can be found through Google and Wikipedia.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 15/03/2010 at 03:06, xxxxxxxx wrote:

So to calculate the normal of a quad would I do something like this...  Assuming that the points in a quad are A, B, C, and D

QUAD

N = (A-C)%(D-B)

TRIANGLE

N = (A-C)%(B-C)

SOmething like that?

Does CalcFaceNormal() do this for you?  or is that something completely different?

Thanks  a lot for your help,

~ Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 15/03/2010 at 03:23, xxxxxxxx wrote:

yes and yes 🙂

source code of CalcFaceNormal()

  
inline Vector CalcFaceNormal(const Vector *padr, const CPolygon &v)  
{  
  if (v.c==v.d)  
      return !((padr[v.b]-padr[v.a])%(padr[v.c]-padr[v.a]));  
  else  
      return !((padr[v.b]-padr[v.d])%(padr[v.c]-padr[v.a]));  
}  

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 15/03/2010 at 12:00, xxxxxxxx wrote:

does CalcFaceNormal work for you?? when i use it i get only nonsense rotations.

cheers,
ello