Skip to content

Commit c3108d6

Browse files
committed
三阶贝塞尔曲线的模拟
1 parent 9701d53 commit c3108d6

File tree

11 files changed

+187
-4
lines changed

11 files changed

+187
-4
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,17 @@
196196
3. Vector图像过于复杂时,不仅仅要注意绘制效率,初始化效率也是需要考虑的重要因素。
197197
4. SVG加载速度会快于PNG,但渲染速度会低于PNG,毕竟PNG有硬件加速,但平均下来,加载速度的提升弥补了渲染的速度缺陷。
198198

199+
### Bezier曲线
200+
201+
**Bézier curve(**[贝塞尔曲线](https://baike.baidu.com/item/%E8%B4%9D%E5%A1%9E%E5%B0%94%E6%9B%B2%E7%BA%BF/1091769?fr=aladdin)**)**是应用于二维图形应用程序的[数学曲线](http://baike.baidu.com/view/627248.htm)。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家**Pierre Bézier**第一个研究了这种[矢量](http://baike.baidu.com/view/77474.htm)绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。
202+
203+
![一阶贝塞尔曲线](img\one_bezier.webp)
204+
205+
![二阶贝塞尔曲线](img\two_bezier.webp)
206+
207+
![三阶贝塞尔曲线](img\three_bezier.webp)
208+
209+
![四阶贝塞尔曲线](img\four_bezier.webp)
210+
211+
![五阶贝塞尔曲线](img\five_bezier.webp)
212+

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
android:roundIcon="@mipmap/ic_launcher_round"
1010
android:supportsRtl="true"
1111
android:theme="@style/AppTheme">
12-
<activity android:name=".SecondBezierDemoActivity"></activity>
12+
<activity android:name=".ThirdBezierActivity"></activity>
13+
<activity android:name=".SecondBezierActivity" />
1314
<activity android:name=".VectorDemoActivity" />
1415
<activity android:name=".MainActivity">
1516
<intent-filter>

app/src/main/java/com/hyd/animationart/MainActivity.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@ protected void onCreate(Bundle savedInstanceState) {
1515

1616
findViewById(R.id.vector_demo).setOnClickListener(this);
1717
findViewById(R.id.second_bezier).setOnClickListener(this);
18+
findViewById(R.id.third_bezier).setOnClickListener(this);
1819
}
1920

2021
@Override
2122
public void onClick(View v) {
2223
if (v.getId() == R.id.vector_demo) {
2324
startActivity(new Intent(this, VectorDemoActivity.class));
2425
} else if (v.getId() == R.id.second_bezier) {
25-
startActivity(new Intent(this, SecondBezierDemoActivity.class));
26+
startActivity(new Intent(this, SecondBezierActivity.class));
27+
} else if (v.getId() == R.id.third_bezier) {
28+
startActivity(new Intent(this, ThirdBezierActivity.class));
2629
}
2730
}
2831
}

app/src/main/java/com/hyd/animationart/SecondBezierDemoActivity.java renamed to app/src/main/java/com/hyd/animationart/SecondBezierActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import android.os.Bundle;
66

7-
public class SecondBezierDemoActivity extends AppCompatActivity {
7+
public class SecondBezierActivity extends AppCompatActivity {
88

99
@Override
1010
protected void onCreate(Bundle savedInstanceState) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.hyd.animationart;
2+
3+
import androidx.appcompat.app.AppCompatActivity;
4+
5+
import android.os.Bundle;
6+
7+
public class ThirdBezierActivity extends AppCompatActivity {
8+
9+
@Override
10+
protected void onCreate(Bundle savedInstanceState) {
11+
super.onCreate(savedInstanceState);
12+
setContentView(R.layout.activity_third_bezier);
13+
}
14+
}

app/src/main/java/com/hyd/animationart/views/SecondBezierView.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public SecondBezierView(Context context) {
3737

3838
public SecondBezierView(Context context, @Nullable AttributeSet attrs) {
3939
super(context, attrs);
40+
41+
4042
init();
4143
}
4244

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package com.hyd.animationart.views;
2+
3+
import android.content.Context;
4+
import android.graphics.Canvas;
5+
import android.graphics.Paint;
6+
import android.graphics.Path;
7+
import android.util.AttributeSet;
8+
import android.view.MotionEvent;
9+
import android.view.View;
10+
11+
import androidx.annotation.Nullable;
12+
13+
/**
14+
* Created by hydCoder on 2019/12/23.
15+
* 以梦为马,明日天涯。
16+
*/
17+
public class ThirdBezierView extends View {
18+
19+
private float mStartPointX;
20+
private float mStartPointY;
21+
22+
private float mEndPointX;
23+
private float mEndPointY;
24+
25+
private float mFlagPointOneX;
26+
private float mFlagPointOneY;
27+
28+
private float mFlagPointTwoX;
29+
private float mFlagPointTwoY;
30+
31+
private Path mPath;
32+
private Paint mPaintBezier;
33+
private Paint mPaintFlag;
34+
private Paint mPaintText;
35+
36+
private boolean isSecondPoint = false;
37+
38+
public ThirdBezierView(Context context) {
39+
super(context);
40+
init();
41+
}
42+
43+
public ThirdBezierView(Context context, @Nullable AttributeSet attrs) {
44+
super(context, attrs);
45+
46+
47+
init();
48+
}
49+
50+
public ThirdBezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
51+
super(context, attrs, defStyleAttr);
52+
init();
53+
}
54+
55+
private void init() {
56+
mPaintBezier = new Paint(Paint.ANTI_ALIAS_FLAG);
57+
mPaintBezier.setStrokeWidth(8);
58+
mPaintBezier.setStyle(Paint.Style.STROKE);
59+
60+
mPaintFlag = new Paint(Paint.ANTI_ALIAS_FLAG);
61+
mPaintFlag.setStrokeWidth(5);
62+
mPaintFlag.setStyle(Paint.Style.STROKE);
63+
64+
mPaintText = new Paint(Paint.ANTI_ALIAS_FLAG);
65+
mPaintText.setStyle(Paint.Style.STROKE);
66+
mPaintText.setTextSize(26);
67+
}
68+
69+
@Override
70+
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
71+
super.onSizeChanged(w, h, oldw, oldh);
72+
73+
mStartPointX = w / 4;
74+
mStartPointY = h / 2 - 200;
75+
76+
mEndPointX = w * 3 / 4;
77+
mEndPointY = h / 2 - 200;
78+
79+
mFlagPointOneX = w / 2 - 100;
80+
mFlagPointOneY = h / 2 - 300;
81+
mFlagPointTwoX = w / 2 + 100;
82+
mFlagPointTwoY = h / 2 - 300;
83+
84+
mPath = new Path();
85+
}
86+
87+
@Override
88+
protected void onDraw(Canvas canvas) {
89+
super.onDraw(canvas);
90+
mPath.reset();
91+
mPath.moveTo(mStartPointX, mStartPointY);
92+
mPath.cubicTo(mFlagPointOneX, mFlagPointOneY, mFlagPointTwoX, mFlagPointTwoY, mEndPointX, mEndPointY);
93+
94+
canvas.drawPoint(mStartPointX, mStartPointY, mPaintFlag);
95+
canvas.drawText("起点", mStartPointX, mStartPointY, mPaintText);
96+
canvas.drawPoint(mEndPointX, mEndPointY, mPaintFlag);
97+
canvas.drawText("终点", mEndPointX, mEndPointY, mPaintText);
98+
canvas.drawPoint(mFlagPointOneX, mFlagPointOneY, mPaintFlag);
99+
canvas.drawText("控制点1", mFlagPointOneX, mFlagPointOneY, mPaintText);
100+
canvas.drawText("控制点2", mFlagPointTwoX, mFlagPointTwoY, mPaintText);
101+
canvas.drawLine(mStartPointX, mStartPointY, mFlagPointOneX, mFlagPointOneY, mPaintFlag);
102+
canvas.drawLine(mFlagPointOneX, mFlagPointOneY, mFlagPointTwoX, mFlagPointTwoY, mPaintFlag);
103+
canvas.drawLine(mEndPointX, mEndPointY, mFlagPointTwoX, mFlagPointTwoY, mPaintFlag);
104+
105+
canvas.drawPath(mPath, mPaintBezier);
106+
}
107+
108+
@Override
109+
public boolean onTouchEvent(MotionEvent event) {
110+
switch (event.getAction() & MotionEvent.ACTION_MASK) {
111+
case MotionEvent.ACTION_POINTER_DOWN:
112+
isSecondPoint = true;
113+
break;
114+
case MotionEvent.ACTION_POINTER_UP:
115+
isSecondPoint = false;
116+
break;
117+
case MotionEvent.ACTION_MOVE:
118+
mFlagPointOneX = event.getX(0);
119+
mFlagPointOneY = event.getY(0);
120+
if (isSecondPoint) {
121+
mFlagPointTwoX = event.getX(1);
122+
mFlagPointTwoY = event.getY(1);
123+
}
124+
invalidate();
125+
break;
126+
}
127+
return true;
128+
}
129+
}

app/src/main/res/layout/activity_main.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,10 @@
1717
android:layout_width="match_parent"
1818
android:layout_height="wrap_content"
1919
android:text="@string/second_bezier" />
20+
21+
<Button
22+
android:id="@+id/third_bezier"
23+
android:layout_width="match_parent"
24+
android:layout_height="wrap_content"
25+
android:text="@string/third_bezier" />
2026
</LinearLayout>

app/src/main/res/layout/activity_second_bezier_demo.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
android:layout_width="match_parent"
66
android:layout_height="match_parent"
77
android:orientation="vertical"
8-
tools:context=".SecondBezierDemoActivity">
8+
tools:context=".SecondBezierActivity">
99

1010
<com.hyd.animationart.views.SecondBezierView
1111
android:layout_width="match_parent"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<LinearLayout
3+
xmlns:android="http://schemas.android.com/apk/res/android"
4+
xmlns:tools="http://schemas.android.com/tools"
5+
android:layout_width="match_parent"
6+
android:layout_height="match_parent"
7+
tools:context=".ThirdBezierActivity">
8+
9+
<com.hyd.animationart.views.ThirdBezierView
10+
android:layout_width="match_parent"
11+
android:layout_height="match_parent"/>
12+
13+
</LinearLayout>

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
<string name="app_name">AnimationArt</string>
33
<string name="vector_demo">VECTOR_DEMO</string>
44
<string name="second_bezier">二阶贝塞尔曲线</string>
5+
<string name="third_bezier">三阶贝塞尔曲线</string>
56
</resources>

0 commit comments

Comments
 (0)