绘制Bezier曲线
// 功 能:单击鼠标左键进行折点确定,单击右键进行Bezier曲线(绿色)绘制,同时也会画出多边折线(黄色)
// 编译环境:Visual C++ 6.0,EasyX_20190219(beta)
#include<graphics.h>
#include<conio.h>
double get(int i,int n,double t){
int j;
double a=1,b=1,c=1,d=1,e=1;
for(j=1;j<=n;j++){
a=a*j;
if(j<=i){
b=b*j;
d=d*t;
}
if(j<=n-i){
c=c*j;
e=e*(1.0-t);
}
}
if(a==0){a=1;}
if(b==0){b=1;}
if(c==0){c=1;}
return (a/(b*c))*d*e;
}
void paint_bezier(POINT *p,int n){
int i,j;
double b[100];
double t=0,x=0,y=0;
setcolor(YELLOW);
moveto(p[0].x,p[0].y);
int k=50;
for(i=0;i<k;i++){
t=(i)/double(k);
x=0;y=0;
for(j=0;j<n;j++){
b[j]=get(j,n-1,t);
x=x+b[j]*p[j].x;
y=y+b[j]*p[j].y;
}
lineto(int(x),int(y));
}
lineto(p[n-1].x,p[n-1].y);
}
void paint_outside(POINT *p,int n){
int i;
setcolor(GREEN);
moveto(p[0].x,p[0].y);
for(i=0;i<n;i++){
lineto(p[i].x,p[i].y);
}
}
void main(){
int n=0;
initgraph(640,480);
MOUSEMSG msg;
POINT p[100];
while (true){
msg = GetMouseMsg();
if (msg.uMsg == WM_LBUTTONDOWN){//初始点击鼠标左键绘制坐标点
setcolor(GREEN);
circle(msg.x, msg.y, 3);
p[n].x=msg.x;
p[n].y=msg.y;
n++;
}
if (msg.uMsg == WM_RBUTTONDOWN){//点击鼠标右键退出循环,绘制抛物线
paint_outside(p,n);
paint_bezier(p,n);
n=0;
}
}
_getch();
closegraph();
}
演示如下:
绘制抛物样条曲线
//功 能:鼠标控制绘制抛物样条曲线,左键单击时绘制实心圆,右键单击后绘制抛物线
// 编译环境:Visual C++ 6.0,EasyX_20190219(beta)
#include<iostream>
#include<graphics.h>
#include<conio.h>
#include<stdio.h>
#include<math.h>
using namespace std;
void parspl(int p[][2],int n,int k,int e){
int x,y,i,j,m;
double t1,t2,t3,t,a,b,c,d;
if(e==1){
m=n;
p[0][0]=p[1][0];
p[0][1]=p[1][1];
p[n+1][0]=p[n][0];
p[n+1][1]=p[n][1];
}
else{
m=n+1;
p[0][0]=p[n][0];
p[0][1]=p[n][1];
p[m][0]=p[1][0];
p[m][1]=p[1][1];
p[m+1][0]=p[2][0];
p[m+1][1]=p[2][1];
}
t=0.5/k;
moveto(p[1][0],p[1][1]);
for(i=0;i<m-1;i++){
for(j=1;j<k;j++){
t1=j*t;t2=t1*t1;t3=t2*t1;
a=-4.0*t3+4.0*t2-t1;
b=12.0*t3-10.0*t2+1.0;
c=-12.0*t3+8.0*t2+t1;
d=4.0*t3-2.0*t2;
x=a*p[i][0]+b*p[i+1][0]+c*p[i+2][0]+d*p[i+3][0];
y=a*p[i][1]+b*p[i+1][1]+c*p[i+2][1]+d*p[i+3][1];
lineto(x,y);
}
lineto(p[i+2][0],p[i+2][1]);
}
}
int main()
{
int n = 0, e, k = 15;
e = 1;
initgraph(640, 480);
MOUSEMSG msg;
int p[30][2];
setcolor(YELLOW);
setfillcolor(RED);
while (true){
msg = GetMouseMsg();
if (msg.uMsg == WM_LBUTTONDOWN) //初始点击鼠标左键绘制坐标点
{
fillcircle(msg.x, msg.y, 2);
p[n + 1][0] = msg.x;
p[n + 1][1] = msg.y;
n++;
}
if (msg.uMsg == WM_RBUTTONDOWN)//鼠标右键退出循环,绘制抛物线
break;
}
parspl(p, n, k, e);
_getch();
closegraph();
return 0;
}
红笔为起点,蓝笔为终点
鼠标右键: