蓝因子教育C语言实现贝塞尔曲线!

点击鼠标右键,在鼠标位置将创建新的点。

按住鼠标左键拖动控制点。

空格键屏幕将清空。

一起来玩一玩吧!

运行效果

源代码

////////////////////////

//程序名称:贝塞尔曲线

//

#include//sin

#include//uint64_t

#include//array

#include//window

usingstd::vector;

#defineWIDTH800//宽

#defineHEIGHT600//高

structPoint{doublex,y;};

//初始化控制点

vectorcontrolPoints;

Pointoperator+(constPoint&a,constPoint&b)

{

returnPoint({a.x+b.x,a.y+b.y});

}

Pointoperator*(doublef,constPoint&p)

returnPoint({f*p.x,f*p.y});

//计算二项式系数:C(n,k)=n!/(k!(n-k)!)

//这里我们不用公式,使用Pascal'sTriangle

//[1],n=0

//[1,1],n=1

//[1,2,1],n=2

//[1,3,3,1],n=3

//[1,4,6,4,1],n=4

intC(intn,intk)

vectorarray(n+1,1);

for(inti=2;i<=n;i++)

for(intj=i-1;j>0;j--)

array[j]+=array[j-1];

returnarray[k];

//绘制贝塞尔曲线,绘制t[0-end_t]范围

voiddrawBezier(constvector&points,doubleend_t)

if(points.size()<=1)return;

intn=points.size()-1;//阶次为点数-1

setfillcolor(RED);

for(doublet=0.0;t<=end_t;t+=0.001)

Pointp{0};

for(intk=0;k<=n;k++)

p=p+C(n,k)*pow(t,k)*pow(1-t,(double)n-k)*points[k];

//位置四舍五入

p.x+=0.5;

p.y+=0.5;

solidcircle((int)p.x,(int)p.y,3);

//递归获取每一层的控制点

voidbezierLevelPoints(vector>&levels,doublet)

vector&pre=levels.back();

vectornext;

intn=pre.size();

if(n<=1)return;

for(inti=0;i

Pointpoint=(1-t)*pre[i]+t*pre[i+1];

next.push_back(point);

levels.push_back(next);

bezierLevelPoints(levels,t);

//处理输入事件

voidprocessInput()

ExMessagemsg;

while(peekmessage(&msg,EM_MOUSE|EM_KEY))

//按住左键拖动控制点

if(WM_MOUSEMOVE==msg.message&&msg.lbutton)

for(auto&p:controlPoints)

intdx=(int)p.x-msg.x;

intdy=(int)p.y-msg.y;

if(dx*dx+dy*dy<50)

p.x=msg.x;

p.y=msg.y;

//点击右键,创建控制点

elseif(WM_RBUTTONDOWN==msg.message&&msg.rbutton)

controlPoints.push_back({(double)msg.x,(double)msg.y});

//按空格键清空

elseif(WM_KEYDOWN==msg.message&&msg.vkcode==VK_SPACE)

controlPoints.clear();

//画点、画线

voiddrawControlLines(vector>&levels)

intk=levels.size();

COLORREFcolor[8]={YELLOW,BROWN,CYAN,LIGHTRED,WHITE,GREEN,MAGENTA,RED};

for(inti=0;i

vectorcur=levels[i];

intn=cur.size();

setlinecolor(color[i&0XF]);

setfillcolor(color[i&0XF]);

for(auto&point:cur)

solidcircle((int)(point.x+0.5),(int)(point.y+0.5),3);

if(k<=2)continue;

for(intj=0;j

line((int)(cur[j].x+0.5),(int)(cur[j].y+0.5),\

(int)(cur[j+1].x+0.5),(int)(cur[j+1].y+0.5));

intmain()

TCHARbuf[32];

doublet=0.f;

doubletime=-1.57079632679489661923;//pi/2;

doublelastTime=0.f;

doublecurrentTime=0.f;

uint64_tstart,now,frequency;

initgraph(WIDTH,HEIGHT);

BeginBatchDraw();

QueryPerformanceCounter((LARGE_INTEGER*)&start);

QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);

while(1)

cleardevice();

QueryPerformanceCounter((LARGE_INTEGER*)&now);

currentTime=(double)(now-start)/frequency;

deltaTime=currentTime-lastTime;

lastTime=currentTime;

//保证不同帧率下绘制速度一致

time+=1.5*deltaTime;

t=0.5*(1+sin(time));

//根据鼠标拖动更新控制点

processInput();

//得到每一层的控制点

vector>levels({controlPoints});

//绘制控制点、控制线

drawControlLines(levels);

//绘制0-t范围内的贝塞尔曲线

drawBezier(controlPoints,t);

//提示信息

outtextxy(0,0,L"RightMouseButtontoCreatePoints.");

outtextxy(0,16,L"LeftMouseButtontoDragPoints.");

outtextxy(0,32,L"PressSPACEtoClear.");

swprintf_s(buf,_T("t:%.3f"),t);

outtextxy(0,48,buf);

swprintf_s(buf,_T("time:%.0fms"),1000*deltaTime);

outtextxy(0,64,buf);

swprintf_s(buf,_T("fps:%d"),(int)(1.f/deltaTime));

outtextxy(0,80,buf);

FlushBatchDraw();

return0;

非常好玩的程序,大家可以自己动动手写出来,代码不多适合练手~

THE END
1.全网最完整的circos中文教程circos 是一款染色体相关数据的可视化软件,采用圆环的形式展示染色体上的相关信息,在多种组学数据的展示中广泛应用,本文整理了之前推送过的circos相关的学习资料 Circos 软件的安装详解 circos 配置文件解析 circos 可视化手册-ideogram 篇 circos 可视化手册-ticks 篇 ...https://www.360doc.cn/article/68068867_881784578.html
2.circos教程之染色体设置百迈客生物【circos教程】之染色体设置 先前已经大致介绍了circos软件的安装、配置文件、如何画图等。下面小编将详细介绍一下染色体的设置问题。 Ci …继续阅读【circos教程】之染色体设置http://www.biomarker.com.cn/archives/15794/embed
1.贝塞尔封闭曲线Pythonmob64ca12e41d46的技术博客贝塞尔曲线是一种数学曲线,广泛应用于计算机图形学、动画、图像处理等领域。通过控制点的不同组合,贝塞尔曲线可以精确地描绘出复杂的形状与路径。本文将详细探讨如何使用Python绘制贝塞尔封闭曲线,并配有示例代码和可视化图示,以便易于理解和学习。 贝塞尔曲线简介 ...https://blog.51cto.com/u_16213380/12687485
2.Circos手把手极简入门(Windows篇)最低配上手教程 安装好Circos后我们看到作者推荐从quick start系列教程开始学起,首先我们对circos的作图模式有一个了解,只有掌握作图逻辑才可以真正理解circos。 作图模式 本节学习使用最少的配置文件,先把图片画出来。随后再对需要的参数进行详细的研究。 https://www.jianshu.com/p/3ff6b91dfb19
3.CIRCOS教程翻译1.6——axe和backgroundcircosbackground条件CIRCOS教程翻译 1.6——axe和background axe和background属于坐标轴,前者是细线条,后者是宽线条- -!!!能这样翻译么- -!!!按照字面意思来讲,background是背景的意思,说那么多还不如画出来实在,例子添加了两个conf,但为了大家能看明白,将其写在主配置文件内比较容易理解,当然也可以多写个conf,使主配置文件简洁...https://blog.csdn.net/skenoy/article/details/8721500
4.谁说Python不能绘制环形基因组图?快看这个..pyCircos可通过如下语句进行快速安装(建议)。 代码语言:javascript 复制 pip install python-circos 如果想安装开发版本,则使用如下语句: 代码语言:javascript 复制 pip install git+https://github.com/ponnhide/pyCircos.git 案例教程 案例01 代码语言:javascript ...https://cloud.tencent.com/developer/article/2350678