Android Custom View Advanced: Bezier curve

Source: Internet
Author: User
Tags gety rewind

In the basic graph of path, in the previous article, we learned about the basic use of path, this time understanding the very very very important content in path-Bezier curve.

One. Path Common method table

For compatibility (lazy) This table removes the addition of API21 (i.e. Android version 5.0). Can not help but spit groove, why seems to be able to write some of the overloaded method to wait until API21 to add AH. The baby's heart is collapsing at the moment.

Action-related method notes

Move start MoveTo Move the start position of the next operation

Set End Setlastpoint Resets the last point position in the current path, and if called before drawing, the effect and moveto are the same

Connect line LineTo Add a line from the previous point to the current point to Path

Closed path Close connects the first point to the last point, forming a closed area

Add content Addrect, Addroundrect, Addoval, Addcircle, Addpath, AddArc, arcto Add (Rectangle, rounded rectangle, ellipse, circle, Path, ARC) to the current path (note the area of AddArc and ArcTo Don't

Whether null IsEmpty determines if path is empty

Whether the path is a rectangle or not is a rectangle isrect

Replace path set replaces all contents of the current path with a new path

Offset path offset offsets the operation before the current path (does not affect subsequent operations)

Bezier curve Quadto, Cubicto Two and three Bezier curves respectively

Rxxx method Rmoveto, Rlineto, Rquadto, Rcubicto method without R is based on the origin of the coordinate system (offset), the Rxxx method is based on the current point coordinate system (offset)

Fill mode Setfilltype, Getfilltype, Isinversefilltype, toggleinversefilltype settings, get, judge and toggle fill mode

Hint Method Increserve indicates how many points of path are waiting to be added (this method seems to allow path to optimize the storage structure)

Boolean operation (API19) Op boolean operation on two path (i.e., intersection, set, etc.)

Calculate boundary computebounds Calculate the boundary of path

Reset path Reset, rewind clears the contents of path

Reset does not retain the internal data structure, but it retains the filltype.

Rewind retains the internal data structure, but does not retain the Filltype

Matrix Operation Transform Matrix transformation

Two. Path explanation

In addition to some of the usual functions, the explanation is basically straight line, this time need to understand the curve part, when it comes to the curve, we have to mention the famous Bezier curve. Its inventor is the following man (French mathematician Pierrebézier).

What can a Bezier curve do?

Bezier curves are widely used, and it can be said that the Bezier curve lays the groundwork for computer graphics (because it can describe any complex graphic in a precise mathematical language), which you have used inadvertently.

If you use Photoshop, you may notice that there is a pen tool in it, and the core of the pen tool is the Bezier curve.

You say you can't PS? It's okay, if you've seen the previous article or used 2D drawings, you must have drawn circles, arcs, rounded rectangles and so on. The arcs in this section are all used in Bezier curves.

The Bezier curve acts very extensively and simply lifts a few chestnuts:

QQ Small red dot drag effect

Some cool drop-down refresh controls

Read the software's book-flipping effect

The making of some smooth line charts

A lot of cool animation effects

How do I easily get started with Bezier curves?

Although the use of Bezier curve is very wide, but there seems to be no suitable Chinese course, can search out Android about Bezier Chinese articles can be divided into the following:

Popular Science type (just let people understand Bessel, and there is no substantive content)

Loading force type (put a lot of formulas, quoting a bunch of English original)

Basic type (only two function usages that explain Bezier curves)

Actual combat type (according to the example of the application of Bezier curve)

The above several types of useful is the basic and actual combat type, but both have shortcomings, this article will synthesize the content of the two, starting from scratch to learn the Bezier curve.

First step. Understanding the principles of Bezier curves

The understanding of Bezier curves here is not a process of learning the derivation of formulas (?ω?), but about how Bezier curves are generated. Bezier curves use a series of points to control the state of the curve, and I divide the points into two simple categories:

Type action

Data points determine the starting and ending positions of a curve

Control points determine how curved the curve is

Here, for the time being, the concept is understood, and the detailed meanings are explained in the following.

First-order curve principle:

The first order curve is no control point, only two data points (A and B), the final effect of a segment.

Represents a stage in the first-order curve generation process, and dynamic processes can be referenced (the dynamic presentation of the Bezier curve in this article is from Wikipedia).

PS: The first-order curve is actually the lineto that was previously explained.

Second-order curve principle:

The second-order curve consists of two data points (A and C), a control point (B) describing the curve state, roughly as follows:

The red curve part is the legendary quadratic Bezier curve, so how is this red curve generated? Next we'll analyze it in one of these states:

Connect AB BC and take point E on the AB D,BC to meet the conditions:

Connect de, take point F, make:

The point F that gets to this is a point on the Bezier curve, and the dynamic process is as follows:

PS: The second-order curve corresponds to the method is Quadto

Sankai Curve principle:

The Sankai curve describes the curve state by two data points (A and D) and two control points (B and C), as follows:

The Sankai curve calculation process is similar to the second order, which can be seen in dynamic effect:

PS: Sankai curve corresponds to the method is Cubicto

Bézier Curve quick Look table

It is highly recommended to practice Bezier curves here to deepen the understanding of Bezier curves.

The second step is to understand how Bezier curve correlation functions are used

First-order curve:

The first order curve is a line segment, very simple, you can see the previous article path of the basic operation, here is not explained in detail.

Second Order curve:

With a simple understanding of the second order curve above, we know that the second order curve is composed of two data points and a control point, and then we use an example to demonstrate how the second order curve is used.

First of all, two data points are the position to control the start and end of the Bezier curve, it is easier to understand, while the control point is controlled Bezier bending state, relatively difficult to understand, so this example is focused on understanding Bezier curve bending State and control points of the relationship, not much to say, first:

In order to make it easier to see the relationship between the control point and curve bending degree, the auxiliary points and auxiliary lines are drawn, from the dynamic graph above, we can see that the Bezier curve has the same elastic effect as the rubber band in the process of dynamic change, so it is often used when making some elastic effects.

The main code is as follows:


public class Bézier 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 (0,0);

end = new PointF (0,0);

Control = new PointF (0,0);

}

@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 location of data points and control points

Start.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) {

Updates control points based on touch location and prompts to redraw

control.x = Event.getx ();

Control.y = Event.gety ();

Invalidate ();

return true;

}

@Override

protected void OnDraw (canvas canvas) {

Super.ondraw (canvas);

Plotting 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 (Control.x,control.y,mpaint);

Draw Guides

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 Bezier Curves

Mpaint.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);

}

}

Sankai curve:

The Sankai curve controls the curve state 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 location of data points and control points

Start.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) {

Updates control points based on touch location and prompts to redraw

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);

Plotting 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 Guides

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 Bezier Curves

Mpaint.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);

}

}

The Sankai curve can make more complex shapes than the second-order curve, but for high-level curves, the combination of low-order curves can achieve the same effect, which is the legendary descending order. So our encapsulation of Bezier curves is generally up to Sankai curves.

Descending order and ascending order

Type interpretation change

Reducing the number of control points in order to maintain the shape and direction of the curve, that is, the reduction of the curve order method becomes simple, the data points become more, the control points may be reduced, the flexibility becomes weaker

In the case of maintaining the shape and direction of the curve, increase the number of control points, that is, the increasing curve order method is more complex, the data points are unchanged, the control points increase, flexibility becomes stronger

Step three. Bezier usage examples

Before making this instance, let's first clarify one thing, that is, under what circumstances will Bezier curves be used?

When you need to draw an irregular shape? Of course not! At present, I think the use of Bezier curve mainly has the following aspects (only personal humble opinion, there may be errors, please correct me)

Ordinal content use case

1 without prior knowledge of the curve state, a smooth line chart that requires real-time calculation of weather forecast temperature changes

2 display status will be changed according to user action qq Little red Dot, simulation book effect

3 Some more complex motion states (used with pathmeasure) animation effects of complex motion states

As for the situation where only a static curve graph is needed, it would be better to use a picture, and a lot of calculations would be very uneconomical.

If the SVG vector is displayed, there is already a relevant parsing tool (the Bezier curve is still used internally) and does not need to be calculated manually.

The main advantage of Bezier curve is that it can control the curve state in real time and make the curve smooth state change in real time by changing the state of the control point.

Next we'll use a simple example to make a circle gradient into a heart shape:

Thinking Analysis:

The effect of our final need is to transform a circle into a heart shape, and through analysis, the circle can be composed of four segments of the Sanche Besel curve, as follows:

The heart shape can also be composed of four segments of the three-order Bezier curve, as follows:

The difference between the two is that the data points and control points have different positions, so you only need to adjust the location of the data points and control points to change the circle to a heart shape.

Core difficulties:

1. How do I get the location of data points and control points?

about using the data points and control points to draw the circle has already been detailed calculation, you can refer to the StackOverflow of a answer how to create circle with Bézier curves? The data is only needed to be used.

And for the heart-shaped data points and control points, can be a circular part of the data points and control points to be translated, the specific parameters can be slowly adjusted to a satisfactory effect.

2. How do I achieve the gradient effect?

The gradient is actually each time the data points and control points slightly moved a little, and then redraw the interface, in a short time to adjust the data points and control points, so that it gradually close to the target value, through the continuous redrawing of the interface to achieve a gradient effect. The process can refer to dynamic effects:

Code:

public class Bezier3 extends View {

Private static final float C = 0.551915024494f; A constant used to calculate the position of the drawing point of a circular Bezier curve

Private Paint Mpaint;

private int Mcenterx, mcentery;

Private PointF Mcenter = new PointF (0,0);

Private float Mcircleradius = 200; Radius of the Circle

private float mdifference = mcircleradius*c; The difference between a circle's control point and the data points

Private float[] Mdata = new Float[8]; Four data points that draw a circle clockwise

Private float[] Mctrl = new FLOAT[16]; Eight control points that draw a circle clockwise

Private float mduration = 1000; Total length of change

private float mcurrent = 0; Current length of time

private float mCount = 100; How many copies of the duration are divided

private float mpiece = Mduration/mcount; The length of each serving

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);

Initializing data points

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 control points

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); Drawing Coordinate systems

Canvas.translate (Mcenterx, mcentery); Move the coordinate system to the center of the canvas

Canvas.scale (1,-1); Flip Y-Axis

Drawauxiliaryline (canvas);

Draw Bezier Curves

Mpaint.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) {

Plotting 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 Guides

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);

}

Drawing Coordinate systems

private void Drawcoordinatesystem (canvas canvas) {

Canvas.save (); Draw to do coordinate system

Canvas.translate (Mcenterx, mcentery); Move the coordinate system to the center of the canvas

Canvas.scale (1,-1); Flip Y-Axis

Paint Fuzhupaint = new paint ();

Fuzhupaint.setcolor (color.red);

Fuzhupaint.setstrokewidth (5);

Fuzhupaint.setstyle (Paint.Style.STROKE);

Canvas.drawline (0, -2000, 0, Fuzhupaint);

Canvas.drawline ( -2000, 0, 0, fuzhupaint);

Canvas.restore ();

}

}

Three. Summary

In fact, the most important thing about Bezier curves is the core understanding of how Bezier curves are generated, and only by understanding how Bezier curves are generated can we better use Bezier curves. At the end of the previous article to refer to a little self-intersecting graphics rendering problems, unfortunately, this article did not, please look forward to the next (may appear in the next article O ( ̄︶ ̄) o), the next article is still the path related content, to teach you something better to play.

Unlock the new realm of "draw a circle of elasticity":

(,,• ? •,,)

PS: Due to my limited level, some places may be misunderstood or inaccurate, if you have questions about this can submit issues for feedback.

Android Custom View Advanced: Bezier curve

Large-Scale Price Reduction
  • 59% Max. and 23% Avg.
  • Price Reduction for Core Products
  • Price Reduction in Multiple Regions
undefined. /
Connect with us on Discord
  • Secure, anonymous group chat without disturbance
  • Stay updated on campaigns, new products, and more
  • Support for all your questions
undefined. /
Free Tier
  • Start free from ECS to Big Data
  • Get Started in 3 Simple Steps
  • Try ECS t5 1C1G
undefined. /

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.