#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/opencv.hpp>
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=a;i<=b;++i)
using namespace cv;
using namespace std;
int n,cnt;
vector<Point2f>a,b;
Mat src;
Mat dst;
Point2f pre_pt ,fir_pt;
Point2f cur_pt ;
double xmin,xmax,ymin,ymax,k;
int flag;
Point2f recursive_bezier(float t)
{
int n=(int)a.size();
vector<Point2f> k(n);
vector<Point2f> w(n);
for(int i=0;i<n;i++) w[i]=a[i];
while(w.size()>1){
k.clear();
n=(int)w.size();
for(int i=0;i<n-1;i++){
k.push_back((w[i])*(1-t)+w[i+1]*(t));
}
w.clear();
n=(int)k.size();
for(int i=0;i<n;i++){
w.push_back(k[i]);
}
}
return w[0];
}
void bezier(){
for (double t = 0.0; t <= 1.0; t += 0.0001)
{
auto point = recursive_bezier(t);
//window.at<Vec3b>(point.y, point.x)[1] = 255;//绿色
circle(src, Point2f(point.x,point.y), 1, Scalar(255,255,255), FILLED, 0);
}
imshow("bezier_curve", src);
}
void on_mouse(int event, int x, int y, int flags, void* ustc){
if (event == EVENT_LBUTTONDOWN){
cnt++;
a.push_back(Point(x,y));
if(cnt==1){
pre_pt=Point(x,y);
fir_pt=pre_pt;
circle(src, fir_pt, 4, Scalar(255,255,255), FILLED, 0);
imshow("bezier_curve", src);
}
if(cnt>1&&cnt<=n){
cur_pt=Point(x,y);
circle(src, cur_pt, 4, Scalar(255,255,255), FILLED, 0);
line(src, pre_pt, cur_pt, Scalar(0, 255,0), 2, 4, 0);
pre_pt=cur_pt;
imshow("bezier_curve", src);
}
if(cnt==n){
bezier();
return;
}
}
}
void add(int event, int x, int y, int flags, void* ustc){
if (event == EVENT_LBUTTONDOWN){
a.push_back(Point(x,y));
dst.copyTo(src);
cnt=0;
for(auto i:a){
if(++cnt==1){
circle(src, i, 4, Scalar(255,255,255), FILLED, 0);
}
else{
circle(src, i, 4, Scalar(255,255,255), FILLED, 0);
line(src, pre_pt, i, Scalar(0, 255,0), 2, 4, 0);
}
pre_pt=i;
}
bezier();
return ;
}
}
void init(){
while(1){
cin>>flag;
switch (flag){
case 1:{ //从0开始搭建贝塞尔曲线
cout<<"请输入控制顶点的个数"<<endl;
cin>>n;
while(n<3){
cout<<"个数不能小于3呀😁,请重新输入"<<endl;
cin>>n;
}
imshow("bezier_curve", src);
cnt=0;
setMouseCallback("bezier_curve", on_mouse, 0);
int kikk=-1;
while(kikk != 27){
kikk=waitKey(0);
cout<<kikk<<endl;
if(kikk==27){
break;
}
}
// if(waitKey(0)=='q') break;
break;
}
case 2:{ //删除最后一个点..
if(n==3){
cout<<"不能再删除啦,再删除都快没了..."<<endl;
}
else{
a.pop_back();
dst.copyTo(src);
cnt=0;
for(auto i:a){
if(++cnt==1){
circle(src, i, 4, Scalar(255,255,255), FILLED, 0);
}
else{
circle(src, i, 4, Scalar(255,255,255), FILLED, 0);
line(src, pre_pt, i, Scalar(0, 255,0), 2, 4, 0);
}
pre_pt=i;
}
imshow("bezier_curve", src);
bezier();
}
break;
}
case 3:{ //在最后添加一个点
imshow("bezier_curve", src);
setMouseCallback("bezier_curve", add, 0);
}
}
}
}
int main(){
namedWindow("bezier_curve", WINDOW_AUTOSIZE);
src=Mat(1000, 1000, CV_8UC3, Scalar(0));
src.copyTo(dst);
init();
//setMouseCallback("bezier_curve", on_mouse, 0);
imshow("bezier_curve", src);
waitKey(0);
return 0;
}