贝塞尔曲线工具类

article/2025/10/18 19:33:49

贝塞尔曲线工具类

先上一张效果图看效果
在这里插入图片描述

贝塞尔曲线

用于计算N阶贝塞尔曲线上的点,根据传入控制点的个数判定阶数N
贝塞尔曲线计算公式:
在这里插入图片描述

  • 工具类源码
public class BezierUtils {/*** 获取二项式系数** @param l 行(杨辉三角)* @param c 列(杨辉三角)* @return 系数*/private static int getBinomialCoefficient(@IntRange(from = 0) int l, @IntRange(from = 0) int c) {int lotteryOdds = 1;for (int i = 1; i <= c; i++)lotteryOdds = lotteryOdds * (l - i + 1) / i;return lotteryOdds;}/*** 获取贝塞尔曲线上t位置的点** @param t      变化值* @param points 控制点* @return 当前t对应的点*/public static PointF getBezierPoint(@FloatRange(from = 0, to = 1) float t, List<PointF> points) {if (points == null || points.size() < 2)return null;PointF result = new PointF();int n = points.size() - 1;//N阶for (int i = 0; i <= n; i++) {int binomialCoefficient = getBinomialCoefficient(n, i);double v = Math.pow(1 - t, n - i) * Math.pow(t, i);result.x += binomialCoefficient * (points.get(i).x * v);result.y += binomialCoefficient * (points.get(i).y * v);}return result;}/*** 获取贝塞尔曲线上t位置的点** @param t      变化值* @param points 控制点* @return 当前t对应的点*/public static PointF getBezierPoint(@FloatRange(from = 0, to = 1) float t, PointF... points) {if (points == null || points.length < 2)return null;return getBezierPoint(t, Arrays.asList(points));}/*** 获取贝塞尔曲线路径** @param precision  生成路径分段的精度* @param points 控制点* @return 贝塞尔曲线路径*/public static Path getBezierPath(@IntRange(from = 1) int precision, List<PointF> points) {if (precision < 1 || points == null || points.size() < 2)return null;float division = 1f / precision;float t = division;PointF lastP = points.get(0);Path path = new Path();path.moveTo(lastP.x, lastP.y);while (t < 1) {PointF point = getBezierPoint(t, points);path.lineTo(point.x, point.y);t += division;}PointF endP = points.get(points.size() - 1);path.lineTo(endP.x, endP.y);return path;}/*** 获取贝塞尔曲线路径** @param precision  生成路径分段的精度* @param points 控制点* @return 贝塞尔曲线路径*/public static Path getBezierPath(@IntRange(from = 1) int precision, PointF... points) {if (precision < 1 || points == null || points.length < 2)return null;return getBezierPath(precision, Arrays.asList(points));}
}

示例代码

public class MyView extends View {private PointF f1;private PointF f2;private PointF f3;private PointF f4;private Paint paint;private Paint paint2;private Paint paint3;private Path path1;private Path path2;private Path path3;private PointF point;private PointF point1;private PointF point2;public MyView(Context context) {this(context, null);}public MyView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);paint = new Paint();paint.setStrokeWidth(20);paint.setColor(Color.RED);paint.setAntiAlias(true);paint.setDither(true);paint2 = new Paint();paint2.setStrokeWidth(10);paint2.setColor(Color.BLUE);paint2.setStyle(Paint.Style.STROKE);paint2.setAntiAlias(true);paint2.setDither(true);paint3 = new Paint();paint3.setStrokeWidth(15);paint3.setColor(Color.YELLOW);paint3.setAntiAlias(true);paint3.setDither(true);path1 = new Path();path2 = new Path();path3 = new Path();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);int measuredHeight = getMeasuredHeight();int measuredWidth = getMeasuredWidth();f1 = new PointF(measuredWidth / 3, measuredHeight / 3);f2 = new PointF(measuredWidth / 3, measuredHeight / 3 * 2);f3 = new PointF(measuredWidth / 3 * 2, measuredHeight / 3);f4 = new PointF(measuredWidth / 3 * 2, measuredHeight / 3 * 2);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//画四个控制点(图中黑色的四个点)canvas.drawPoint(f1.x, f1.y, paint);canvas.drawPoint(f2.x, f2.y, paint);canvas.drawPoint(f3.x, f3.y, paint);canvas.drawPoint(f4.x, f4.y, paint);//系统API画3阶贝塞尔曲线(图中蓝色线条)path1.moveTo(f1.x, f1.y);path1.cubicTo(f1.x, f1.y, f2.x, f2.y, f3.x, f3.y);paint2.setColor(Color.BLUE);canvas.drawPath(path1, paint2);//系统API画3阶贝塞尔曲线(图中绿色线条)path2.moveTo(f1.x, f1.y);path2.cubicTo(f2.x, f2.y, f3.x, f3.y, f4.x, f4.y);paint2.setColor(Color.GREEN);canvas.drawPath(path2, paint2);//系统API画2阶贝塞尔曲线(图中灰色线条)path3.moveTo(f1.x, f1.y);paint2.setColor(Color.LTGRAY);path3.quadTo(f2.x, f2.y, f4.x, f4.y);canvas.drawPath(path3, paint2);//画图中三个黄色变动的点(取自灰色线条)if (point != null) {canvas.drawPoint(point.x, point.y, paint3);}//画图中三个黄色变动的点(取自蓝色线条)if (point1 != null) {canvas.drawPoint(point1.x, point1.y, paint3);}//画图中三个黄色变动的点(取自绿色线条)if (point2 != null) {canvas.drawPoint(point2.x, point2.y, paint3);}}//画图中三个黄色变动的点(取自灰色线条)public void drawPoint(@FloatRange(from = 0, to = 1) float t) {point = BezierUtils.getBezierPoint(t, f1, f2, f4);invalidate();}//画图中三个黄色变动的点(取自绿色线条)public void drawPoint2(@FloatRange(from = 0, to = 1) float t) {point2 = BezierUtils.getBezierPoint(t, f1, f2, f3, f4);invalidate();}//画图中三个黄色变动的点(取自蓝色线条)public void drawPoint1(@FloatRange(from = 0, to = 1) float t) {point1 = BezierUtils.getBezierPoint(t, f1, f1, f2, f3);invalidate();}
}
相关

仿直播送礼物控件:https://blog.csdn.net/TomCat0916/article/details/105143646
自定义翻书效果控件:https://blog.csdn.net/TomCat0916/article/details/105753657

参考

贝塞尔曲线
杨辉三角


http://chatgpt.dhexx.cn/article/qwqHj9Ed.shtml

相关文章

贝塞尔曲线打断生成两个贝塞尔曲线

问题&#xff1a;如何将一个三阶贝塞尔曲线打断生成两个三阶贝塞尔曲线&#xff0c;生成的两条贝塞尔曲线与原来的贝塞尔曲线重合&#xff1f; 输入&#xff1a;一条贝塞尔曲线的四个控制点P1,C1,C2,P2,和一个打断点E(E在曲线上) 输出&#xff1a;两条贝塞尔曲线: P1,F,I,E E,J…

html5贝塞尔曲线,Canvas学习:贝塞尔曲线

在绘制圆和圆弧一节中,了解到在Canvas中可以使用arc()和arcTo()绘制制圆或弧线,但很多时候,仅这两个方法还不能满足我们实际的需求,特别是绘制复杂的曲线。不过值得庆幸的是,在Canvas中还提供了其他的方法可以帮助我们绘制复杂的曲线。那就是我们今天要说的贝塞尔曲线,在…

贝塞尔曲线(Bezier Curve)

有兴趣的建议看这篇&#xff0c;比较新&#xff1a;https://zhuanlan.zhihu.com/p/366678047 曲线和曲面 在生活中存在着各种各样光滑的曲线或曲面&#xff0c;例如汽车的表面&#xff0c;钢珠球等。 在建模的时候&#xff0c;我们通常使用很多的小三角形来逼近这样的曲面&am…

java贝塞尔曲线_贝塞尔曲线学习

贝塞尔曲线学习 1.贝塞尔曲线 以下公式中: B(t)为t时间下 点的坐标; P0为起点,Pn为终点,Pi为控制点 一阶贝塞尔曲线(线段): 一阶贝塞尔曲线公式 一阶贝塞尔曲线演示 意义:由 P0 至 P1 的连续点, 描述的一条线段 二阶贝塞尔曲线(抛物线): 二阶贝塞尔曲线公式 二阶贝塞尔曲…

贝塞尔曲线

一&#xff1a;简介 1962年&#xff0c;法国工程师贝塞尔发表&#xff0c;他运用贝塞尔曲线来为汽车的主体进行设计。 贝塞尔曲线是最基本的曲线&#xff0c;一般用在计算机 图形学和 图像处理。贝塞尔曲线可以用来创建平滑的曲线的道路、 弯曲的路径就像 祖玛游戏、 弯曲型的…

【Unity3d游戏开发】游戏中的贝塞尔曲线以及其在Unity中的实现

RT&#xff0c;马三最近在参与一款足球游戏的开发&#xff0c;其中涉及到足球的各种运动轨迹和路径&#xff0c;比如射门的轨迹&#xff0c;高吊球&#xff0c;香蕉球的轨迹。最早的版本中马三是使用物理引擎加力的方式实现的足球各种运动&#xff0c;后来的版本中使用了根据物…

Bezier Curve贝塞尔曲线概念

一、贝塞尔曲线的概念 对于两点之间的连线&#xff0c;我们可以用直线进行连接效果如下&#xff1a; 其中的每一个F点都在AB连接的线段上。 这就是一阶贝塞尔曲线。 如果我们加入一个控制点C&#xff0c;那么做图如下&#xff1a; 1、连接AC,BC&#xff1b; 2、在AC,B…

贝塞尔(贝兹尔)曲线介绍

2019独角兽企业重金招聘Python工程师标准>>> 贝塞尔(贝兹尔)曲线介绍 什么是贝塞尔曲线&#xff1f; “贝赛尔曲线”是由法国数学家Pierre Bzier所发明&#xff0c;由此为计算机矢量图形学奠定了基础。它的主要意义在于无论是直线或曲线都能在数学上予以描述。贝塞尔…

【ARM】-栈帧

ARM 栈帧 本系列均以 corter-A7(armv7-a) 为例 在 ARM 中&#xff0c;通常为满减栈&#xff08;Full Descending FD&#xff09;, 也就是说&#xff0c;堆栈指针指向堆栈内存中最后一个填充的位置&#xff0c;并且随着每个新数据项被压入堆栈而递减。 栈的本质 要理解栈的本…

JVM 栈和栈帧

tag: jvm,stack,stack frame,栈,栈帧 原文&#xff1a;JVM Stacks and Stack Frames 翻译&#xff1a;陈同学 欢迎访问陈同学博客原文&#xff0c;文章可读性更佳 前情提要 对于没有深度递归的函数来说&#xff0c;无需担心上篇文章中的算法。当知道正在处理数据集有限时&am…

C语言的函数栈帧

⭐️前面的话⭐️ &#x1f4d2;博客主页&#xff1a;未见花闻的博客主页 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4cc;本文由未见花闻原创&#xff0c;CSDN首发&#xff01; ✉️坚持和努力一定能换来诗与远方&#xff01; &…

【C语言】函数栈帧的创建和销毁(1)

前言&#xff1a; ❓ 在我们前期学习C语言时&#xff0c;你是否曾产生过很多困惑&#xff1f; &#x1f4ad; 比如&#xff1a;局部变量是怎么创建出来的&#xff1f;因为局部变量的值是随机值&#xff0c;我们建议将它初始化&#xff0c;那么为什么局部变量的值是随机值&am…

函数栈帧(详解版)

文章目录 前言1.浅谈C语言内存1.1 内存分配1.2 栈1.3 寄存器 2. 为main()函数开辟栈帧3.变量的初始化及函数调用4.ADD函数4.1 ADD函数的创建4.2 ADD函数使用与销毁 5.总结 前言 前期学习的时候&#xff0c;我们可能有很多困感? 比如: ●局部变量是怎么创建的?I为什么局部变量…

也谈栈和栈帧

&#xfeff;&#xfeff; 一个码农要是没遇见过coredump&#xff0c;那他就是神仙了。core file(coredump的转储文件)中保存的最重要内容之一&#xff0c;就是函数的call trace。还原这部分内容 (栈回溯) &#xff0c;并与原代码对应上&#xff0c;尽快找出程序崩溃的位置和…

(栈帧和函数调用一)栈帧,函数调用与栈的关系

&#xff08;栈帧和函数调用一&#xff09;栈帧&#xff0c;函数调用与栈的关系 一&#xff0c;栈帧的介绍二&#xff0c;函数调用与栈的关系三&#xff0c;汇编演示四&#xff0c;总结 在计算机科学中&#xff0c;栈是一个特殊的容器&#xff0c;用户可以将数据压入栈中&#…

理解栈帧和栈的运行原理

栈中的数据都是以栈帧&#xff08;Stack Frame&#xff09;的格式存在&#xff0c;栈帧是一个内存区块&#xff0c;是一个数据集&#xff0c;是一个有关方法 (Method) 和运行期数据的数据集&#xff0c;当一个方法A被调用时就产生了一个栈帧 F1&#xff0c;并被压入到栈中&…

函数栈帧的形成与释放

✅作者简介&#xff1a;嵌入式入坑者&#xff0c;与大家一起加油&#xff0c;希望文章能够帮助各位&#xff01;&#xff01;&#xff01;&#xff01; &#x1f4c3;个人主页&#xff1a;rivencode的个人主页 &#x1f525;系列专栏&#xff1a;玩转C语言 &#x1f4ac;推荐一…

【函数栈帧的创建和销毁】(超详细图解)

想必大家在学完C语言函数章节之后&#xff0c;是否有这样的困惑&#xff1a; 局部变量是怎么创建的 &#xff1f; 为什么局部变量的值是随机值 &#xff1f; 函数是怎么传参的&#xff1f;传参的顺序又是什么样的 &#xff1f; 形参和实参是什么关系 &#xff1f; 函数调用…

C语言函数栈帧详解

系列文章目录 前言 最近正在学习栈帧方面的知识&#xff0c;由于本人对汇编不太熟悉&#xff0c;对其中频繁出现的ESP寄存器和EBP寄存器一直没搞清楚&#xff0c;在查找资料后&#xff0c;在此进行整理&#xff0c;方便以后温故知新。 一、预备知识 要清楚理解栈帧的概念&…

详解栈帧结构

https://www.1024do.com/?p367 栈帧结构 含义&#xff1a;C语言中&#xff0c;每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。栈帧也叫过程活动记录&#xff0c;是编译器用来实现过程函数调用的一种数据结构。 从逻辑上讲&#xff0c;栈帧就是…