From: http://www.bfcat.com/index.php/2012/11/random-polygon-ellipse/
I saw it on a blog today.
On a piece of paperRandomly draw some pointsAnd connect them to formRandom Polygon. Find all edges of a polygon.MidpointAnd link the midpoint intoNew Polygon, SoRepeatedThe final result isSmaller and smallerAnd tendAn elliptic!
For example, you can go to an app webpage provided by the author and perform the following operations on your own:
The matthen blog returns the code for this process. This blog also introduces many other interesting questions about mathematics and science, which are worth subscribing.
========================== The following content is original
Address of this article: http://blog.csdn.net/houston#35/article/details/8498938. please specify
This phenomenon looks interesting, so we used opencv to simulate it and encountered several problems.
1. Coordinate normalization. As the point polygon is getting smaller and smaller, you will receive a point without normalization.
2. The data type of coordinates. The integer type is used at the beginning. It is difficult to converge when there are more points. It may be that it reaches the steady state during the approximate process, so it is changed to the floating point type, which then converges, multiple points can also converge to an elliptic
Paste out the code. If you want to find out, you can take a look.
// Poly2Ellipse.h#include <opencv.hpp>#include <vector>#include <iostream>using namespace std;using namespace cv;#define img_width 400#define img_height 400#define n_pts 100
// Poly2Ellipse.cpp#include "Poly2Ellipse.h"void display(Mat& img, string win_name, int wait_time = 1){namedWindow(win_name);imshow(win_name, img);waitKey(wait_time);}void drawPts(Mat& img, vector<Point2f>& pts){for (size_t i = 0; i < pts.size(); ++i){circle(img, pts[i], 3, Scalar(0,255,0));}for (size_t i = 0; i < pts.size() - 1; ++i){line(img, pts[i], pts[i+1], Scalar(0,0,255));}line(img, pts.back(), pts.front(), Scalar(0,0,255));}void interpPt(const vector<Point2f>& pts1, vector<Point2f>& pts2){float x_max = -1;float y_max = -1;float x_min = 10000;float y_min = 10000;for (size_t i = 0; i < pts1.size() - 1; ++i){pts2[i].x = (pts1[i].x + pts1[i + 1].x) / 2;pts2[i].y = (pts1[i].y + pts1[i + 1].y) / 2;if (pts2[i].x > x_max){x_max = pts2[i].x;}if (pts2[i].y > y_max){y_max = pts2[i].y;}if (pts2[i].x < x_min){x_min = pts2[i].x;}if (pts2[i].y < y_min){y_min = pts2[i].y;}}pts2.back().x = (pts1.front().x + pts1.back().x) / 2;pts2.back().y = (pts1.front().y + pts1.back().y) / 2;if (pts2.back().x > x_max){x_max = pts2.back().x;}if (pts2.back().y > y_max){y_max = pts2.back().y;}if (pts2.back().x < x_min){x_min = pts2.back().x;}if (pts2.back().y < y_min){y_min = pts2.back().y;}float x_ratio = 0.8 * img_width / (x_max - x_min);float y_ratio = 0.8 * img_height / (y_max - y_min);int x_shift = 0.1 * img_width;int y_shift = 0.1 * img_height;for (size_t i = 0; i < pts2.size(); ++i){pts2[i].x = x_ratio * (pts2[i].x - x_min) + x_shift;pts2[i].y = y_ratio * (pts2[i].y - y_min) + y_shift;}}int main(void){Mat img_show(img_height, img_width, CV_8UC3, Scalar(0));Mat img_black = img_show.clone();//int n_pts = 10;RNG rng(getTickCount());Mat tmp(1, 2, CV_32S);vector<Point2f> pts1(n_pts);vector<Point2f> pts2(n_pts);for (int i = 0; i < n_pts; ++i){pts1[i].x = rng.uniform(0, img_width);pts1[i].y = rng.uniform(0, img_height);}drawPts(img_show, pts1);display(img_show, "img");for (;;){interpPt(pts1, pts2);img_black.copyTo(img_show);pts1 = pts2;drawPts(img_show, pts1);display(img_show, "interp");if (waitKey(50)=='e'){break;}}waitKey(0);return 0;}