Android Studio Canvas 实现鼠标贝塞尔曲线拖尾特效

本文详细介绍了如何使用Android Studio的Canvas结合贝塞尔曲线,实现鼠标拖尾特效。首先解释了贝塞尔曲线的概念和特点,然后通过四步指导读者创建新工程、编写Bezier函数、创建MainCanvas以及修改布局文件,最终实现动态的鼠标拖尾效果。
摘要由CSDN通过智能技术生成

Android Studio Canvas 实现鼠标贝塞尔曲线拖尾特效

特效预览图

在这里插入图片描述

什么是贝塞尔曲线?

百度百科:

​ 贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。

​ 贝塞尔曲线于1962,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由Paul de Casteljau于1959年运用de Casteljau演算法开发,以稳定数值的方法求出贝兹曲线。

​ 贝塞尔曲线是计算机图形图像造型的基本工具,是图形造型运用得最多的基本线条之一。它通过控制曲线上的四个点(起始点、终止点以及两个相互分离的中间点)来创造、编辑图形。其中起重要作用的是位于曲线中央的控制线。这条线是虚拟的,中间与贝塞尔曲线交叉,两端是控制端点。移动两端的端点时贝塞尔曲线改变曲线的曲率(弯曲的程度);移动中间点(也就是移动虚拟的控制线)时,贝塞尔曲线在起始点和终止点锁定的情况下做均匀移动。注意,贝塞尔曲线上的所有控制点、节点均可编辑。这种“智能化”的矢量线条为艺术家提供了一种理想的图形编辑与创造的工具。本文即用贝塞尔曲线实现鼠标拖尾特效。


理解贝塞尔曲线

贝塞尔曲线数学理解、推导方法:怎么理解贝塞尔曲线? - 知乎

本文bezier求点公式参考论文:Finding a Point on a Bézier Curve: De Casteljau’s Algorithm

引用 贝塞尔曲线简单介绍_xiaozhangcsdn的博客-CSDN博客_bezier曲线 对贝塞尔曲线理解关键点进行简要介绍:

对于贝塞尔曲线,最重要的点是数据点和控制点。
数据点: 指一条路径的起始点和终止点。
控制点:控制点决定了一条路径的弯曲轨迹
根据控制点的个数,贝塞尔曲线被分为一阶贝塞尔曲线(0个控制点)、二阶贝塞尔曲线(1个控制点)、三阶贝塞尔曲线(2个控制点)等等。

特点一:曲线通过始点和终点,并与特征多边形首末两边相切于始点和终点,中间点将曲线拉向自己。
特点二:平面离散点控制曲线的形状,改变一个离散点的坐标,曲线的形状将随之改变(点对曲线具有整体控制性)。
特点三:曲线落在特征多边形的凸包之内,它比特征多边形更趋于光滑。


贝塞尔曲线图示

引用自 贝塞尔曲线的数学原理_程序人生-CSDN博客_贝塞尔曲线原理

一阶贝塞尔曲线(线段):
在这里插入图片描述
在这里插入图片描述
意义:由 P0 至 P1 的连续点, 描述的一条线段

二阶贝塞尔曲线(抛物线):
在这里插入图片描述
在这里插入图片描述
原理:由 P0 至 P1 的连续点 Q0,描述一条线段。
由 P1 至 P2 的连续点 Q1,描述一条线段。
由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。

经验:P1-P0为曲线在P0处的切线。

三阶贝塞尔曲线:
在这里插入图片描述
在这里插入图片描述
通用公式:
在这里插入图片描述
高阶贝塞尔曲线:

4阶曲线:
在这里插入图片描述
5阶曲线:
在这里插入图片描述

好了,了解完以上贝塞尔曲线的知识,我们该如何用贝塞尔曲线在Android Studio上做特效呢?以本文所提鼠标拖尾特效为例:


第一步

创建新工程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9THZ1H0Z-1639291917480)(116052019057 刘睿 Android Studio Canvas 实现鼠标贝塞尔曲线拖尾特效.assets/image-20211212143658584.png)]
直接创建空白 activity 即可

package com.example.drawimagery;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
   

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }
}

第二步

因为 java 好像并未提供n阶贝塞尔函数的 api,所以我们就自己写一个

创建 Bezier 文件在这里插入图片描述

Bezier 文件作为主函数体文件,保存了 beizer(计算n阶贝塞尔曲线上点的位置)、factorial(阶乘)、rainBow(彩虹色)三个函数。其中贝塞尔曲线公式是运用下图公式计算得出

公式引用自 贝塞尔曲线 WPF MVVM N阶实现 公式详解+源代码下载 - ARM830 - 博客园
在这里插入图片描述在这里插入图片描述

  • n=有效坐标点数量
  • i=坐标点的下标
  • P=坐标
  • t=时间百分比,在0~1之间,覆盖了整条曲线

因为
在这里插入图片描述
可得
在这里插入图片描述
硬转换成 java 后其代码如下:

(因为本文项目使用 Queue 进行数据存储所以使用 LinkedList 结构)

package com.example.drawimagery;

import java.util.LinkedList;

public class Bezier {
   

    public static float[] bezier(LinkedList<Float> theArrayX, LinkedList<Float> theArrayY, float t){
    //贝塞尔公式调用
        float x = 0;
        float y = 0;
        //控制点数组
        int n = theArrayX.size() - 1;
        int size = theArrayX.size();
        for (
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 中,可以通过继承 View 或 SurfaceView 实现曲线。 一般来说,需要使用 Path 对象来绘制曲线。Path 对象可以通过 moveTo、lineTo、quadTo、cubicTo 等方法来绘制线条、二次曲线和三次曲线。其中,quadTo 和 cubicTo 方法用于绘制曲线。 下面是一个简单的例子,演示了如何在自定义视图中绘制一条二次曲线: ```java public class BezierView extends View { private Paint mPaint; private Path mPath; public BezierView(Context context) { this(context, null); } public BezierView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); mPath = new Path(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int startX = 100; int startY = getHeight() / 2; int endX = getWidth() - 100; int endY = getHeight() / 2; int controlX = getWidth() / 2; int controlY = getHeight() / 2 - 200; mPath.reset(); mPath.moveTo(startX, startY); mPath.quadTo(controlX, controlY, endX, endY); canvas.drawPath(mPath, mPaint); } } ``` 在这个例子中,我们绘制了一条二次曲线,起点为 `(startX, startY)`,终点为 `(endX, endY)`,控制点为 `(controlX, controlY)`。我们使用 `mPath.quadTo(controlX, controlY, endX, endY)` 方法来绘制曲线,并且在 `onDraw` 方法中调用 `canvas.drawPath(mPath, mPaint)` 来绘制出来。 当然,这只是一个非常简单的例子,实际使用中可能需要更多的控制点和更复杂的路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值