{"id":16558776,"url":"https://github.com/pengmaster/bezier","last_synced_at":"2026-04-19T02:33:02.053Z","repository":{"id":143248464,"uuid":"187797509","full_name":"pengMaster/Bezier","owner":"pengMaster","description":"二次贝塞尔曲线 ， 三次贝塞尔曲线","archived":false,"fork":false,"pushed_at":"2019-05-21T08:50:39.000Z","size":127,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-07T09:45:17.133Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pengMaster.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-05-21T08:43:45.000Z","updated_at":"2025-06-25T09:46:22.000Z","dependencies_parsed_at":"2023-06-29T19:00:13.440Z","dependency_job_id":null,"html_url":"https://github.com/pengMaster/Bezier","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pengMaster/Bezier","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pengMaster%2FBezier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pengMaster%2FBezier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pengMaster%2FBezier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pengMaster%2FBezier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pengMaster","download_url":"https://codeload.github.com/pengMaster/Bezier/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pengMaster%2FBezier/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31991989,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T20:23:41.531Z","updated_at":"2026-04-19T02:33:02.025Z","avatar_url":"https://github.com/pengMaster.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 二次贝塞尔曲线\n\n\n## 贝塞尔曲线简介\n\n\n贝塞尔曲线(Bézier curve)，又称[贝兹](http://baike.baidu.com/item/%E8%B4%9D%E5%85%B9)曲线或贝济埃曲线，是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线，贝兹曲线由[线段](http://baike.baidu.com/item/%E7%BA%BF%E6%AE%B5)与[节点](http://baike.baidu.com/item/%E8%8A%82%E7%82%B9)组成，节点是可拖动的支点，线段像可伸缩的皮筋，我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。贝塞尔曲线是计算机图形学中相当重要的参数曲线，在一些比较成熟的位图软件中也有贝塞尔[曲线工具](http://baike.baidu.com/item/%E6%9B%B2%E7%BA%BF%E5%B7%A5%E5%85%B7)，如PhotoShop等。在Flash4中还没有完整的曲线工具，而在Flash5里面已经提供出贝塞尔曲线工具。\n\n贝塞尔曲线于1962，由法国工程师皮埃尔·贝塞尔（Pierre Bézier）所广泛发表，他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由Paul de Casteljau于1959年运用de Casteljau演算法开发，以稳定数值的方法求出贝兹曲线。\n\n以上内容从采取自百度百科\n\n贝塞尔曲线目前被广泛应用于计算机制图中，可以说贝塞尔曲线奠定了计算机制图的基础。\n\n\n# Android中绘制Path的API\n\nAndroid中绘制Path常用方法：\n\n| 作用          | 相关方法                                     | 备注                                       |\n| ----------- | ---------------------------------------- | ---------------------------------------- |\n| 移动起点        | moveTo                                   | 移动下一次操作的起点位置                             |\n| 设置终点        | setLastPoint                             | 重置当前path中最后一个点位置，如果在绘制之前调用，效果和moveTo相同   |\n| 连接直线        | lineTo                                   | 添加上一个点到当前点之间的直线到Path                     |\n| 闭合路径        | close                                    | 连接第一个点连接到最后一个点，形成一个闭合区域                  |\n| 添加内容        | addRect, addRoundRect,  addOval, addCircle, \taddPath, addArc, arcTo | 添加(矩形， 圆角矩形， 椭圆， 圆， 路径， 圆弧) 到当前Path (注意addArc和arcTo的区别) |\n| 是否为空        | isEmpty                                  | 判断Path是否为空                               |\n| 是否为矩形       | isRect                                   | 判断path是否是一个矩形                            |\n| 替换路径        | set                                      | 用新的路径替换到当前路径所有内容                         |\n| 偏移路径        | offset                                   | 对当前路径之前的操作进行偏移(不会影响之后的操作)                |\n| 贝塞尔曲线       | quadTo, cubicTo                          | 分别为二次和三次贝塞尔曲线的方法                         |\n| rXxx方法      | rMoveTo, rLineTo, rQuadTo, rCubicTo      | **不带r的方法是基于原点的坐标系(偏移量)， rXxx方法是基于当前点坐标系(偏移量)** |\n| 填充模式        | setFillType, getFillType, isInverseFillType, toggleInverseFillType | 设置,获取,判断和切换填充模式                          |\n| 提示方法        | incReserve                               | 提示Path还有多少个点等待加入**(这个方法貌似会让Path优化存储结构)** |\n| 布尔操作(API19) | op                                       | 对两个Path进行布尔运算(即取交集、并集等操作)                |\n| 计算边界        | computeBounds                            | 计算Path的边界                                |\n| 重置路径        | reset, rewind                            | 清除Path中的内容\u003cbr/\u003e **reset不保留内部数据结构，但会保留FillType.**\u003cbr/\u003e **rewind会保留内部的数据结构，但不保留FillType** |\n| 矩阵操作        | transform                                | 矩阵变换                                     |\n\n\n\n贝塞尔曲线应用简单场景：\n\n- QQ小红点拖拽效果\n- 平滑的折线图的制作\n- 阅读软件的翻书效果\n\n\n\n## 绘制贝塞尔曲线\n\n\n\n### 一阶贝塞尔曲线\n\n\n\n一阶贝塞尔曲线的原理就是一条直线，其实就是直接画了一个Path出来，在这里不做过多的介绍，本文主要介绍的是二阶的贝塞尔曲线。\n\n\n\n### 二阶贝塞尔曲线\n\n\n\n二阶贝塞尔曲线效果图：\n\n![bezier](https://ws2.sinaimg.cn/large/006tKfTcly1fgw7fga6nkg30ay0h27iz.gif)\n\n\n\n\n\n### 实现原理\n\n二阶曲线由两个数据点(A 和 C)，一个控制点(B)来描述曲线状态，大致如下：\n\n![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f35p4913k7j308c0dw74d.jpg)\n\n上图中红色曲线部分就是传说中的二阶贝塞尔曲线，那么这条红色曲线是如何生成的呢？接下来我们就以其中的一个状态分析一下：\n\n![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f361bjqj2vj308c0dwwem.jpg)\n\n连接AB BC，并在AB上取点D，BC上取点E，使其满足条件：\n\u003cimg src=\"http://chart.googleapis.com/chart?cht=tx\u0026chl=%5Cfrac%7BAD%7D%7BAB%7D%20%3D%20%5Cfrac%7BBE%7D%7BBC%7D\" style=\"border:none;\" /\u003e\n\n![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f361oje6h1j308c0dwdg0.jpg)\n\n连接DE，取点F，使得:\n\n``AD／AB = BE／BC = DF／DE``\n\n\n\n这样获取到的点F就是贝塞尔曲线上的一个点，动态过程如下：\n\n![](https://upload.wikimedia.org/wikipedia/commons/3/3d/B%C3%A9zier_2_big.gif)\n\n\n\n### 实现代码\n\n\n\n```java\npublic class Bezier2 extends View {\n\n    private Paint mPaint;\n    private int centerX, centerY;\n\n    private PointF start, end, control;\n\n    public Bezier2(Context context) {\n        super(context);\n        mPaint = new Paint();\n        mPaint.setColor(Color.BLACK);\n        mPaint.setStrokeWidth(8);\n        mPaint.setStyle(Paint.Style.STROKE);\n        mPaint.setTextSize(60);\n\n        start = new PointF(0,0);\n        end = new PointF(0,0);\n        control = new PointF(0,0);\n    }\n\n\n    public Bezier2(Context context, @Nullable AttributeSet attrs) {\n        super(context, attrs);\n        mPaint = new Paint();\n        mPaint.setColor(Color.BLACK);\n        mPaint.setStrokeWidth(8);\n        mPaint.setStyle(Paint.Style.STROKE);\n        mPaint.setTextSize(60);\n\n        start = new PointF(0,0);\n        end = new PointF(0,0);\n        control = new PointF(0,0);\n    }\n\n    @Override\n    protected void onSizeChanged(int w, int h, int oldw, int oldh) {\n        super.onSizeChanged(w, h, oldw, oldh);\n        centerX = w/2;\n        centerY = h/2;\n\n        // 初始化数据点和控制点的位置\n        start.x = centerX-200;\n        start.y = centerY;\n        end.x = centerX+200;\n        end.y = centerY;\n        control.x = centerX;\n        control.y = centerY-100;\n    }\n\n    @Override\n    public boolean onTouchEvent(MotionEvent event) {\n        // 根据触摸位置更新控制点，并提示重绘\n        control.x = event.getX();\n        control.y = event.getY();\n        invalidate();\n        return true;\n    }\n\n    @Override\n    protected void onDraw(Canvas canvas) {\n        super.onDraw(canvas);\n\n        // 绘制数据点和控制点\n        mPaint.setColor(Color.GRAY);\n        mPaint.setStrokeWidth(20);\n        canvas.drawPoint(start.x,start.y,mPaint);\n        canvas.drawPoint(end.x,end.y,mPaint);\n        canvas.drawPoint(control.x,control.y,mPaint);\n\n        // 绘制辅助线\n        mPaint.setStrokeWidth(4);\n        canvas.drawLine(start.x,start.y,control.x,control.y,mPaint);\n        canvas.drawLine(end.x,end.y,control.x,control.y,mPaint);\n\n        // 绘制贝塞尔曲线\n        mPaint.setColor(Color.RED);\n        mPaint.setStrokeWidth(8);\n\n        Path path = new Path();\n\n        path.moveTo(start.x,start.y);\n        path.quadTo(control.x,control.y,end.x,end.y);\n\n        canvas.drawPath(path, mPaint);\n    }\n}\n\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpengmaster%2Fbezier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpengmaster%2Fbezier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpengmaster%2Fbezier/lists"}