//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; } }
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; }