NO

Author Topic: Computing Z given X and Y  (Read 3369 times)

Offline HellOfMice

  • Member
  • *
  • Posts: 105
  • Never be pleased, always improve
Computing Z given X and Y
« on: February 02, 2023, 04:13:46 PM »
I need some help because, I am very good useing math.
The user draws a rectangle with the mouse.
SO I have (X1,Y1) and (X2,Y2)

(X1,Y1) are the top left coordinates and
(X2,Y2) are the bottom right coordinates.

I have computed the slope and got the angle.

The rectangle drawn is at (X1,Y1,0)-(X2,Y2,0) but if want to display or to rotate along an axis I need the Z coordinate.

Code: [Select]
static int Create3DObject(HWND __hWnd,int __iX_First,int __iY_First,int __iX_Last,int __iY_Last)
{
   int         _iX1, _iY1, _iX2, _iY2 ;
   int         _iWidth, _iHeight ;
   int         _iPrevIndex ;

   double      _dDistance, _dSlope, _dAngle ;
   double      _dDelta_X, _dDelta_Y ;

   LPOBJECT3D   _lpFirstObject, _lpTmpObject, _lpObject ;

   if((__iX_First == __iX_Last) && (__iY_First == __iY_Last))
   {
      Error("Cannot create an object if the distance between points is equal to 0") ;
      return (FALSE) ;
   }

   _iX1 = __iX_First ;
   _iY1 = __iY_First ;

   _iX2 = __iX_Last ;
   _iY2 = __iY_Last ;

   _iWidth = abs(_iX2 - _iX1) ;
   _iHeight = abs(_iY2 - _iY1) ;

   if(_iHeight == 0)
      return (Error("Cannot create an object if its height is equal to 0")) ;

   _dDistance = sqrt(pow((double) _iWidth,2) + pow((double) _iHeight,2)) ;

   if(_dDistance == 0.00)
      return (Error("Cannot create an object if the distance between points is equal to 0")) ;

   _dDelta_Y = ((double) _iY2) - ((double) _iY1) ;
   _dDelta_X = ((double) _iX2) - ((double) _iX1) ;

   _dSlope = _dDelta_Y / _dDelta_X ;

   _dAngle = VANISH_RAD_TO_DEG * atan2(_dDelta_Y,_dDelta_X) ;

   _lpFirstObject = (LPOBJECT3D) GetWindowLongPtr(__hWnd,GWLP_USERDATA) ;
   if(_lpFirstObject == NULL)
   {
      _lpObject = (LPOBJECT3D) malloc(sizeof(OBJECT3D)) ;
      if(_lpObject == NULL)
      {
         Error("Not enough memory for allocating a new object") ;
         return (FALSE) ;
      }

      _lpObject->Index                           = 1 ;

      _lpObject->Liste.lpPrev                        = NULL ;
      _lpObject->Liste.lpNext                        = NULL ;

      SetWindowLongPtr(__hWnd,GWLP_USERDATA,(LONG_PTR) _lpObject) ;
   }
   else
   {
      _iPrevIndex = 0 ;
      _lpTmpObject = _lpFirstObject ;

      while(_lpTmpObject->Liste.lpNext != NULL)
      {
         if(_iPrevIndex < _lpTmpObject->Index)
            _iPrevIndex = _lpTmpObject->Index ;

         _lpTmpObject = (LPOBJECT3D) _lpTmpObject->Liste.lpNext ;
      }

      _lpObject = (LPOBJECT3D) malloc(sizeof(OBJECT3D)) ;
      if(_lpObject == NULL)
      {
         Error("Not enough memory for allocating a new object") ;
         return (FALSE) ;
      }

      _lpTmpObject->Liste.lpNext                  = _lpObject ;
      _lpObject->Liste.lpPrev                     = _lpTmpObject ;
      _lpObject->Liste.lpNext                     = NULL ;

      _lpObject->Index                        = _iPrevIndex + 1 ;
   }

   _lpObject->ColorBrush                        = -1 ;            // NULL BRUSH
   _lpObject->ColorPen                           = 0x000000FF ;

//   z = sqrt(x² + y² - 2 * x * y * cos(γ)) ?

   _lpObject->Coordonnees3D.Distance         = _dDistance ;
   _lpObject->Coordonnees3D.Slope            = _dSlope ;
   _lpObject->Coordonnees3D.Angle            = _dAngle ;
   _lpObject->Coordonnees3D.DeltaX            = _dDelta_X ;
   _lpObject->Coordonnees3D.DeltaY            = _dDelta_Y ;

   _lpObject->Coordonnees3D.Left.x            = _iX1 ;
   _lpObject->Coordonnees3D.Left.y            = _iY1 ;
   _lpObject->Coordonnees3D.Left.z            = sqrt(pow((double) _iX1,2) + pow((double) _iY1,2) - (2 * (double) _iX1 * (double) _iY1 * cos(_dAngle))) ;

   _lpObject->Coordonnees3D.Right.x         = _iX2 ;
   _lpObject->Coordonnees3D.Right.y         = _iY2 ;
   _lpObject->Coordonnees3D.Right.z         = sqrt(pow((double) _iX2,2) + pow((double) _iY2,2) - (2 * (double) _iX2 * (double) _iY2 * cos(_dAngle))) ;

   _lpObject->Coordonnees3D.Rectangle.x      = _iX1 ;
   _lpObject->Coordonnees3D.Rectangle.y      = _iY1 ;
   _lpObject->Coordonnees3D.Rectangle.z      = sqrt(pow((double) _iX1,2) + pow((double) _iY1,2) - (2 * (double) _iX1 * (double) _iY1 * cos(_dAngle))) ;
   _lpObject->Coordonnees3D.Rectangle.width   = _iWidth ;
   _lpObject->Coordonnees3D.Rectangle.height   = _iHeight ;
   _lpObject->Coordonnees3D.Rectangle.Depth   = abs(_iX1 - _lpObject->Coordonnees3D.Rectangle.z) ;

   lpCurrentObject                        = _lpObject ;

   return (TRUE) ;
}

z = sqrt(x² + y² - 2 * x * y * cos(γ))

This is how I compute the Z.
It is a formula I found somewhere on the internet but I don't know it this is good.

Some help would be welcome.
Thank You / Merci
--------------------------------
Kenavo

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Computing Z given X and Y
« Reply #1 on: February 03, 2023, 09:22:58 AM »
These MS docs about 2D transformations are woth to be read for your needs.
The articles contain a broad discussion of the topics from a mathematical point of view (MS uses matrix algebra). and also the list of GDI library functions that implement the transformations in case you don't want to reinvent the wheel.
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

Offline HellOfMice

  • Member
  • *
  • Posts: 105
  • Never be pleased, always improve
Re: Computing Z given X and Y
« Reply #2 on: February 03, 2023, 09:57:20 AM »
Thank You Fankie.
I take look.
--------------------------------
Kenavo