• UE4 C++之实现二阶贝塞尔曲线
2021-10-09 15:38:17

任务：实现物体沿着二阶贝塞尔曲线运动

原理介绍参考链接：贝塞尔曲线 总结_PlayBoy's 部落格-CSDN博客_贝塞尔曲线

关键代码如下：

BezierCurve.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "BezierCurve.generated.h"

UCLASS()
class DATALEARN_API ABezierCurve : public AActor
{
GENERATED_BODY()

public:
// Sets default values for this actor's properties
ABezierCurve();

protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;

public:
// Called every frame
virtual void Tick(float DeltaTime) override;

private:
void SetMeshToBezierCurve(double curTime);

public:
class UStaticMeshComponent* Mesh;
class UStaticMeshComponent* StartMesh;
class UStaticMeshComponent* FirstMesh;
class UStaticMeshComponent* FinalMesh;

FVector FirstPos;
FVector FinalPos;
float DurationTime;

private:
double StartTime;
};


BezierCurve.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "BezierCurve.h"
#include "Components/StaticMeshComponent.h"
#include "DrawDebugHelpers.h"
#include "Kismet/GameplayStatics.h"

// Sets default values
ABezierCurve::ABezierCurve()
{
// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;

StartMesh = CreateDefaultSubobject<UStaticMeshComponent>("StartMesh");
RootComponent = StartMesh;
FirstMesh = CreateDefaultSubobject<UStaticMeshComponent>("FirstMesh");
FinalMesh = CreateDefaultSubobject<UStaticMeshComponent>("FinalMesh");
Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");

DurationTime = 2000;
}

// Called when the game starts or when spawned
void ABezierCurve::BeginPlay()
{
Super::BeginPlay();
FirstPos = FirstMesh->GetRelativeLocation();
FinalPos = FinalMesh->GetRelativeLocation();
StartTime = FPlatformTime::ToMilliseconds64(FPlatformTime::Cycles64());

FVector actorLocation = GetActorLocation();
UWorld* myWorld = GetWorld();
DrawDebugLine(myWorld, actorLocation, actorLocation + FirstPos, FColor::Red, true);
DrawDebugLine(myWorld, actorLocation + FirstPos, actorLocation + FinalPos, FColor::Red, true);
}

// Called every frame
void ABezierCurve::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
double curTime = FPlatformTime::ToMilliseconds64(FPlatformTime::Cycles64());
SetMeshToBezierCurve(curTime);
}

void ABezierCurve::SetMeshToBezierCurve(double curTime)
{
float tmpT = fmod(curTime - StartTime, DurationTime) / DurationTime;
FVector resLocation;
resLocation.X = 2 * tmpT * (1 - tmpT) * FirstPos.X + tmpT * tmpT * FinalPos.X;
resLocation.Y = 2 * tmpT * (1 - tmpT) * FirstPos.Y + tmpT * tmpT * FinalPos.Y;
resLocation.Z = 2 * tmpT * (1 - tmpT) * FirstPos.Z + tmpT * tmpT * FinalPos.Z;

Mesh->SetRelativeLocation(resLocation);

FVector drawCenter =  Mesh->GetRelativeLocation() + GetActorLocation();
UWorld* myWorld = GetWorld();
DrawDebugSphere(myWorld, drawCenter, 0.5, 10,FColor::Blue, false, 2);
}



效果如下图：

更多相关内容
• 这是用Processing实现的二阶贝塞尔曲线演示动画。 PVector p0, p1, p2; float t; PVector p00, p11; PVector p02; void setup() { size(400, 400); p0 = new PVector(100, 300); p1 = new PVe

# 原理

这篇文章讲的很清楚：贝塞尔曲线原理(简单阐述)

# 演示

以下演示转自 贝塞尔曲线 总结

一阶：

二阶：

三阶：

四阶：

五阶：

# 代码

这是用Processing实现的二阶贝塞尔曲线演示动画。

PVector p0, p1, p2;
float t;
PVector p00, p11;
PVector p02;

void setup() {
size(400, 400);
p0 = new PVector(100, 300);
p1 = new PVector(200, 100);
p2 = new PVector(300, 250);
t = 0.001;
}

void draw() {
background(200);

update();

showPoints();
showCurves();
showText();
}

void mousePressed() {
t = 0.001;
}

void update() {
if(t < 0.999){
t += 0.005;
}
p00 = new PVector((1-t)*p0.x + t*p1.x, (1-t)*p0.y + t*p1.y);
p11 = new PVector((1-t)*p1.x + t*p2.x, (1-t)*p1.y + t*p2.y);
p02 = new PVector((1-t)*p00.x + t*p11.x, (1-t)*p00.y + t*p11.y);
}

void showPoints() {
push();

stroke(30);
strokeWeight(6);
point(p0.x, p0.y);
point(p1.x, p1.y);
point(p2.x, p2.y);

stroke(0, 200, 0);
strokeWeight(8);
point(p00.x, p00.y);
point(p11.x, p11.y);

stroke(200, 0, 0);
point(p02.x, p02.y);

pop();
}

void showCurves() {
push();

stroke(0);
strokeWeight(1);
noFill();

beginShape();
vertex(p0.x, p0.y);
endShape();

line(p0.x, p0.y, p1.x, p1.y);
line(p1.x, p1.y, p2.x, p2.y);

push();
stroke(0, 0, 200);
line(p00.x, p00.y, p11.x, p11.y);
pop();

pop();
}

void showText() {
push();

fill(0);
textSize(14);
textAlign(RIGHT, TOP);
text("P0", p0.x, p0.y);
text("P1", p1.x, p1.y);
text("P2", p2.x, p2.y);

text("P00", p00.x, p00.y);
text("P11", p11.x, p11.y);

text("P02", p02.x, p02.y);
pop();
}



# 参考

展开全文
• ## 二阶贝塞尔曲线

千次阅读 2019-09-12 15:21:14
实现二阶贝塞尔曲线须知三个点点坐标，起点P0(x,y), 控制点P1(x,y),终点P2(x,y) 示例： /** * 二阶贝塞尔曲线 */ public class BSE2View extends View { /*起点*/ int startPointX; int ...

实现原理

实现二阶贝塞尔曲线须知三个点点坐标，起点P0(x,y), 控制点P1(x,y),终点P2(x,y)

示例：

/**
* 二阶贝塞尔曲线
*/
public class BSE2View extends View {

/*起点*/
int startPointX;
int startPointY;

/*控制点*/
int conPointX ;
int conPointY ;

/*终点*/
int endPiontX;
int endPiontY;

/*曲线*/
Path path;
/*画笔*/
Paint paint;

public BSE2View(Context context) {
this(context,null);
}

public BSE2View(Context context,  AttributeSet attrs) {
this(context, attrs,0);
}

public BSE2View(Context context,  AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}

private void initPaint() {
path = new Path();

paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setDither(true);
paint.setAntiAlias(true);
paint.setColor(getContext().getResources().getColor(R.color.colorPrimaryDark));
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 开始点的坐标
startPointX = 0;
startPointY = 0;
// 结束点的位置
endPiontX = w ;
endPiontY = 0;
// 控制点坐标
conPointX = w / 2;
conPointY = 0;

}

float y = 0;

@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
y = event.getRawY();
case MotionEvent.ACTION_MOVE:
conPointX = (int) event.getRawX();
conPointY = (int) (event.getRawY()-y);
if (conPointY>0){
invalidate();
}
break;
case MotionEvent.ACTION_UP:
conPointX = endPiontX / 2;
conPointY = 0;
invalidate();
break;
}
return true;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
path.reset(); // 初始化Path
path.moveTo(startPointX,startPointY);
canvas.drawPath(path,paint);
}
}


展开全文
• 上一篇自定义View中，贝塞尔曲线出现的频率很高，有小伙伴就问到关于贝塞尔曲线控制点坐标怎么计算的问题。一阶贝塞尔曲线是一条直线，确定起点...二阶贝塞尔曲线只有一个控制点，在实际开发中应用的也是最多

转载地址：http://blog.csdn.net/tyk0910/article/details/51626828#rd

上一篇自定义View中，贝塞尔曲线出现的频率很高，有小伙伴就问到关于贝塞尔曲线控制点坐标怎么计算的问题。一阶贝塞尔曲线是一条直线，确定起点终点即可，三阶贝塞尔曲线有两个控制点，相对比较复杂,不容易控制。二阶贝塞尔曲线只有一个控制点，在实际开发中应用的也是最多的。今天讨论的就是关于二阶贝塞尔曲线的控制点坐标计算问题。

到底怎样一张图就能够彻底了解二阶贝塞尔曲线呢，往下看就知道了：

设置二阶贝塞尔曲线的方法：
moveTo(float x,float y)
其中x,y的坐标代表图中曲线左边起点的位置坐标
quadTo(float x1, float y1, float x2, float y2 )
其中x1,y1的坐标就是图中小圆点的位置，也就是控制点的坐标
x2,y2的坐标就是图中曲线右边终点的位置坐标

代码中怎么实现的，一起看一下：

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onDraw</span>(Canvas canvas) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDraw(canvas);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>);
path.reset();
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//绘制二阶贝塞尔曲线</span>
path.moveTo(mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>, mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>);
path.quadTo(xWidth, yHeight, mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>, mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>);
canvas.drawPath(path, paint);
paint.setStyle(Paint.Style.FILL);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//绘制控制点</span>
canvas.drawCircle(xWidth, yHeight, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>, paint);
}

<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onTouchEvent</span>(MotionEvent ev) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> action = ev.getAction();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> x = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) ev.getX();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> y = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) ev.getY();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">switch</span> (action) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> MotionEvent.ACTION_DOWN:
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> MotionEvent.ACTION_MOVE:
xWidth = x;
yHeight = y;
postInvalidate();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> MotionEvent.ACTION_UP:
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul>

其实就是重写了onTouchEvent(MotionEvent ev)方法，在action为MotionEvent.ACTION_MOVE的时候，得到滑动时候的x与y坐标，然后分别赋值给path.quadTo(float x1, float y1, float x2, float y2 )方法中的前两个参数，也就是二阶贝塞尔曲线的控制点坐标。然后调用postInvalidate()来重新进行绘制即可。最后记得在onTouchEvent(MotionEvent ev)方法后返回true，表示View消耗当前滑动事件。

哈哈，看完是不是觉得很简单了。基于这张原理图，实际开发中有很多应用。我后来做了一些改进，算是小小拓展一下。看看下面的效果图：

是不是一种很熟悉的赶脚，各大手机卫士的清理小火箭不就出来了嘛，哈哈。这里关于自定义View的一些初始工作就不详细介绍了，前几篇博客说的很清楚。这里就主要贴onDraw()的代码了，上代码：

1.重写onDraw()方法

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//确定小火箭控制点的范围</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (xWidth < xSize) {
xWidth = xSize;
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (xWidth > mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>) {
xWidth = mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (yHeight > mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>) {
yHeight = mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (yHeight > mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> && xWidth < mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>) {
yHeight = mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (yHeight > mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> && xWidth > mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>) {
yHeight = mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>

xSize与ySize分别代表整体View宽度与高度的1/10，xWidth与yHeight是在action为MotionEvent.ACTION_MOVE时拿到的x与y坐标。后面绘制小火箭以及发射台的坐标都是基于这两个点进行改变的。仔细观察示例图效果，你会发现，小火箭是无法超出这个设置的区域。

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">        paint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setStrokeWidth</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
paint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setStyle</span>(Paint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Style</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.STROKE</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
path<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.reset</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
//绘制小火箭
path<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.moveTo</span>(xWidth - xSize * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, yHeight - ySize * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
path<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lineTo</span>(xWidth, yHeight - ySize)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
path<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lineTo</span>(xWidth + xSize * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, yHeight - ySize * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
path<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.moveTo</span>(xWidth - xSize * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>, yHeight - ySize * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
path<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lineTo</span>(xWidth - xSize * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>, yHeight)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
path<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lineTo</span>(xWidth + xSize * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>, yHeight)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
path<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lineTo</span>(xWidth + xSize * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>, yHeight - ySize * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
canvas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.drawPath</span>(path, paint)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

一阶贝塞尔曲线的应用

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">        //绘制发射台
paint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setStrokeWidth</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
arcPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.reset</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
arcPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.moveTo</span>(mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>, mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
if (yHeight > mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> && xWidth > mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> && xWidth < mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>) {
arcHeight = yHeight + yHeight - mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
} else {
arcHeight = mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}
arcPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.quadTo</span>(mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>, arcHeight, mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>, mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
canvas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.drawPath</span>(arcPath, paint)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

示例图中，只有火箭到达指定区域，才会引起发射台弯曲。这里进行了一下判断，只有在控制点坐标大于整体高度的7/10，并且宽度在指定范围内的时候，才会让quadTo(float x1, float y1, float x2, float y2 )中的第二个参数进行改变，否则保持不变。

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">        //绘制成功后的文字
if (isSuccess && yHeight < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
txtPaint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTextSize</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">80</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
txtPaint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setColor</span>(color)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
txtPaint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getTextBounds</span>(text, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, text<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.length</span>(), mRect)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
canvas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.drawText</span>(text, mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span> - mRect<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.width</span>() / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span> + mRect<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.height</span>() * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, txtPaint)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

这里的文字是在动画效果完成以后，并且控制点y的值小于0，也就是消失在视野中的时候，才让发射成功的文字出现。

2.重写onTouchEvent(MotionEvent ev)方法

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">   <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">onTouchEvent</span>(MotionEvent ev) {

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> action = ev.getAction();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> x = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) ev.getX();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> y = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) ev.getY();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">switch</span> (action) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> MotionEvent.ACTION_DOWN:
isSuccess = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> MotionEvent.ACTION_MOVE:
xWidth = x;
yHeight = y;
postInvalidate();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> MotionEvent.ACTION_UP:
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (yHeight > mHeight * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> && xWidth > mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> && xWidth < mWidth * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>) {
startAnim();
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>

MotionEvent.ACTION_DOWN的时候，发射成功设置为false
MotionEvent.ACTION_MOVE的时候，获取触摸点的坐标，并赋值给控制点
MotionEvent.ACTION_UP的时候，进行判断，符合发射条件就开启动画

返回true，表示消费当前滑动事件

3.动画实现

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">startAnim</span>() {
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//动画实现</span>
ValueAnimator animator = ValueAnimator.ofInt(yHeight, -ySize);
animator.addUpdateListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ValueAnimator.AnimatorUpdateListener() {
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onAnimationUpdate</span>(ValueAnimator animation) {
yHeight = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) animation.getAnimatedValue();
postInvalidate();
}
});
animSet.setDuration(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1200</span>);
animSet.play(animator);
animSet.start();
isSuccess = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul>

设置好开始值与结束值，添加一个动画的监听，就能够得到变化的值，再使用postInvalidate()方法，从而调用onDraw()方法来进行数值的改变并重新绘制。最后开启动画，并且将发射成功设置为true即可。

OK，相信看到这里，你对二阶贝塞尔曲线有了更加全面的认识。下一篇自定义View再见~~

展开全文
• 贝塞尔曲线有着很多特殊的性质, 在图形设计和路径规划中应用都非常广泛, 在路径规划中贝塞尔曲线完全由其控制点决定其形状,　ｎ个控制点对应着ｎ－１阶的贝塞尔曲线，并且可以通过递归的方式来绘制.
• 3、贝塞尔曲线原理介绍：掘金https://juejin.cn/post/6844903666361565191一、效果图： 二、React组件代码(注意我用的是tsx文件，如果是jsx的话把相关的类型声明删除即可) import React from...
• 前言：先膜拜一下启舰大神，本想自己写一篇关于贝塞尔曲线的文章，但无奈此大神写的太6了 ，所以直接转载相关文章：《Android自定义控件三部曲文章索引》: ...我将延续androidGraphics系列文章把图片相关的知识给大家...
• 下面以二阶贝塞尔曲线说明： 步骤一：在平面内选3个不同线的点并且依次用线段连接。 步骤二：在AB和BC线段上找出点D和点E，使得 AD/AB = BE/BC 步骤三：连接DE，在DE上寻找点F，F点需要满足：DF/DE = AD/AB = BE/BC...
• P0为起点,Pn为终点,Pi为控制点一阶贝塞尔曲线(线段)：一阶贝塞尔曲线公式一阶贝塞尔曲线演示意义：由 P0 至 P1 的连续点， 描述的一条线段二阶贝塞尔曲线(抛物线)：二阶贝塞尔曲线公式二阶贝塞尔曲线演示原理：由 P0...
• 贝塞尔曲线 (Bézier curve) 由法国数学家Pierre Bézier于 1962 年提出的一种矢量曲线，广泛应用于工程绘图、动画设计等领域。贝塞尔曲线是一种运动轨迹曲线，由 n 个点在 n 条线段上匀速运动（不同线段上的速度...
• 二阶贝塞尔曲线实现绘画板效果
• 贝赛尔工具在 photoshop 中叫“钢笔工具”；在 CorelDraw 中翻译成“贝赛尔工具”；而在 Fireworks 中叫“画笔”. 它是用来“画线”造型的一种专业工具....很多设计师应该都知道贝塞尔曲线，习惯用 ...
• ## 贝塞尔曲线拟合原理

万次阅读 多人点赞 2017-01-13 18:07:53
1.什么是贝塞尔曲线贝塞尔曲线所依据的最原始的数学公式，是早在1912年就广为人知的伯恩斯坦多项式。简单来说，伯恩斯坦多项式可以用来证明，在[ a, b ] 区间上所有的连续函数都可以用多项式来逼近，并且收敛性很...
• 二阶贝塞尔曲线公式 B（t）=（1 – t）²Po + 2t（1 – t）P1 + t²P2，t∈[0，1] 可转换为 B（t）= （1-t）[（1-t）Po + tP1] + t[（1-t）P1 + tP2] 二阶贝塞尔曲线示例图 气泡实现解析 实现过程 先通过上面的...
• 目前支持二阶和三阶贝塞尔曲线绘制、匀速运动、导出路径的JSON数据， 在项目中可以直接读取json文件，里面存储了许多连续的曲线点，直接拿来用即可。 可以根据不同的需求来达到想要的效果。 匀速运动实现思路很简单...
• 前一篇文章讲了Path绘制直线以及各种基本图形，这篇文主要说Path绘制曲线，...Paste_Image.png贝塞尔曲线作用十分广泛:QQ小红点拖拽效果一些炫酷的下拉刷新控件阅读软件的翻书效果一些平滑的折线图的制作很多炫酷的...
• 今天在学习贝塞尔曲线的过程中觉得很新奇，特别是之前觉得很神秘的东西一下全部融会贯通了，为了实践，特地写了一个demo——波浪图，先看效果图：纸上得来终觉浅，绝知此事要躬行！... 二阶贝塞尔曲线形成原理
• Android动画，特别是涉及运动轨迹的，很多时候都会使用贝塞尔曲线，下面将系统的介绍下贝塞尔曲线的相关知识。 什么是贝塞尔曲线 贝塞尔曲线于1962年，由法国工程师皮埃尔·贝兹（Pierre Bézier）所广泛发表，他...
• 原理和简单推导(以三阶为例)：设P0、P02、P2是一条抛物线上顺序三个不同的点。过P0和P2点的两切线交于P1点，在P02点的切线交P0P1和P2P1于P01和P11，则如下比例成立：这是所谓抛物线的三切线定理。当P0，P2固定，引入...
• 有同学私信我，问我能否出一个三阶贝塞尔曲线的教程。 嘛，今天就来讲讲贝塞尔曲线吧。 二、 结束语 完毕。 喜欢Unity的同学，不要忘记点击关注，如果有什么Unity相关的技术难题，也欢迎留言或私信~ ...
• 本文主要内容为贝塞尔曲线原理解析并用 SurfaceView 实现其展示动画关于SurfaceView 的使用，大家可以看我的上一篇文章 Android：SurfaceView 的使用(附代码模板)概述贝塞尔曲线(Bézier curve)，又称贝兹曲线或贝济...
• 什么是贝塞尔曲线 贝塞尔曲线，英文名Bezier Curve，是计算机图形学非常重要的一种曲线 它可以将若干的点，用一条平滑自然的曲线来连接起来 比如我们在地图库中绘制用户行走轨迹时，如果用折线来展示，就比较难看 ...
• Android Studio Canvas 实现鼠标贝塞尔曲线拖尾特效 特效预览图 什么是贝塞尔曲线？ 百度百科： ​ 贝塞尔曲线(Bézier curve)，又称贝兹曲线或贝济埃曲线，是应用于二维图形应用程序的数学曲线。一般的矢量图形...
• 1. 定义 贝塞尔曲线(Bezier curve)，又称贝兹曲线或贝济埃曲线，是应用于二维图形应用...贝塞尔曲线是计算机图形学中相当重要的参数曲线，在一些比较成熟的位图软件中也有贝塞尔曲线工具，如PhotoShop等。 贝塞...

...