网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
02月06日漏签0天
easyx吧 关注:10,683贴子:46,072
  • 看贴

  • 图片

  • 吧主推荐

  • 游戏

  • 4回复贴,共1页
<<返回easyx吧
>0< 加载中...

贝塞尔曲线的动态展示程序,很好玩

  • 只看楼主
  • 收藏

  • 回复
  • yangw80
  • 吧主
    12
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
作者:luyiran <872289455@qq.com>
先上图:


  • yangw80
  • 吧主
    12
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
完整代码:


/////////////////////////////////////////////////////////////
// 程序名称:贝塞尔曲线
// 编译环境:Visual Studio 2019 (v142) x86,EasyX_20211109_x86
// 作  者:luyiran <872289455@qq.com>
// 发布日期:2021-11-18
//
#include <math.h>// sin
#include <stdint.h>// uint64_t
#include <vector>// array
#include <graphics.h>// window


using std::vector;


#defineWIDTH800// 宽
#defineHEIGHT600// 高


struct Point { double x, y; };


// 初始化控制点
vector<Point> controlPoints;


Point operator+(const Point& a, const Point& b)
{
return Point({ a.x + b.x, a.y + b.y });
}
Point operator*(double f, const Point& p)
{
return Point({f*p.x, f*p.y});
}


// 计算二项式系数:C(n, k) = n! / (k!(n-k)!)
// 这里我们不用公式,使用 Pascal's Triangle
// [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
int C(int n, int k)
{
vector<int> array(n + 1, 1);
for (int i = 2; i <= n; i++)
for (int j = i - 1; j > 0; j--)
array[j] += array[j - 1];
return array[k];
}


// 绘制贝塞尔曲线,绘制 t [0 - end_t] 范围
void drawBezier(const vector<Point>& points, double end_t)
{
if (points.size() <= 1) return;
int n = points.size() - 1; // 阶次为点数 - 1
setfillcolor(RED);
for (double t = 0.0; t <= end_t; t += 0.001)
{
Point p{ 0 };
for (int k = 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);
}
}


// 递归获取每一层的控制点
void bezierLevelPoints(vector<vector<Point>>& levels, double t)
{
vector<Point> &pre = levels.back();
vector<Point> next;
int n = pre.size();
if (n <= 1) return;

for (int i = 0; i < n - 1; i++)
{
Point point = (1 - t) * pre[i] + t * pre[i + 1];
next.push_back(point);
}
levels.push_back(next);
bezierLevelPoints(levels, t);
}


// 处理输入事件
void processInput()
{
ExMessage msg;
if (peekmessage(&msg, EM_MOUSE | EM_KEY))
{
// 按住左键拖动控制点
if (WM_MOUSEMOVE == msg.message && msg.lbutton)
{
for (auto& p : controlPoints)
{
int dx = (int)p.x - msg.x;
int dy = (int)p.y - msg.y;
if (dx * dx + dy * dy < 50)
{
p.x = msg.x;
p.y = msg.y;
}
}
}
// 点击右键,创建控制点
else if (WM_RBUTTONDOWN == msg.message && msg.rbutton)
{
controlPoints.push_back({ (double)msg.x, (double)msg.y });
}
// 按空格键清空
else if (WM_KEYDOWN == msg.message && msg.vkcode == VK_SPACE)
{
controlPoints.clear();
}
}
}


// 画点、画线
void drawControlLines(vector<vector<Point>>& levels)
{
int k = levels.size();
COLORREF color[8] = { YELLOW, BROWN, CYAN, LIGHTRED, WHITE, GREEN, MAGENTA, RED };
for (int i = 0; i < k; i++)
{
vector<Point> cur = levels[i];
int n = 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 (int j = 0; j < n - 1; 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));
}
}


int main()
{
TCHAR buf[32];
double t = 0.f;
double time = -1.57079632679489661923;// pi / 2;
double deltaTime = 0.f;// 当前帧和上一帧的时间差
double lastTime = 0.f;
double currentTime = 0.f;
uint64_t start, 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<vector<Point>> levels({ controlPoints });
bezierLevelPoints(levels, t);
// 绘制控制点、控制线
drawControlLines(levels);
// 绘制 0 - t 范围内的贝塞尔曲线
drawBezier(controlPoints, t);


// 提示信息
outtextxy(0, 0, L" Right Mouse Button to Create Points.");
outtextxy(0, 16, L" Left Mouse Button to Drag Points.");
outtextxy(0, 32, L" Press SPACE to Clear.");
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\n"), (int)(1.f / deltaTime));
outtextxy(0, 80, buf);
FlushBatchDraw();
}
return 0;
}


4399游戏官网
竞技类游戏-越菜越爱玩!Q版实时竞技,多人对战弹射,搭配灵活多样的竞技手法,让你欲罢不能!单人,团体随时开战,活埋,深坑,卡敏,竞技对抗更high更过瘾!
2023-02-06 20:51广告
立即查看
  • yangw80
  • 吧主
    12
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
老规矩,需要完整代码格式的同学,请到 codebus 找。


  • 红--枫
  • 幼儿园
    2
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
大佬,请问你的这个 swprintf_s()实现都需要啥条件,外部以及()里边参数的类型。谢谢!


  • 阿润古
  • 托儿所
    1
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
大佬,请问image变量怎么清空啊,加载完一张我想再用这个变量加载另外一张,但是效果不好


登录百度帐号
sia-SIA艺术留学首页【SIA】
广告

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 4回复贴,共1页
<<返回easyx吧
分享到:
©2023 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示