示例#1
0
//Transforms the model coordinates into world space coordinates
//using the orientation and position
void PolygonBody::updateVerticesWorldSpace() {
    float sinOrientation = sinf(_orientation);
    float cosOrientation = cosf(_orientation);
    
    for (size_t i = 0; i < _verticesModelSpace.size(); ++i) {
        const Vector2f& v = _verticesModelSpace[i];
        Vector2f rotatedVertex(v.x * cosOrientation + v.y * sinOrientation, v.y * cosOrientation - v.x * sinOrientation);

        _verticesWorldSpace[i] = rotatedVertex + _position;
    }
}
示例#2
0
void ossimPolygon::getMinimumBoundingRect(ossimPolygon& minRect) const
{
   static const double MIN_STEP = (0.5)*M_PI/180.0;
   double angle_step = M_PI/8.0;  // initial rotation step size for min area search = 22.5 deg
   double theta;
   double best_theta = M_PI/4.0;  // Initial guess is 45 deg orientation
   double center_theta;
   double cos_theta, sin_theta;
   ossimPolygon rotatedPolygon(*this);
   ossimDpt xlatedVertex;
   ossimDpt rotatedVertex(0.0, 0.0);
   double min_x, min_y, max_x, max_y;
   double area;
   double min_area = 1.0/DBL_EPSILON;
   rotatedPolygon.theVertexList[0] = ossimDpt(0, 0);  // first vertex always at origin
   bool first_time = true;
   ossimDrect best_rect;
   static const bool TESTING = false;

   //***
   // Loop to converge on best orientation angle for bounding polygon:
   //***
   while (angle_step > MIN_STEP)
   {
      //***
      // Try four different rotations evenly centered about the current best guess:
      //***
      center_theta = best_theta;
      for (int i=0; i<5; i++)
      {
         //***
         // Check for i=2 (center angle) since already computed quantities for this in last iteration
         // unless this is first time through:
         //***
         if ((i != 2) || (first_time)) 
         {
            theta = center_theta + (i - 2.0)*angle_step;
            cos_theta = cos(theta);
            sin_theta = sin(theta);
            min_x = rotatedPolygon.theVertexList[0].x;
            min_y = rotatedPolygon.theVertexList[0].y;
            max_x = min_x;
            max_y = min_y;

            //***
            // Translate polygon to origin and rotate all vertices by current theta:
            //***
            for (unsigned int vertex=1; vertex < theVertexList.size(); vertex++)
            {
               xlatedVertex.x = theVertexList[vertex].x - theVertexList[0].x;
               xlatedVertex.y = theVertexList[vertex].y - theVertexList[0].y;
               rotatedVertex.x = cos_theta*xlatedVertex.x + sin_theta*xlatedVertex.y;
               rotatedVertex.y = cos_theta*xlatedVertex.y - sin_theta*xlatedVertex.x;
               rotatedPolygon.theVertexList[vertex] = rotatedVertex;

               //***
               // Latch max and mins of bounding rect:
               //***
               if (min_x > rotatedVertex.x) min_x = rotatedVertex.x;
               if (min_y > rotatedVertex.y) min_y = rotatedVertex.y;
               if (max_x < rotatedVertex.x) max_x = rotatedVertex.x;
               if (max_y < rotatedVertex.y) max_y = rotatedVertex.y;
            }

            if (TESTING)
            {
               ossimDpt v1 (cos_theta*min_x - sin_theta*max_y + theVertexList[0].x,
                            cos_theta*max_y + sin_theta*min_x + theVertexList[0].y);
               ossimDpt v2 (cos_theta*max_x - sin_theta*max_y + theVertexList[0].x,
                            cos_theta*max_y + sin_theta*max_x + theVertexList[0].y);
               ossimDpt v3 (cos_theta*max_x - sin_theta*min_y + theVertexList[0].x,
                            cos_theta*min_y + sin_theta*max_x + theVertexList[0].y);
               ossimDpt v4 (cos_theta*min_x - sin_theta*min_y + theVertexList[0].x,
                            cos_theta*min_y + sin_theta*min_x + theVertexList[0].y);
               cout << v1.x << "\t" << v1.y << endl;
               cout << v2.x << "\t" << v2.y << endl;
               cout << v3.x << "\t" << v3.y << endl;
               cout << v4.x << "\t" << v4.y << endl << endl;
            }

            //***
            // Establish bounding rect and area about rotated polygon:
            //***
            area = (max_x - min_x) * (max_y - min_y);
            if (area < min_area)
            {
               best_theta = theta;
               min_area = area;
               best_rect = ossimDrect(min_x, max_y, max_x, min_y, OSSIM_RIGHT_HANDED);
            }
         } // end if (i != 2 || first_time)
      }  // end for-loop over surrounding rotations

      //***
      // Adjust step size by half to repeat process:
      //***
      angle_step /= 2.0;
      first_time = false;

   } // end while loop for convergence

   //***
   // best_theta now contains optimum rotation of bounding rect. Need to apply reverse
   // rotation and translation of best_rect:
   //***
   cos_theta = cos(best_theta);
   sin_theta = sin(best_theta);
   ossimDpt v1 (cos_theta*best_rect.ul().x - sin_theta*best_rect.ul().y + theVertexList[0].x,
                cos_theta*best_rect.ul().y + sin_theta*best_rect.ul().x + theVertexList[0].y);
   ossimDpt v2 (cos_theta*best_rect.ur().x - sin_theta*best_rect.ur().y + theVertexList[0].x,
                cos_theta*best_rect.ur().y + sin_theta*best_rect.ur().x + theVertexList[0].y);
   ossimDpt v3 (cos_theta*best_rect.lr().x - sin_theta*best_rect.lr().y + theVertexList[0].x,
                cos_theta*best_rect.lr().y + sin_theta*best_rect.lr().x + theVertexList[0].y);
   ossimDpt v4 (cos_theta*best_rect.ll().x - sin_theta*best_rect.ll().y + theVertexList[0].x,
                cos_theta*best_rect.ll().y + sin_theta*best_rect.ll().x + theVertexList[0].y);
    
   if (TESTING)
   {
      cout << v1.x << "\t" << v1.y << endl;
      cout << v2.x << "\t" << v2.y << endl;
      cout << v3.x << "\t" << v3.y << endl;
      cout << v4.x << "\t" << v4.y << endl << endl;
   }

   //***
   // Assign return value rect:
   //***
   minRect.clear();
   minRect.addPoint(v1);
   minRect.addPoint(v2);
   minRect.addPoint(v3);
   minRect.addPoint(v4);

   return;
}