Android animation effect of the left and right swing of the ball _android

Source: Internet
Author: User
Tags abs cos

First, look at the effect


Maybe you've seen something like this somewhere else, and I saw a gadget at the end of my micro-letter article, and it felt interesting, and it was done with code. This article mainly grasps the thought which writes the code to show.

See above, I think you can think of the simplest implementation is to use animation, cut a lot of graphics out, and then you can easily achieve. In order not to allow yourself to be too comfortable in the comfort zone, get some trouble: by calculation. The end of the article will have all the code posted, replication can be directly run.

Need to remember the knowledge

Geopotential E = MGH

Kinetic Energy E =½mv²

In an ideal state, kinetic energy and gravity can be converted to each other, and the energy conservation

If you do not want to pay attention to details, the above knowledge can be ignored

Drawing process

Draw 5 balls with a rope

This is a very simple step, as a general rule:

Determine the center coordinates of the ball O

Draw fixed-length segment OA

With Point O as the center, draw a ball with a fixed radius (this completes a ball with a rope).

Draw multiple balls with a rope

The relevant code at the end of the article has been posted (78-121 lines, the code has follow-up details to be processed, the need to identify the relevant code), here just write down the idea, no longer repeat

Put the code on.

Let the ball rotate.

The static diagram is:


To rotate a ball with a rope is actually to change the angle α of the upper figure, and the larger the α, the greater the angle of the offset, and the smaller the angle of the offset when the alpha is smaller.
To make the calculation simple, let's assume some prerequisites:

The maximum value of 1.α is 45° (this is free to value)

2. Each refresh screen Alpha changed the size of the value is consistent and 1 (that is, call the Invalidate () method)

3. First Alpha for 45°

With these prerequisites, in fact, each time we have a drawing we know that the condition is:

Coordinates of the 1.O point

2. Radius of great circle = length of rope and radius of small circle

3.α values (because of 2 and 3 of the premises, the angle of the current alpha can be known when drawing)

So, the approximate process for this step is:

1. According to the center of the Circle O, radius r, the current alpha angle, to find the coordinates of the B point (similar to the previous article, by drawing arcs, and then through the Pathmeasure.getpostan () to obtain the coordinates of the corresponding points)

2. Draw Segment OB

3. A small circle with a fixed radius at the center of Point B

The relevant code at the end of the article has been posted (128-212 lines, the code has follow-up details to deal with, you need to identify the relevant code), here just write down the idea, no longer heavy

Duplicate code.

Simulation reality

In the previous step, in order to simplify the model, let Alpha change the amount of 1 each time, but this does not match the reality. The reality is this:

1. When the ball is offset to the highest point, the speed is very slow, basically 0

2. The ball is offset to the lowest point, the fastest speed

At the beginning of the article, we are ready to recall the knowledge, now, let's go back to the physics class, say a simple pendulum model calculation:

Condition: The length of the rope is L, the ball A is still, the angle in the vertical direction is α

The angular velocity of a β when the angle is in the vertical direction

Solving steps to find the total mechanical energy

Mechanical energy = geopotential when the ball is stationary

Representation of the general situation

When the ball is moving, the mechanical energy = geopotential + kinetic energy

There are also formulas:

So the end result is:

Well, come to the conclusion, let's go back to the code:

Calculates the current rate
float v = (float) math.sqrt (2 * 9.8 * L * (Math.Cos (β* math.pi/180)-cos (α* math.pi/180)));
Calculate the angular velocity of
float w = v/l;

Description: Here just fitting, and not particularly precise. We think that the angular velocity between the current angle and the changed angle is the same, and it is the angular velocity corresponding to the current angle.

So, at the current angle, the amount of change in the angle is:

The specific implementation process in the following code of 219-225 lines, is not feeling very simple?

All code

Luo Li in the long time, finally give out the things can be copied O (∩_∩) o~

/** * Created by Kevin on 2016/9/2. * <p> * need to be examined: * 1. Draw multiple balls with ropes * 2. Let the ball of the right and left sides rotate * 3. To simulate reality, the angle of rotation of unit time is required according to physics/public class Pendulum extends Vie W {private Paint linepaint; private int width; private int height; private path linepath;//used to draw a static part path private path big circlepath;//is used to measure the great circle's path private path rotatelinepath;//is used to draw the dynamic part of the path private int stroke = 5; Width of line segments private int r = 20; Radius of the circle private int length = 200; Length of the line private int number = 5; The number of balls (odd, even feel ugly is not implemented) private static int angle = 50;//maximum rotation angle//first parameter representation angle; Negative numbers indicate the angle of the left ball rotation, positive numbers indicate the angle of rotation of the right ball/+ Angle that the right side of the ball deviation from the maximum angle of 30 degrees//-angle that the left ball deviation from the maximum angle of 30 degrees//The second parameter indicates direction;-1 means to swing from right to left, 1 to swing from left to right private float[] degree = new float[]{
Angle,-1};  Private float t = 2f;//time; can be used to control the rate, t the smaller, the pendulum Zhong slow, the larger t, the faster the pendulum private float coso;//cosθ, is a fixed value private float gr2;//2gr, is a fixed value public Pendulum (context) {Super [context]; Initpaint (); calcosoand2gr ();} public pendulum (context, Attributese T attrs) {Super (context, attrs); Initpaint (); Calcosoand2GR (); Public pendulum (context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr); Initpaint (
);
CALCOSOAND2GR (); /** * is used to compute cosθ and 2GR/private void calcosoand2gr () {//here in order to avoid cosα-cosθ=0 situation, so +0.1 CosO = (float) math.cos (angle + 0.1f
) * math.pi/180);
Twice times the gravitational acceleration multiplied by the radius GR2 = (float) (9.8 * R * 2); @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas); Canvas.translate (WIDTH/2, HEIGHT/2); Drawpic (
Canvas);
Rotate (canvas); /** * Draw Static Graphics * * @param canvas/private void drawpic (canvas canvas) {if (number < 1) {throw new Illegalargumentex
Ception ("Quantity cannot be less than 1");
int x; if (number% 2 = 1) {//odd case//used to determine the outermost position, for example: If number is 3,leftnumber 1//number is 5,leftnumber 2//number is 7,leftnumber 3 I
NT Leftnumber = NUMBER/2; for (int i =-leftnumber i <= leftnumber; i++) {if (Isright ()) {//rightmost in swing if (i = = Leftnumber) continue;} else if (!
Isright ()) {//leftmost in the swing if (i = =-leftnumber) Continue}//The horizontal axis of the center of the calculation x x = 2 * R * I; if (Linepath = = null) Linepath = new Path ();
Linepath.reset ();
Move to center (more accurate coordinates (X,-R), the circle will be drawn out to cover part of the line; here just to make it easier to express, no longer add extra points) Linepath.moveto (x, 0);
Draw a line to the vertex (the vertex from the center of the circle = the length + radius of the segment) Linepath.lineto (x,-(r + length));
Draw Straight Line Linepaint.setstyle (Paint.Style.FILL_AND_STROKE);
Canvas.drawpath (Linepath, linepaint);
Draws the circle, in order not to coincide, uses FILL, does not draw the line width linepaint.setstyle (Paint.Style.FILL);
Canvas.drawcircle (x, 0, R, Linepaint);
' Else if (number% 2 = 0) {//even throw new illegalargumentexception ("Even too ugly, no Draw");} /** * Draw Rotated Graphics * * @param canvas/private void rotate (canvas canvas) {//Left ball motion and right ball motion are symmetric, using direction (value +1 or-1) to mark Int dir
ection; if (Isright ()) {//Right ball motion, +1 direction = 1;} else {//left ball tung, -1 direction =-1;}//measure.getpostan () does not accept negative numbers, you need to take absolute value Floa
T nowdegree = Math.Abs (degree[0]);
Linepaint.setstyle (Paint.Style.STROKE);
Determine the number of one-sided outer picture int pointnumber = NUMBER/2;
Determine the horizontal coordinate of the static circle, and the drawpic (x = 2 * R * i) is similar to int x = 2 * R * pointnumber * direction; Used to determine the coordinates of the center of the circle, and also the coordinates of the vertex of the segment float[] Toppoint = new Float[]{x,-(R + length)};
int totallength = length + R;
if (Bigcirclepath = = null) Bigcirclepath = new Path ();
Bigcirclepath.reset (); RECTF is used to draw arcs: the vertices of a segment are centered, length + R is curved for radii rectf RECTF = new RECTF (toppoint[0)-Totallength, toppoint[1]-totallength, t
Oppoint[0] + totallength, toppoint[1] + totallength);
Draw 1/4 Circular arc bigcirclepath.addarc (RECTF, -90 * direction);
The boundary coordinates used to determine the rotational nowdegree; float[] Rotatepoint = new float[2];
Pathmeasure measure = new Pathmeasure (Bigcirclepath, false);
At this point, the coordinates of the rotatepoint are the coordinates of the center of the small Circle in our graph (measure.getlength () * (nowdegree)/Measure.getpostan, rotatepoint, NULL);
So far, we know the coordinates of the center and the coordinates of the vertex of the segment.
Below, we link the two points and draw the circle with Rotatepoint as the center of the line//Draw segment if (Rotatelinepath = null) Rotatelinepath = new Path ();
Rotatelinepath.reset ();
Rotatelinepath.moveto (Toppoint[0], toppoint[1]);
Rotatelinepath.lineto (Rotatepoint[0], rotatepoint[1]);
Canvas.drawpath (Rotatelinepath, linepaint);
Draw round Linepaint.setstyle (Paint.Style.FILL); Canvas.drawcircle (Rotatepoint[0], rotatepoint[1], R, LINEPaint);
Display text with the linepaint.settextsize (40);
Canvas.drawtext ("Offset angle:" + degree[0] + "", -100, Linepaint); DEGREE[1] indicates direction, when it is 1 o'clock, which means moving from left to right, then degree[0] need to increase continuously (this is my stipulation, of course, if you want to change, you can modify it according to the situation, estimate the modification will be dizzy for a while) if (degree[1] = = 1) {//from total to right degree increase if (degree[0] < angle) {//compute the angle that needs to rotate the float changeangle = Rotateangle ();//Change the value of the current angle degree[0] = degree[0] + Cha
Ngeangle;
Invalidate ();
//When the rightmost is reached, the direction flips if (degree[0] >= angle) {degree[1] =-1;}} DEGREE[1] indicates direction, when 1, the movement from right to left, then degree[0] need to be reduced (this is my rule, of course, if you want to modify, can be modified according to the situation, estimate the modification will be dizzy for a while) else if (degree[1] = = 1) {/ /From right to left, degree reduce if (degree[0] >-angle) {//compute the angle that needs to rotate the float changeangle = Rotateangle ();//Change the value of the current angle degree[0] = degree[0
]-Changeangle;
Invalidate ();
//When the leftmost is reached, the direction flips if (Degree[0] <=-angle) {degree[1] = 1;} /** * Calculates the current need to rotate the angle * * @return/private float Rotateangle () {//Compute the current rate float v = (float) math.sqrt (GR2 * (Math.Cos
H.abs (degree[0]) * math.pi/180)-CosO));
Calculate the radians that need to be changed float Changedangle = t * V/R; Return ChangEdangle; /** * Determine if the sphere on the right is moving * * @return true--> on the right side of the sphere in motion * false--> the ball on the left is moving * * Private Boolean Isright () {Boolean flag = Fals
E DEGREE[0] is greater than 0, indicating that the right ball is moving//degree[1] less than 0, indicating that the left ball is in the move if (Degree[0] > 0) {flag = true;} else if (Degree[0] < 0) {flag = f
Alse; else if (degree[0] = = 0) {//If degree equals 0, it needs to be judged by direction which is//degree[1] equal to 1: the ball is moving from right to left, at this time, the velocity of the ball is v-->0, but the right ball is moving if (Degr
EE[1] = = 1) {flag = true;}//In contrast to the above, is the ball on the left of the move else if (degree[1] = = 1) {flag = false;}}
return flag; @Override protected void onsizechanged (int w, int h, int oldw, int oldh) {super.onsizechanged (W, H, OLDW, OLDH); width
= W;
Height = h;
private void Initpaint () {//here do not want to get multiple Paint, with a Paint to replace, if necessary, you can increase the Paint to draw the specified graphics linepaint = new Paint ();
Linepaint.setstrokewidth (stroke);
Linepaint.setantialias (TRUE);
Linepaint.setstyle (Paint.Style.FILL_AND_STROKE);
Linepaint.setcolor (0XFF4897FE); }
}

The above is a small set to introduce the Android to achieve sway around the ball animation effect, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

Related Article

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.