CV_IMPL CvBox2D cvMinAreaRect2( const CvArr* array, CvMemStorage* storage ) { CvMemStorage* temp_storage = 0; CvBox2D box; CvPoint2D32f* points = 0; CV_FUNCNAME( "cvMinAreaRect2" ); memset(&box, 0, sizeof(box)); __BEGIN__; int i, n; CvSeqReader reader; CvContour contour_header; CvSeqBlock block; CvSeq* ptseq = (CvSeq*)array; CvPoint2D32f out[3]; if( CV_IS_SEQ(ptseq) ) { if( !CV_IS_SEQ_POINT_SET(ptseq) && (CV_SEQ_KIND(ptseq) != CV_SEQ_KIND_CURVE || !CV_IS_SEQ_CONVEX(ptseq) || CV_SEQ_ELTYPE(ptseq) != CV_SEQ_ELTYPE_PPOINT )) CV_ERROR( CV_StsUnsupportedFormat, "Input sequence must consist of 2d points or pointers to 2d points" ); if( !storage ) storage = ptseq->storage; } else { CV_CALL( ptseq = cvPointSeqFromMat( CV_SEQ_KIND_GENERIC, array, &contour_header, &block )); } if( storage ) { CV_CALL( temp_storage = cvCreateChildMemStorage( storage )); } else { CV_CALL( temp_storage = cvCreateMemStorage(1 << 10)); } if( !CV_IS_SEQ_CONVEX( ptseq )) { CV_CALL( ptseq = cvConvexHull2( ptseq, temp_storage, CV_CLOCKWISE, 1 )); } else if( !CV_IS_SEQ_POINT_SET( ptseq )) { CvSeqWriter writer; if( !CV_IS_SEQ(ptseq->v_prev) || !CV_IS_SEQ_POINT_SET(ptseq->v_prev)) CV_ERROR( CV_StsBadArg, "Convex hull must have valid pointer to point sequence stored in v_prev" ); cvStartReadSeq( ptseq, &reader ); cvStartWriteSeq( CV_SEQ_KIND_CURVE|CV_SEQ_FLAG_CONVEX|CV_SEQ_ELTYPE(ptseq->v_prev), sizeof(CvContour), CV_ELEM_SIZE(ptseq->v_prev->flags), temp_storage, &writer ); for( i = 0; i < ptseq->total; i++ ) { CvPoint pt = **(CvPoint**)(reader.ptr); CV_WRITE_SEQ_ELEM( pt, writer ); } ptseq = cvEndWriteSeq( &writer ); } n = ptseq->total; CV_CALL( points = (CvPoint2D32f*)cvAlloc( n*sizeof(points[0]) )); cvStartReadSeq( ptseq, &reader ); if( CV_SEQ_ELTYPE( ptseq ) == CV_32SC2 ) { for( i = 0; i < n; i++ ) { CvPoint pt; CV_READ_SEQ_ELEM( pt, reader ); points[i].x = (float)pt.x; points[i].y = (float)pt.y; } } else { for( i = 0; i < n; i++ ) { CV_READ_SEQ_ELEM( points[i], reader ); } } if( n > 2 ) { icvRotatingCalipers( points, n, CV_CALIPERS_MINAREARECT, (float*)out ); box.center.x = out[0].x + (out[1].x + out[2].x)*0.5f; box.center.y = out[0].y + (out[1].y + out[2].y)*0.5f; box.size.height = (float)sqrt((double)out[1].x*out[1].x + (double)out[1].y*out[1].y); box.size.width = (float)sqrt((double)out[2].x*out[2].x + (double)out[2].y*out[2].y); box.angle = (float)atan2( -(double)out[1].y, (double)out[1].x ); } else if( n == 2 ) { box.center.x = (points[0].x + points[1].x)*0.5f; box.center.y = (points[0].y + points[1].y)*0.5f; double dx = points[1].x - points[0].x; double dy = points[1].y - points[0].y; box.size.height = (float)sqrt(dx*dx + dy*dy); box.size.width = 0; box.angle = (float)atan2( -dy, dx ); } else { if( n == 1 ) box.center = points[0]; } box.angle = (float)(box.angle*180/CV_PI); __END__; cvReleaseMemStorage( &temp_storage ); cvFree( &points ); return box; }
/* * If curve is convex, return true. Otherwise return false. */ VALUE rb_convex_q(VALUE self) { return CV_IS_SEQ_CONVEX(CVSEQ(self)) ? Qtrue : Qfalse; }