Torque3D Documentation / _generateds / quadTransforms.cpp

quadTransforms.cpp

Engine/source/math/util/quadTransforms.cpp

More...

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "platform/platform.h"
 25#include "math/util/quadTransforms.h"
 26
 27
 28BiQuadToSqr::BiQuadToSqr(  const Point2F &p00, 
 29                           const Point2F &p10, 
 30                           const Point2F &p11, 
 31                           const Point2F &p01 )
 32   : m_kP00( p00 )
 33{
 34   m_kB = p10 - p00 ;   // width
 35   m_kC = p01 - p00;   // height
 36   m_kD = p11 + p00 - p10 - p01; // diagonal dist
 37
 38   if(mFabs(m_kD.x) < POINT_EPSILON)    
 39      m_kD.x = 0.f;
 40   if(mFabs(m_kD.y) < POINT_EPSILON) 
 41      m_kD.y = 0.f;  
 42
 43   m_fBC = mDotPerp( m_kB, m_kC );
 44   m_fBD = mDotPerp( m_kB, m_kD );   
 45   m_fCD = mDotPerp( m_kC, m_kD );
 46}
 47
 48Point2F BiQuadToSqr::transform( const Point2F &p ) const
 49{
 50   Point2F kA = m_kP00 - p;
 51   
 52   F32 fAB = mDotPerp( kA, m_kB );
 53   F32 fAC = mDotPerp( kA, m_kC);
 54
 55   // 0 = ac*bc+(bc^2+ac*bd-ab*cd)*s+bc*bd*s^2 = k0 + k1*s + k2*s^2
 56   F32 fK0 = fAC*m_fBC;
 57   F32 fK1 = m_fBC*m_fBC + fAC*m_fBD - fAB*m_fCD;
 58   F32 fK2 = m_fBC*m_fBD;
 59
 60   if (mFabs(fK2) > POINT_EPSILON)
 61   {
 62      // s-equation is quadratic
 63      F32 fInv = 0.5f/fK2;
 64      F32 fDiscr = fK1*fK1 - 4.0f*fK0*fK2;
 65      F32 fRoot = mSqrt( mFabs(fDiscr) );
 66
 67      Point2F kResult0( 0, 0 );
 68      kResult0.x = (-fK1 - fRoot)*fInv;
 69      kResult0.y = fAB/(m_fBC + m_fBD*kResult0.x);
 70      F32 fDeviation0 = deviation(kResult0);
 71      if ( fDeviation0 == 0.0f )
 72         return kResult0;
 73
 74      Point2F kResult1( 0, 0 );
 75      kResult1.x = (-fK1 + fRoot)*fInv;
 76      kResult1.y = fAB/(m_fBC + m_fBD*kResult1.x);
 77      F32 fDeviation1 = deviation(kResult1);
 78      if ( fDeviation1 == 0.0f )
 79         return kResult1;
 80
 81      if (fDeviation0 <= fDeviation1)
 82      {
 83         if ( fDeviation0 < POINT_EPSILON )
 84            return kResult0;
 85      }
 86      else
 87      {
 88         if ( fDeviation1 < POINT_EPSILON )
 89            return kResult1;
 90      }
 91   }
 92   else
 93   {
 94      // s-equation is linear
 95      Point2F kResult( 0, 0 );
 96
 97      kResult.x = -fK0/fK1;
 98      kResult.y = fAB/(m_fBC + m_fBD*kResult.x);
 99      F32 fDeviation = deviation(kResult);
100      if ( fDeviation < POINT_EPSILON )
101         return kResult;
102   }
103
104   // point is outside the quadrilateral, return invalid
105   return Point2F(F32_MAX,F32_MAX);
106}
107
108F32 BiQuadToSqr::deviation( const Point2F &sp )
109{
110   // deviation is the squared distance of the point from the unit square
111   F32 fDeviation = 0.0f;
112   F32 fDelta;
113
114   if (sp.x < 0.0f)
115   {
116      fDeviation += sp.x*sp.x;
117   }
118   else if (sp.x > 1.0f)
119   {
120      fDelta = sp.x - 1.0f;
121      fDeviation += fDelta*fDelta;
122   }
123
124   if (sp.y < 0.0f)
125   {
126      fDeviation += sp.y*sp.y;
127   }
128   else if (sp.y > 1.0f)
129   {
130      fDelta = sp.y - 1.0f;
131      fDeviation += fDelta*fDelta;
132   }
133
134   return fDeviation;
135}
136
137
138BiSqrToQuad3D::BiSqrToQuad3D( const Point3F& pnt00,
139                              const Point3F& pnt10, 
140                              const Point3F& pnt11,
141                              const Point3F& pnt01)
142{
143   p00 = pnt00;
144   p10 = pnt10;
145   p11 = pnt11;
146   p01 = pnt01;
147}
148
149Point3F BiSqrToQuad3D::transform( const Point2F &p ) const
150{   
151   //Let p00, p10, p01, and p11 be your 3-tuples that are the quad's
152   //vertices.  You can parameterize the quad as follows.
153
154   //q(s,t) = (1-s)*((1-t)*p00 + t*p01) + s*((1-t)*p10 + t*p11)
155
156   //for 0 <= s <= 1 and 0 <= t <= 1.  Notice that q(0,0) = p00,
157   //q(1,0) = p10, q(0,1) = p01, and q(1,1) = p11, so the parameter
158   //"square" whose points are (s,t) will be mapped to the quad.
159
160   const F32 &s = p.x;
161   const F32 &t = p.y;
162
163   Point3F result = (1.0f-s)*((1.0f-t)*p00 + t*p01) + s*((1.0f-t)*p10 + t*p11);
164   return result;   
165}
166
167