Android custom View-step-Path-based beiser curve, Android-path

Source: Internet
Author: User

Android custom View-step-Path-based beiser curve, Android-path
1. Commonly Used Path method table

For compatibility (Lazy) In this table, the method is added only after API21 (Android 5.0) or later. I can't help but give it a sigh of relief. It seems that some methods that can be easily written will not be added until API21. The baby's heart is also broken at the moment.

Function Related Methods Remarks
Move start point MoveTo Move the start point of the next operation
Set end point SetLastPoint Resets the last vertex position in the current path. If it is called before painting, the effect is the same as that of moveTo.
Connection line LineTo Add a straight line from the previous point to the current point to the Path
Closed Path Close Connect the first vertex to the last vertex to form a closed area.
Add content AddRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo Add (rectangle, rounded rectangle, elliptic, circle, Path, and arc) to the current Path (note the differences between addArc and arcTo)
Empty or not IsEmpty Determines whether the Path is empty.
Rectangle or not IsRect Determines whether the path is a rectangle.
Replacement path Set Replace all content in the current path with a new path
Offset path Offset Offset the operation before the current path (subsequent operations will not be affected)
Besell Curve QuadTo, cubicTo Method for quadratic and cubic besell curves, respectively
RXxx Method RMoveTo, rLineTo, rQuadTo, rCubicTo The method without r is based on the origin coordinate system (offset), and The rXxx method is based on the current coordinate system (offset)
Fill Mode SetFillType, getFillType, isInverseFillType, toggleInverseFillType Set, retrieve, judge, and switch fill Mode
Tips IncReserve Indicates the number of points in the Path to be added.(This method seems to optimize the storage structure of Path)
Boolean operation (API19) Op Perform Boolean operations on two paths (operations such as intersection and Union)
Computing Boundary ComputeBounds Calculate the Path Boundary
Reset path Reset, rewind Clear content in Path
Reset does not retain the internal data structure, but retains FillType.
Rewind retains the internal data structure, but does not retain the FillType.
Matrix Operations Transform Matrix Transformation
Ii. Detailed explanation of Path

In addition to some common functions, the last explanation is basically a straight line. This time, we need to know the curve section. When talking about the curve, we have to pick up the famous besell curve. It was invented by the following (French mathematician pierreb ).

What is the besell curve?

The beiser curve is widely used.The beiser curve lays the foundation for computer plotting (Because it can describe any complex image in a precise mathematical language)You have used it inadvertently.

If you use Photoshop, you may noticePen toolThe core of this pen tool is the bésel curve.

You said you would not PS? It doesn't matter. If you have read the previous article or used 2D drawing, you must have drawn such things as circles, edges, and rounded corners. All the arcs in this section are used by the besell curve.

The beiser curve has a wide range of functions. Here are some simple examples: QQ little red dot drag effect some cool pull-down refresh control reading software flip effect some smooth line chart make a lot of cool animation effect how to easily get started with the besell curve?

Although the besserl curve is widely used, it seems that there are no suitable Chinese tutorials currently. The Chinese articles on the Bessert curve of Android can be found in the following categories:

Copptype (only let people know about Bessel, and there is no substantive content) Forced type (put out a lot of formulas, reference a bunch of Original ENGLISH) basic type (just explain the use of the two functions of the Bessel curve) real-world model (based on examples, describe the use of the besell curve)

Among the above types, the basic and real-world models are useful, but each has its own shortcomings. This article will combine the two to learn the besell curve from scratch.

Step 1. Understand the principle of the besell Curve

Here, we understand that the besell curve is not a process of learning the derivation of the formula (* ω), but how the besell curve is generated.
The beiser curve uses a series of points to control the curve state. I will divide these points into two categories:

Type Function
Data point Determine the start and end positions of the curve
Control Point Determine the curve bending degree

For the time being, I only want to understand the concept. Next I will explain the detailed meaning.

First-order Curve principle:

The first-order curve has no control points. There are only two data points (A and B), and the final result is A line segment.

It indicates a stage in the first-order curve generation process. For details about the dynamic process, refer to (in this article, the dynamic demonstration images related to the besell curve are from Wikipedia ).

PS: the first-order curve is actually the lineTo described above.

Second-Order Curve principle:

The second-order curve consists of two data points (A and C) and one control point (B) to describe the curve status, which is roughly as follows:

The red curve is the legendary second-order besell curve. How is this red curve generated? Next we will analyze one of the statuses:

Connect to AB bc, and take point D and point E on AB to satisfy the following conditions:

Connect to DE, take point F, so that:

In this way, the obtained vertex F is a point on the besell curve. The dynamic process is as follows:

PS: The method for second-order curves is quadTo.

Third-Order Curve principle:

The third-order curve consists of two data points (A and D) and two control points (B and C) to describe the curve status, as shown below:

The calculation process of the third-order curve is similar to that of the second-order Curve. For details, see the dynamic results:

PS: The method corresponding to the third-order curve is cubicTo.

We strongly recommend that you click here to practice the besell curve to deepen your understanding of the besell curve. Step 2. Learn how to use the besserl curve functions first-order Curve:

The first-order curve is a line segment, which is very simple. You can refer to the basic operation of Path in the previous article, which is not described here.

Second-Order Curve:

Through a simple understanding of the second-order curve, we know that the second-order curve consists of two data points and one control point. Next we will use an example to demonstrate how to use the second-order curve.

First, the two data points are the locations that control the start and end of the beiser curve, which is easy to understand, while the control points are the control points that control the bending status of the beiser, which is relatively difficult to understand, therefore, the focus of this example is to understand the relationship between the beiser curve Bending State and the control point:

To make it easier to see the relationship between the control point and the curve bending degree, the auxiliary points and guides are drawn. From the dynamic diagram above, we can see that the beiser curve has the same elastic effect as the rubber band in the dynamic change process, therefore, it is often used to make some elastic effects.

The main code is as follows:

Public class bezr extends View {private Paint mPaint; private int centerX, centerY; private PointF start, end, control; public Bessel1 (Context context) {super (context ); mPaint = new Paint (); mPaint. setColor (Color. BLACK); mPaint. setStrokeWidth (8); mPaint. setStyle (Paint. style. STROKE); mPaint. setTextSize (60); start = new PointF (); end = new PointF (); control = new PointF ();} @ Override protected void onSizeChanged (int w, int h, int oldw, int oldh) {super. onSizeChanged (w, h, oldw, oldh); centerX = w/2; centerY = h/2; // initialize the start of the data point and control point. x = centerX-200; start. y = centerY; end. x = centerX + 200; end. y = centerY; control. x = centerX; control. y = centerY-100;} @ Override public boolean onTouchEvent (MotionEvent event) {// update the control point based on the Touch Location and prompt to re-paint the control. x = event. getX (); control. y = event. getY (); invalidate (); return true ;}@ Override protected void onDraw (Canvas canvas) {super. onDraw (canvas); // draw the data point and Control Point mPaint. setColor (Color. GRAY); mPaint. setStrokeWidth (20); canvas. drawPoint (start. x, start. y, mPaint); canvas. drawPoint (end. x, end. y, mPaint); canvas. drawPoint (control. x, control. y, mPaint); // draw the Auxiliary Line mPaint. setStrokeWidth (4); canvas. drawLine (start. x, start. y, control. x, control. y, mPaint); canvas. drawLine (end. x, end. y, control. x, control. y, mPaint); // draw the mPaint of the besell curve. setColor (Color. RED); mPaint. setStrokeWidth (8); Path path = new Path (); path. moveTo (start. x, start. y); path. quadTo (control. x, control. y, end. x, end. y); canvas. drawPath (path, mPaint );}}
Third-Order Curve:

The third-order curve is controlled by two data points and two control points.

Code:

Public class Bezier2 extends View {private Paint mPaint; private int centerX, centerY; private PointF start, end, control1, control2; private boolean mode = true; public Bezier2 (Context context) {this (context, null);} public Bezier2 (Context context, AttributeSet attrs) {super (context, attrs); mPaint = new Paint (); mPaint. setColor (Color. BLACK); mPaint. setStrokeWidth (8); mPaint. setStyle (Paint. style. STROKE); mPaint. setTextSize (60); start = new PointF (0, 0); end = new PointF (0, 0); control1 = new PointF (0, 0 ); control2 = new PointF (0, 0);} public void setMode (boolean mode) {this. mode = mode ;}@ Override protected void onSizeChanged (int w, int h, int oldw, int oldh) {super. onSizeChanged (w, h, oldw, oldh); centerX = w/2; centerY = h/2; // initialize the start of the data point and control point. x = centerx- 200; start. y = centerY; end. x = centerX + 200; end. y = centerY; control1.x = centerX; control1.y = centerY-100; control2.x = centerX; control2.y = centerY-100;} @ Override public boolean onTouchEvent (MotionEvent event) {// update the control point based on the touch location, and prompt to re-paint if (mode) {control1.x = event. getX (); control1.y = event. getY ();} else {control2.x = event. getX (); control2.y = event. getY () ;}invalidate (); return true ;}@ Override protected void onDraw (Canvas canvas) {super. onDraw (canvas); // drawCoordinateSystem (canvas); // draw data points and control points mPaint. setColor (Color. GRAY); mPaint. setStrokeWidth (20); canvas. drawPoint (start. x, start. y, mPaint); canvas. drawPoint (end. x, end. y, mPaint); canvas. drawPoint (control1.x, control1.y, mPaint); canvas. drawPoint (control2.x, control2.y, mPaint); // draw the Auxiliary Line mPaint. setStrokeWidth (4); canvas. drawLine (start. x, start. y, control1.x, control1.y, mPaint); canvas. drawLine (control1.x, control1.y, control2.x, control2.y, mPaint); canvas. drawLine (control2.x, control2.y, end. x, end. y, mPaint); // draw the mPaint of the besell curve. setColor (Color. RED); mPaint. setStrokeWidth (8); Path path = new Path (); path. moveTo (start. x, start. y); path. cubicTo (control1.x, control1.y, control2.x, control2.y, end. x, end. y); canvas. drawPath (path, mPaint );}}

Compared with a second-order curve, a third-order curve can produce more complex shapes. However, for a higher-order curve, a lower-order curve combination can achieve the same effect.Downgrading. Therefore, our Encapsulation Method for The besell curve is generally as high as the third-order curve.

Downgrading and upgrading
Type Meaning Change
Downgrading When the shape and direction of the curve remain unchanged, reduce the number of control points, that is, reduce the curve order. The method becomes simple, the number of data points increases, the control points may be reduced, and the flexibility becomes weak.
Upgrade When the shape and direction of the curve remain unchanged, increase the number of control points, that is, increase the curve order. The method is more complex, the data points remain unchanged, the control points are increased, and the flexibility is increased.
Step 3. Example of using the besserl Curve

Before creating this instance, you must first define the content, that is, under what circumstances do you need to use the besell curve?

When you need to draw irregular images? Of course not! At present, I think the use of the beiser curve mainly has the following aspects (for personal opinions only, there may be errors. please correct me)

Serial number Content Use Cases
1 If you do not know the curve status in advance and need to calculate it in real time Smooth line chart of weather forecast temperature change
2 When the display status changes according to user operations QQ little red dot, simulation of book flip Effect
3 Some complex motion states (used with PathMeasure) Animation effects of complex motion states

As for the case where only a static curve graph is needed, isn't it better to use images? A large amount of computing is not cost-effective.

If the SVG vector graph is displayed, there are related parsing tools (the internal use of the besell curve is still used), and manual computation is not required.

The main advantage of the besell curve is that the curve state can be controlled in real time, and the state of the curve can be smoothly changed in real time by changing the state of the control point.

Next we will use a simple example to turn a circle gradient into a heart shape ::

Train of Thought Analysis:

The final result we need is to convert a circle into a heart shape. Through analysis, we can see that a circle can be formed by a combination of four third-order besell curves, as shown below:

The heart shape can also be composed of four third-order besels, as shown below:

The difference between the two lies in that the data point and the control point are different. Therefore, you only need to adjust the data point and the control point to change the circle to the heart shape.

Core difficulties: 1. How to obtain the data point and control point location?

We have already calculated the data points and control points used to draw circles in detail, you can refer to the answer in stackoverflow to How to create circle with bégiz curves. You only need to use the data here.

For heart-shaped data points and control points, the data points and control points in the circle can be translated, and the specific parameters can be adjusted to a satisfactory effect.

2. How to Achieve gradient effect?

The gradient is actually to move the data point and control point a little bit each time, then re-draw the interface, adjust the data point and Control Point multiple times in a short time, so that it gradually approaches the target value, you can achieve a gradient through the continuous re-painting interface. You can refer to the dynamic results for the process:

Code:
Public class Bezier3 extends View {private static final float C = 0.551915024494f; // a constant used to calculate the position of the control point of the circular besell curve. private int mCenterX and mCenterY; private PointF mCenter = new PointF (200); private float mCircleRadius =; // the radius of the circle private float mDifference = mCircleRadius * C; // The Difference Between the circular Control Point and the data point private float [] mData = new float [8]; // clockwise record the four data points of the circle private float [] mCtrl = new float [16]; // clockwise record the eight control points of the circle private float mDuration = 1000; // total change duration private float mCurrent = 0; // the current duration private float mCount = 100; // The total number of private float mPiece = mDuration/mCount for the duration. // The duration of each private float mPiece = mDuration/mCount; public Bezier3 (Context context) {this (context, null );} public Bezier3 (Context context, AttributeSet attrs) {super (context, attrs); mPaint = new Paint (); mPaint. setColor (Color. BLACK); mPaint. setStrokeWidth (8); mPaint. setStyle (Paint. style. STROKE); mPaint. setTextSize (60); // initialize the data point mData [0] = 0; mData [1] = mCircleRadius; mData [2] = mCircleRadius; mData [3] = 0; mData [4] = 0; mData [5] =-mCircleRadius; mData [6] =-mCircleRadius; mData [7] = 0; // initialize the control point mCtrl [0] = mData [0] + mDifference; mCtrl [1] = mData [1]; mCtrl [2] = mData [2]; mCtrl [3] = mData [3] + mDifference; mCtrl [4] = mData [2]; mCtrl [5] = mData [3]-mDifference; mCtrl [6] = mData [4] + mDifference; mCtrl [7] = mData [5]; mCtrl [8] = mData [4]-mDifference; mCtrl [9] = mData [5]; mCtrl [10] = mData [6]; mCtrl [11] = mData [7]-mDifference; mCtrl [12] = mData [6]; mCtrl [13] = mData [7] + mDifference; mCtrl [14] = mData [0]-mDifference; mCtrl [15] = mData [1] ;}@ Override protected void onSizeChanged (int w, int h, int oldw, int oldh) {super. onSizeChanged (w, h, oldw, oldh); mCenterX = w/2; mCenterY = h/2;} @ Override protected void onDraw (Canvas canvas) {super. onDraw (canvas); drawCoordinateSystem (canvas); // draw the coordinate system canvas. translate (mCenterX, mCenterY); // move the coordinate system to the canvas center canvas. scale (1,-1); // flip the Y axis drawAuxiliaryLine (canvas); // draw the mPaint of the besell curve. setColor (Color. RED); mPaint. setStrokeWidth (8); Path path = new Path (); path. moveTo (mData [0], mData [1]); path. cubicTo (mCtrl [0], mCtrl [1], mCtrl [2], mCtrl [3], mData [2], mData [3]); path. cubicTo (mCtrl [4], mCtrl [5], mCtrl [6], mCtrl [7], mData [4], mData [5]); path. cubicTo (mCtrl [8], mCtrl [9], mCtrl [10], mCtrl [11], mData [6], mData [7]); path. cubicTo (mCtrl [12], mCtrl [13], mCtrl [14], mCtrl [15], mData [0], mData [1]); canvas. drawPath (path, mPaint); mCurrent + = mPiece; if (mCurrent <mDuration) {mData [1]-= 120/mCount; mCtrl [7] + = 80/mCount; mCtrl [9] + = 80/mCount; mCtrl [4]-= 20/mCount; mCtrl [10] + = 20/mCount; postInvalidateDelayed (long) mPiece );}} // draw guides private void drawAuxiliaryLine (Canvas canvas) {// draw data points and control points mPaint. setColor (Color. GRAY); mPaint. setStrokeWidth (20); for (int I = 0; I <8; I ++ = 2) {canvas. drawPoint (mData [I], mData [I + 1], mPaint) ;}for (int I = 0; I <16; I ++ = 2) {canvas. drawPoint (mCtrl [I], mCtrl [I + 1], mPaint);} // draw the Auxiliary Line mPaint. setStrokeWidth (4); for (int I = 2, j = 2; I <8; I + = 2, j + = 4) {canvas. drawLine (mData [I], mData [I + 1], mCtrl [j], mCtrl [j + 1], mPaint); canvas. drawLine (mData [I], mData [I + 1], mCtrl [j + 2], mCtrl [j + 3], mPaint);} canvas. drawLine (mData [0], mData [1], mCtrl [0], mCtrl [1], mPaint); canvas. drawLine (mData [0], mData [1], mCtrl [14], mCtrl [15], mPaint);} // draw the coordinate system private void drawCoordinateSystem (Canvas canvas) {canvas. save (); // draw the canvas coordinate system. translate (mCenterX, mCenterY); // move the coordinate system to the canvas center canvas. scale (1,-1); // flip the Y axis Paint fuzhuPaint = new Paint (); fuzhuPaint. setColor (Color. RED); fuzhuPaint. setStrokeWidth (5); fuzhuPaint. setStyle (Paint. style. STROKE); canvas. drawLine (0,-2000, 0, 2000, fuzhuPaint); canvas. drawLine (-2000, 0, 2000, 0, fuzhuPaint); canvas. restore ();}}
Iii. Summary

In fact, the most important thing about the beiser curve is the core understanding of the beiser curve generation method. Only by understanding the beiser curve generation method can we better use the beiser curve. At the end of the previous article, this article may involve some graphics rendering problems. Unfortunately, this article does not exist. Please look forward to the next article () O) in the next article, we will continue with the Path-related content and teach you some more interesting things.

Unlock the new realm [draw an Elastic circle ]:

(,,,,)

PS: Due to my limited level, there may be misunderstandings or inaccuracies in some places. If you have any questions, submit Issues for feedback.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.