zl程序教程

您现在的位置是:首页 >  其它

当前栏目

三阶贝塞尔曲线_三阶贝塞尔曲线公式

公式 曲线 贝塞尔 三阶
2023-06-13 09:14:40 时间

大家好,又见面了,我是你们的朋友全栈君。

目的:使用L-Edit绘制版图,其中有一段弯曲部分就是基于贝塞尔曲线画出来的。长这样↓

使用语言:C语言

写了两个版本。一个是基于L-edit平台的版本,一个是基于VS平台版本(我的是2017版)。这里说下VS的版本,不过VS里我就没有费心画出来了,只是列出了坐标来验证我L-Edit里面版图的正确性。

贝塞尔曲线是个啥可参考这篇:点击打开链接

简言之我们要画的三阶贝塞尔曲线就是通过四个点来拟合一条曲线。其中首尾二点在曲线上,中间两点只是确定方向用的,不在曲线上。

我遇到比较麻烦的问题是,我的已知条件只有四个点坐标,我需要“加粗”用这四个点画出的贝塞尔曲线,让它变成如图所示的两条平行贝塞尔曲线。

我开始的方法是:画出一条以后,y方向移动我需要的宽度,活生生移出一条曲线来。结果如下:

隐隐约约不太对劲(

单纯的y向平移显然不适合这种gay里gay气的曲线(不是钢铁直线对不起了呢

然后我想到应该把每点的斜率算出来,然后在法向上平移,这个方法是可行的,只是比较麻烦,我写了一半就想回去洗澡了。

为了节省时间,我参考了第三种方法。戳戳->点击打开链接

简言之就是从四个已知点下手,通过平移点,来平移曲线。这样一来我只需要操作四个点就行,十分方便。结果就如我一开始放的图那样。

下面放上程序:

// DCtest3.cpp: 定义控制台应用程序的入口点。 // /******************风格看起来有点奇怪不要介意,因为是从L-edit改过来的*****************************/ #include "stdafx.h" #include <stdlib.h> #include <math.h> #include <stdio.h> void sub_2(double x, double y, struct D_C dc); /*定义变量*/ struct D_C { double Lc, Lw, Ls, base_width, gap, y_span, w2, y_2; /* # Lc: length of the central straight waveguide sections for coupling # Lw: length of the four individual straight waveguide sections # at the input and output ports # Ls: x span of the four individual s-bend sections # base width: width of the waveguide base # gap: gap between two coupling sections # y span: center-to-center distance between the two input ports # w2:base_width/2; y_2:y_span/2; */ double x1, y1; double x2, y2; double x3, y3; double x4, y4; double x11, y11; double x22, y22; double x33, y33; double x44, y44; double factor; char* WG; }dc; int main() { double x0 = 0; double y0 = 0; dc.factor = 1.0e3; dc.Lc = 30 * dc.factor; dc.Lw = 3 * dc.factor; dc.Ls = 5 * dc.factor; dc.base_width = 0.5*dc.factor; dc.gap = 0.4*dc.factor; dc.y_span = 8 * dc.factor; dc.w2 = dc.base_width / 2; dc.y_2 = dc.y_span / 2; //中心曲线坐标(左上) dc.x1 = dc.Lw, dc.y1 = dc.y_2; dc.x2 = dc.Lw + dc.Ls / 2, dc.y2 = dc.y_2; dc.x3 = dc.Lw + dc.Ls / 2, dc.y3 = dc.gap / 2 + dc.w2; dc.x4 = dc.Lw + dc.Ls, dc.y4 = dc.gap / 2 + dc.w2; dc.x11 = dc.x1, dc.y11 = -dc.y1; dc.x22 = dc.x2, dc.y22 = -dc.y2; dc.x33 = dc.x3, dc.y33 = -dc.y3; dc.x44 = dc.x4, dc.y44 = -dc.y4; sub_2(x0, y0, dc);//弯曲波导左上 getchar(); return 0; } /*****贝塞尔曲线公式*****/ /******这个是百度来的可以直接用,当然也可以自己写成之前链接里面的那种标准格式, 我两种都试过,都ok的*****emmm注释比较随意懒得搞了**********/ //n!/k! int zuhe(int n, int k) { int i, s1, s2; s1 = 1, s2 = 1; if (k == 0) return 1; for (i = n; i >= n - k + 1; i--) s1 = s1 * i; for (i = k; i >= 2; i--) s2 = s2 * i; return s1 / s2; } //n^k double fang(double n, int k) { if (k == 0) return 1; return pow(n, k); } //(n!/k!)*t^k*(1-t)*(n-k) double eiheihei(int n, int k, double t) { return zuhe(n, k)*fang(t, k)*fang(1 - t, n - k); } void sub_2(double x, double y, struct D_C dc) { double t[101] = { 0 }; double xa[101], ya[101]; double s = 0.00; int i; //t[i]从0取到1,步进0.01 for (i = 1; i<101; i++) { s = s + 0.01; t[i] = s; } //向上平移 for (i = 0; i<101; i++) { xa[i]=(dc.x1*eiheihei(3, 0, t[i]) + (dc.x2 + dc.w2)*eiheihei(3, 1, t[i]) + (dc.x3 + dc.w2)*eiheihei(3, 2, t[i]) + dc.x4*eiheihei(3, 3, t[i])); ya[i] = ((dc.y1 + dc.w2)*eiheihei(3, 0, t[i]) + (dc.y2 + dc.w2)*eiheihei(3, 1, t[i]) + (dc.y3 + dc.w2)*eiheihei(3, 2, t[i]) + (dc.y4 + dc.w2)*eiheihei(3, 3, t[i])); printf("i:%d (%f,%f);\n", i, xa[i], ya[i]); } printf("\n\n"); //向下平移 for (i = 0; i<101; i++) { int j = 102 + i; xa[i]= (dc.x4*eiheihei(3, 0, t[i]) + (dc.x3 - dc.w2)*eiheihei(3, 1, t[i]) + (dc.x2 - dc.w2)*eiheihei(3, 2, t[i]) + dc.x1*eiheihei(3, 3, t[i])); ya[i] = ((dc.y4 - dc.w2)*eiheihei(3, 0, t[i]) + (dc.y3 - dc.w2)*eiheihei(3, 1, t[i]) + (dc.y2 - dc.w2)*eiheihei(3, 2, t[i]) + (dc.y1 - dc.w2)*eiheihei(3, 3, t[i])); printf("i:%d (%f,%f);\n", j, xa[i], ya[i]); } }

运行结果:

图我是在L-edit里画的,以上程序只有坐标,没有费心画图了,要画图的话改改就能用。

贝塞尔函数参考程序:点击打开链接

【以上程序属于七改八改加点小原创写出来的,如有不正确的地方欢迎指正。】

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/191617.html原文链接:https://javaforall.cn