Android-Bessel Curve of Educational Notes on Good Knowledge

Keywords: Java Attribute Android less

I. Bessel function

The use of Bessel functions can draw smooth curves, often using second-order Bessel functions.

//Second-order Bessel  
//In the parameters (x1,y1) is the coordinate of the control point, (x2,y2) is the coordinate of the end point.
public void quadTo(float x1, float y1, float x2, float y2)   
//dx1: The control point X coordinate represents the displacement coordinate relative to the last end point X coordinate, which can be negative, positive value represents addition, negative value represents subtraction;
//dy1: Control point Y coordinate, relative to the displacement coordinate of the last end point Y coordinate. It can also be negative, positive value means adding, negative value means subtracting.
//dx2: The terminal X coordinate is also a relative coordinate. The displacement value of the last terminal X coordinate can be negative, positive value can be added, negative value can be subtracted.
//dy2: The terminal Y coordinate is also a relative displacement value relative to the last terminal Y coordinate. It can be negative, positive value can be added and negative value can be subtracted.
public void rQuadTo(float dx1, float dy1, float dx2, float dy2) 

Using the second-order Bessel function quadTo method, draw the following curve

This is the simplest code that can be understood by reference to the comments.

public class MyBezier extends View {
Context mContext;
Path mPath;
Paint mPaint;
public MyBezier(Context context) {
this(context,null);
}

public MyBezier(Context context, AttributeSet attrs) {
    super(context, attrs);
    mContext=context;
    init(mContext);
}
public void init(Context context){
    mPath=new Path();
    mPaint=new Paint();
    mPaint.setColor(0xffff0000);
    //Setting Anti-aliasing
    mPaint.setAntiAlias(true);
    mPaint.setStyle(Paint.Style.STROKE);
}

//This is the core approach.
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //This method fills in the starting point coordinates, that is, the P0 in the graph.
    mPath.moveTo(100,300);
    //Parametric 1 and 2: Represents the control point, which is the P1 in the graph.
    //Parameters 3 and 4: Represents the end point, which is the P2 in the graph.
    mPath.quadTo(200,100,300,300);
    //The meaning of the parameter is the same as above.
    mPath.quadTo(400,500,500,300);
    canvas.drawPath(mPath,mPaint);
    }
}

The starting point of the whole line is specified by Path.moveTo(x,y), and if we call quadTo(), the end point of the former quadTo() is the starting point of the next quadTo() function. Referring to the code above, we can see that there is no moveTo() method between the two quadTo() to specify the starting point, because quadTo() is called continuously, and the system defaults to be the starting point of the next quadTo() method. The end of a quadTo().
If Path.moveTo(x,y) is not initially invoked to specify the starting point, the top-left corner (0, 0) of the control is the default starting point.

2. Draw a curve without edges and corners with your fingers

First, curves with edges and corners

If you don't use the Bessel curve to draw a curve, you will find that the curve has edges and corners. The code and effect are as follows
If you look at the effect map carefully, you can see that there are obvious edges and corners in the curve part. Using Bessel curve, you can eliminate these edges and corners.

Two points need to be noted:
First, the question of return true in case MotionEvent.ACTION_DOWN: return TRUE indicates that the current control has consumed the push-down action, and subsequent ACTION_MOVE and ACTION_UP actions will continue to be passed to the current control; if we return false in case MotionEvent.ACTION_DOWN, then the subsequent ACTION_MOVE and ACTION_UP actions will no longer be passed to the control.

Second: The redraw control here uses invalidate(); of course, you can also use the postInvalidate() function. Both functions are used to redraw controls, but the difference is invalidate() must be executed in the UI thread, if not in the UI thread, it will report an error. PosInvalidate () is less elaborate, and it can be executed in any thread, not necessarily the main thread. In fact, postInvalidate() is implemented by using handler to send refresh interface messages to the main thread, so it can be executed in any thread without error. And because it's done by sending messages, its interface refresh may not be as fast as the invalidate() refresh directly.
So when we decide that the current thread is the main thread, or invalide() function is the main one. When we're not sure if the thread where we're going to refresh the page is the main thread or not, it's better to use postInvalidate.

Second, curves without edges and corners (using the qaudTo method)
The code is as follows, the code is not very much, mainly understand the core idea. The core of the code is the logic of onTouchEvent method, let's analyze it.

Drawing a line is divided into two parts, one is drawing a straight line, the other is drawing a curve, so the logic in the code should conform to these two parts, not just drawing a curve, but the logic of the code does not conform to the idea of drawing a straight line.
1. Analysis of drawing straight lines (mainly analyzing the code in onTouchEvent)
Suppose our starting point is (0,0), draw a straight line to the end point (10,10) (other points on the line are omitted)

mPreX=0,mPreY=0; 
endX=5,endY=5;

The parameters of quadTo are quadTo(0,0,5,5); that is to say, the control point is (0,0), the end point is (5,5), and the starting point is (0,0). So a simple analysis shows that the figure is a straight line.

2. Analysis of drawing curves (mainly analyzing the code in onTouchEvent)
Suppose we start at (0,0), turn around (10,10) and end at (20,10) (other points on the line are omitted)
The general figures are as follows.

(1) The parameters in the moveTo method: moveTo(0,0), but mPreX and mPreY are not (0,0), because when the MotionEvent.ACTION_MOVE method is executed, the points of mPreX and mPreY have been changed to (10,10), that is, B in the graph. When the point C is reached, the drawing curve ends. The parameters of this method are as follows.

mPath.moveTo(0,0)
mPath.quadTo(10,10,20,10);

3. Dynamic water waves
The following code realizes the effect of water waves, mainly the combination of attribute animation and Bessel function.
The following articles are about the use of attribute animation
http://blog.csdn.net/iispring/article/details/50322625
http://blog.csdn.net/guolin_blog/article/details/43536355
http://blog.csdn.net/guolin_blog/article/details/43536355

public class MyView5 extends View {
    Path mPath;
    Context mContext;
    Paint mPaint;
    // Length of a single wave
    int mWaveLength = 900;
    // Wave Height
    int mWaveHeight = 700;
    // Horizontal drift
    int distanceX = 0;
    // animation
    ValueAnimator mValueAnimator;

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

public MyView5(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

//This sentence means that only the version with level greater than 21 can be used.
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void init(Context context) {
mPath = new Path();
mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mContext = context;
//Set animation to color change
//Gradient from 0xff0000 to 0xff00ff00 and then to 0xff0000ff
//Period 6 s, uniform change
mValueAnimator = ValueAnimator.
ofArgb(0xffff0000, 0xff00ff00, 0xff0000ff);
mValueAnimator.setDuration(6000);
mValueAnimator.setInterpolator(new LinearInterpolator());
//The following callback is achieved for animation monitoring, in this case color change.
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float fraction = animation.getAnimatedFraction();
        // Calculating drift
        distanceX = (int) (mWaveLength * fraction * 10);
        // stroke color
        mPaint.setColor((Integer) animation.getAnimatedValue());
        // Repaint
        invalidate();
    }
});
startAnim();
}
@Override
protected void onDraw(Canvas canvas) {
// 1/4 water wave width
int halfWaveLength = mWaveLength / 2;
//Clear mPath
mPath.reset();
//Notice here that it's easier to fool around.
//The value of distance X% mWaveLength will not be greater than one wavelength
//So the value of - mWaveLength + distance X% mWaveLength will not be greater than zero
mPath.moveTo(-mWaveLength + distanceX % mWaveLength, mWaveHeight++);
// Draw n waves, each consisting of two second-order curves
for (int i = -mWaveLength; i <= getWidth() + mWaveLength; i += mWaveLength) {
mPath.rQuadTo(halfWaveLength / 2, -100, halfWaveLength, 0);
mPath.rQuadTo(halfWaveLength / 2, 100, halfWaveLength, 0);
}
// Closed areas under water waves
mPath.lineTo(getWidth(), getHeight());
mPath.lineTo(0, getHeight());
mPath.close();
canvas.drawPath(mPath, mPaint);
}
    //Not for the time being
public void reset() {
    mPath.reset();
    distanceX = 0;
    mWaveHeight = 700;
    invalidate();
    }
    //The Opening of Animation
public void startAnim() {
    mValueAnimator.start();
    }
}

On the Education of Good Knowledge (Official Website: Kindness Education < Click Enter > Wechat Public Number: Good Knowledge Technology
Address: Beijing Dongyan Suburb Economic and Technological Development Zone Cultural Building
Consulting Teacher: Mr. Zheng's Telephone/Wechat: 13315631002 QQ: 1939441377
At present, we have Java servers, HTML5 front-end web pages, Android mobile terminals, PHP servers, full-time classes, weekend classes;
Tuition discount to 8480!!!!!!
Our strengths:

  • Basic courses are offered free of charge in one month.
  • Average employment salary is 10,000-15,000;
  • Free hard-of-hearing, free interdisciplinary learning;
  • 5-5.5 months of large capacity technology teaching; 0 tuition fees, 0 basic admission;
  • Massive project training, flexible teaching system, flexible arrangement of teaching time;
  • Most students find jobs with salaries above 10k a month, and the project training will be terminated naturally.
  • Video recording of the whole course, occasionally delayed and not worried;
  • Fees can be refunded at any time on the way to study without reason according to the students'conditions.
  • One subject won't be able to learn another subject for free.
  • Full-time classes, weekend classes, online teaching at the same time;
  • QQ Group of Technical Exchange: 198983438 (Where to See Our Group) In the group at any time, we will update some of our course videos and class opening dynamics.

A summary of learning videos of kindheartedness education:

Posted by marketboy on Sun, 09 Jun 2019 17:14:56 -0700