Android suction animation effect decomposition _android

Source: Internet
Author: User
Tags abstract static class
Android suction animation effect detailed.





Here, I want to introduce how to achieve a similar effect on Android. First look at the effect I realized.





The above illustration shows a few frames of the animation, from 1-4, which shows the picture being inhaled from the original graphic to a point (red logo).


To achieve this effect, we took advantage of the Canvas.drawbitmapmesh () method, which involves the concept of a mesh.


The concept of 2,mesh


Mesh for the grid, say more popular, you can imagine the artboard as a lattice cloth, on this piece of cloth to draw pictures. For grids with uniformly distributed grid endpoints, there are meshwidth + 1 vertices horizontally, with meshheight + 1 endpoints longitudinally. Vertex data verts are rows-first arrays (two-dimensional arrays are represented in one-dimensional arrays, preceded by columns). Grids can be unevenly distributed. Take a look at the following picture:





The picture above shows the image divided into many squares, each lattice in the above figure is homogeneous and its vertex number is: (Meshwidth + 1) * (Meshheight + 1), then the size of the one-dimensional data to place these vertices should be: (Meshwidth + 1) * (meshheight + 1) * 2 (one point contains x, y coordinates)


Copy Code code as follows:

float[] vertices = new float[: (meshwidth + 1) * (Meshheight + 1) * 2];



Just imagine, we let this lattice (mesh) uneven distribution, then the drawing out of the picture will be distorted, look at the following image:





3, how to build mesh


Inhale the core of the animation is inhaled to a point, then we will be at different times to construct different mesh vertex coordinates, how do we do it?


3.1, create two paths (path)


If our inhalation effect is inhaled from top to bottom, the path we construct is shown in the following illustration:





The blue lines in the image above represent the path we construct, but we can build mesh vertices along these two path.


The code to build two path is as follows:


Copy Code code as follows:

Mfirstpathmeasure.setpath (Mfirstpath, false);
Msecondpathmeasure.setpath (Msecondpath, false);
float w = mbmpwidth;
float h = mbmpheight;
Mfirstpath.reset ();
Msecondpath.reset ();
Mfirstpath.moveto (0, 0);
Msecondpath.moveto (w, 0);
Mfirstpath.lineto (0, h);
Msecondpath.lineto (W, h);
Mfirstpath.quadto (0, (EndY + H)/2, EndX, EndY);
Msecondpath.quadto (W, (EndY + H)/2, EndX, EndY);



3.2, calculate vertex coordinates according to path


Algorithm:


1, if we divide the lattice into the width, the height, and the length of the path by 20, [0, length], which means 20 moments.


2, No. 0 time, we want the shape is a rectangle, the 1th moment may be trapezoidal, nth time may be a triangle. The following figure illustrates the changes in the picture during the animation.





3, the length of the first (left) path is len1, the length of the second (right) path is len2, and for any moment T [0-20] We can know the length of the four vertices of the trapezoid from the top of the path.


Upper left corner: T * (LEN1/20)


Lower left corner: T * (LEN1/20) + bitmapheight


upper right Corner: T * (LEN2/20)


Lower right corner: T * (LEN2/20) + bitmapheight





We can use the Pathmeasure class to calculate the coordinates of the point on the path based on length, that is to say, according to two path, we can calculate the coordinates of four vertices respectively, I here is called A, B, C, D (clockwise), with the coordinates of the point, we can calculate the ad, The length of the BC, and the base is divided into the height (because we divide the mesh into wide width, high height division), the AD,BC above each equal points to form a direct, and then this direct horizontal width equal, according to the linear equation, based on X calculated y, So that the coordinates of each vertex are calculated. (Please refer to the above picture)


The following is a detailed code for calculating vertex coordinates:


Copy Code code as follows:



private void buildmeshbypathonvertical (int timeindex)


{


Mfirstpathmeasure.setpath (Mfirstpath, false);


Msecondpathmeasure.setpath (Msecondpath, false);


int index = 0;


Float[] Pos1 = {0.0f, 0.0f};


Float[] Pos2 = {0.0f, 0.0f};


float Firstlen = Mfirstpathmeasure.getlength ();


float Secondlen = Msecondpathmeasure.getlength ();


float len1 = firstlen/height;


float len2 = secondlen/height;


float firstpointdist = Timeindex * LEN1;


float secondpointdist = Timeindex * LEN2;


float height = mbmpheight;


Mfirstpathmeasure.getpostan (firstpointdist, POS1, NULL);


Mfirstpathmeasure.getpostan (firstpointdist + height, pos2, null);


float x1 = pos1[0];


float x2 = pos2[0];


float y1 = pos1[1];


float y2 = pos2[1];


float first_dist = (float) math.sqrt (x1-x2) * (X1-X2) + (y1-y2) * (Y1-y2));


float first_h = first_dist/height;


Msecondpathmeasure.getpostan (secondpointdist, POS1, NULL);


Msecondpathmeasure.getpostan (secondpointdist + height, pos2, null);


x1 = pos1[0];


x2 = pos2[0];


y1 = pos1[1];


y2 = pos2[1];


float second_dist = (float) math.sqrt (x1-x2) * (X1-X2) + (y1-y2) * (Y1-y2));


float second_h = second_dist/height;


for (int y = 0; y <= HEIGHT; ++y)


{


Mfirstpathmeasure.getpostan (Y * first_h + firstpointdist, pos1, NULL);


Msecondpathmeasure.getpostan (Y * second_h + secondpointdist, pos2, NULL);


float w = pos2[0]-pos1[0];


Float fx1 = pos1[0];


float FX2 = pos2[0];


float fy1 = pos1[1];


float fy2 = pos2[1];


float dy = fy2-fy1;


float dx = fx2-fx1;


for (int x = 0; x <= WIDTH; ++x)


{


y = x * dy/dx


FLOAT FX = x * w/width;


float FY = FX * DY/DX;


Mverts[index * 2 + 0] = FX + fx1;


Mverts[index * 2 + 1] = fy + fy1;


Index + 1;


}


}


}





4, how to draw


Drawing code is simple, calling the Canvas.drawbitmapmesh method. The most essential thing is to compute a list of top points.


Copy Code code as follows:

Canvas.drawbitmapmesh (Mbitmap,
Minhalemesh.getwidth (),
Minhalemesh.getheight (),
Minhalemesh.getvertices (),
0, NULL, 0, mpaint);



5, how to achieve animation


Copy Code code as follows:

protected void Applytransformation (float interpolatedtime, transformation t)
{
int curindex = 0;
Interpolator interpolator = This.getinterpolator ();
if (null!= interpolator)
{
Float value = interpolator.getinterpolation (interpolatedtime);
Interpolatedtime = value;
}
if (mreverse)
{
Interpolatedtime = 1.0f-interpolatedtime;
}
Curindex = (int) (Mfromindex + (mendindex-mfromindex) * interpolatedtime);
if (null!= mlistener)
{
Mlistener.onanimupdate (Curindex);
}
}



In the animation, we calculate the index of the frame to be animated, suppose we divide the inhalation animation into 20 frames, in the animation, calculate each frame, and finally through the onanimupdate (int index) method callback, in this method implementation, We recalculate a new mesh vertex array based on the index of the frame, and then use this array to draw the bitmap. In this way, we can see a series of continuous changes in the mesh, you will be able to view the expansion effect of animation.


Animation class inside, the core is to extend the animation class, rewrite the Applytransformation method.


6, summary


This paper briefly introduces the realization of the suction effect, according to this principle, we can construct more complex path to do more effect. At the same time, can also achieve upward, left, right suction effect.


The most essential thing is that we should understand the concept of mesh, the most important task is to construct the vertex coordinates of mesh.


Computing mesh is usually a very complex work, make some simple deformation can also, for too complex deformation, may not be very convenient. In addition, like the effect of book page, with mesh is actually can do. Just the algorithm is a little more complicated.


Here can not give a complete code, the principle may not be too clear, I hope to the people who want to achieve a guide to the idea.


7, implementation code


Inhaleanimationactivity.java


Copy Code code as follows:



Package Com.nj1s.lib.test.anim;


Import Android.os.Bundle;


Import android.view.Gravity;


Import Android.view.Menu;


Import Android.view.MenuItem;


Import Android.view.View;


Import Android.widget.Button;


Import Android.widget.LinearLayout;


Import Com.nj1s.lib.mesh.InhaleMesh.InhaleDir;


Import com.nj1s.lib.test.GABaseActivity;


Import COM.NJ1S.LIB.TEST.R;


Import Com.nj1s.lib.test.effect.BitmapMesh;


public class Inhaleanimationactivity extends gabaseactivity


{


Private static Final Boolean debug_mode = false;


Private Bitmapmesh.sampleview Msampleview = null;


@Override


protected void OnCreate (Bundle savedinstancestate)


{


Super.oncreate (savedinstancestate);


LinearLayout linearlayout = new LinearLayout (this);


Msampleview = new Bitmapmesh.sampleview (this);


Msampleview.setisdebug (Debug_mode);


Msampleview.setlayoutparams (New Linearlayout.layoutparams (-1,-1));


Button btn = New button (this);


Btn.settext ("Run");


Btn.settextsize (20.0f);


Btn.setlayoutparams (New Linearlayout.layoutparams (150,-2));


Btn.setonclicklistener (New View.onclicklistener ()


{


Boolean mreverse = false;


@Override


public void OnClick (View v)


{


if (Msampleview.startanimation (Mreverse))


{


Mreverse =!mreverse;


}


}


});


Linearlayout.setorientation (linearlayout.vertical);


Linearlayout.setgravity (gravity.center_vertical);


Linearlayout.addview (BTN);


Linearlayout.addview (Msampleview);


Setcontentview (LinearLayout);


}


@Override


public boolean Oncreateoptionsmenu (Menu menu)


{


Getmenuinflater (). Inflate (R.menu.inhale_anim_menu, menu);


return true;


}


@Override


public boolean onoptionsitemselected (MenuItem Item)


{


Switch (Item.getitemid ())


{


Case R.id.menu_inhale_down:


Msampleview.setinhaledir (Inhaledir.down);


Break


Case R.ID.MENU_INHALE_UP:


Msampleview.setinhaledir (inhaledir.up);


Break


Case R.id.menu_inhale_left:


Msampleview.setinhaledir (Inhaledir.left);


Break


Case R.id.menu_inhale_right:


Msampleview.setinhaledir (Inhaledir.right);


Break


}


return super.onoptionsitemselected (item);


}


}





Bitmapmesh.java


Copy Code code as follows:



/*


* Copyright (C) 2008 the Android Open Source Project


*


* Licensed under the Apache License, Version 2.0 (the "License");


* You could not use this file, except in compliance with the License.


* Obtain a copy of the License at


*


* http://www.apache.org/licenses/LICENSE-2.0


*


* Unless required by applicable or agreed to in writing, software


* Distributed under the License is distributed on ' as ' basis,


* Without warranties or CONDITIONS of any KIND, either express or implied.


* The License for the specific language governing permissions and


* Limitations under the License.


*/


Package com.nj1s.lib.test.effect;


Import Android.content.Context;


Import Android.graphics.Bitmap;


Import Android.graphics.BitmapFactory;


Import Android.graphics.Canvas;


Import Android.graphics.Color;


Import Android.graphics.Matrix;


Import Android.graphics.Paint;


Import Android.graphics.Paint.Style;


Import Android.graphics.Path;


Import Android.util.Log;


Import android.view.MotionEvent;


Import Android.view.View;


Import android.view.animation.Animation;


Import Android.view.animation.Interpolator;


Import android.view.animation.Transformation;


Import Com.nj1s.lib.mesh.InhaleMesh;


Import Com.nj1s.lib.mesh.InhaleMesh.InhaleDir;


Import COM.NJ1S.LIB.TEST.R;


public class Bitmapmesh {


public static class Sampleview extends View {


private static final int WIDTH = 40;


private static final int HEIGHT = 40;


Private final Bitmap Mbitmap;


Private final Matrix Mmatrix = new Matrix ();


Private final Matrix Minverse = new Matrix ();


Private Boolean misdebug = false;


Private Paint Mpaint = new Paint ();


Private float[] minhalept = new float[] {0, 0};


Private Inhalemesh Minhalemesh = null;


Public Sampleview {


Super (context);


Setfocusable (TRUE);


Mbitmap = Bitmapfactory.decoderesource (Getresources (),


R.drawable.beach);


Minhalemesh = new Inhalemesh (WIDTH, HEIGHT);


Minhalemesh.setbitmapsize (Mbitmap.getwidth (), Mbitmap.getheight ());


Minhalemesh.setinhaledir (Inhaledir.down);


}


public void Setisdebug (Boolean isdebug)


{


Misdebug = Isdebug;


}


public void Setinhaledir (Inhalemesh.inhaledir dir)


{


Minhalemesh.setinhaledir (dir);


float w = mbitmap.getwidth ();


Float h = mbitmap.getheight ();


float EndX = 0;


float EndY = 0;


float dx = 10;


float dy = 10;


Mmatrix.reset ();


Switch (dir)


{


Case down:


EndX = W/2;


EndY = GetHeight ()-20;


Break


Case up:


DY = getheight ()-h-20;


EndX = W/2;


EndY =-dy + 10;


Break


Case left:


DX = getwidth ()-w-20;


EndX =-dx + 10;


EndY = H/2;


Break


Case right:


EndX = GetWidth ()-20;


EndY = H/2;


Break


}


Mmatrix.settranslate (dx, dy);


Mmatrix.invert (Minverse);


Buildpaths (EndX, EndY);


Buildmesh (W, h);


Invalidate ();


}


@Override


protected void onsizechanged (int w, int h, int oldw, int oldh)


{


Super.onsizechanged (W, H, OLDW, OLDH);


float BMPW = Mbitmap.getwidth ();


float bmph = Mbitmap.getheight ();


Mmatrix.settranslate (10, 10);


Mmatrix.settranslate (10, 10);


Mmatrix.invert (Minverse);


Mpaint.setcolor (color.red);


Mpaint.setstrokewidth (2);


Mpaint.setantialias (TRUE);


Buildpaths (BMPW/2, h-20);


Buildmesh (BMPW, bmph);


}


Public Boolean startanimation (Boolean reverse)


{


Animation anim = This.getanimation ();


if (null!= anim &&!anim.hasended ())


{


return false;


}


pathanimation animation = new Pathanimation (0, HEIGHT + 1, reverse,


New Pathanimation.ianimationupdatelistener ()


{


@Override


public void onanimupdate (int index)


{


Minhalemesh.buildmeshes (index);


Invalidate ();


}


});


if (null!= animation)


{


Animation.setduration (1000);


This.startanimation (animation);


}


return true;


}


@Override


protected void OnDraw (Canvas Canvas)


{


LOG.I ("Leehong2", "OnDraw ===========");


Canvas.drawcolor (0xFFCCCCCC);


Canvas.concat (Mmatrix);


Canvas.drawbitmapmesh (Mbitmap,


Minhalemesh.getwidth (),


Minhalemesh.getheight (),


Minhalemesh.getvertices (),


0, NULL, 0, mpaint);


// ===========================================


Draw the target point.


Mpaint.setcolor (color.red);


Mpaint.setstyle (Style.fill);


Canvas.drawcircle (Minhalept[0], minhalept[1], 5, mpaint);


if (Misdebug)


{


// ===========================================


Draw the mesh vertices.


Canvas.drawpoints (Minhalemesh.getvertices (), mpaint);


// ===========================================


Draw The paths


Mpaint.setcolor (Color.Blue);


Mpaint.setstyle (Style.stroke);


path[] paths = minhalemesh.getpaths ();


for (Path path:paths)


{


Canvas.drawpath (path, mpaint);


}


}


}


private void Buildmesh (float W, float h)


{


Minhalemesh.buildmeshes (W, h);


}


private void Buildpaths (float endx, float EndY)


{


Minhalept[0] = EndX;


MINHALEPT[1] = EndY;


Minhalemesh.buildpaths (EndX, EndY);


}


int mlastwarpx = 0;


int mlastwarpy = 0;


@Override


public boolean ontouchevent (Motionevent event)


{


Float[] pt = {Event.getx (), event.gety ()};


Minverse.mappoints (PT);


if (event.getaction () = = motionevent.action_up)


{


int x = (int) pt[0];


int y = (int) pt[1];


if (mlastwarpx!= x | | | mlastwarpy!= y) {


MLASTWARPX = x;


Mlastwarpy = y;


Buildpaths (Pt[0], pt[1]);


Invalidate ();


}


}


return true;


}


}


private static class Pathanimation extends Animation


{


public interface Ianimationupdatelistener


{


public void onanimupdate (int index);


}


private int mfromindex = 0;


private int mendindex = 0;


Private Boolean mreverse = false;


Private Ianimationupdatelistener mlistener = null;


Public pathanimation (int fromindex, int endindex, Boolean reverse, Ianimationupdatelistener listener)


{


Mfromindex = Fromindex;


Mendindex = Endindex;


Mreverse = reverse;


Mlistener = listener;


}


public boolean gettransformation (long currenttime, transformation outtransformation) {


Boolean more = Super.gettransformation (CurrentTime, outtransformation);


LOG.D ("Leehong2", "gettransformation more =" + more);


return to more;


}


@Override


protected void Applytransformation (float interpolatedtime, transformation t)


{


int curindex = 0;


Interpolator interpolator = This.getinterpolator ();


if (null!= interpolator)


{


Float value = interpolator.getinterpolation (interpolatedtime);


Interpolatedtime = value;


}


if (mreverse)


{


Interpolatedtime = 1.0f-interpolatedtime;


}


Curindex = (int) (Mfromindex + (mendindex-mfromindex) * interpolatedtime);


if (null!= mlistener)


{


LOG.I ("Leehong2", "onanimupdate =========== curindex =" + Curindex);


Mlistener.onanimupdate (Curindex);


}


}


}


}





The core of the class


Inhalemesh


Copy Code code as follows:



Package Com.nj1s.lib.mesh;


Import Android.graphics.Path;


Import Android.graphics.PathMeasure;


public class Inhalemesh extends Mesh


{


public enum Inhaledir


{


Up,


Down,


Left,


Right,


}


Private Path Mfirstpath = new Path ();


Private Path Msecondpath = new Path ();


Private Pathmeasure mfirstpathmeasure = new Pathmeasure ();


Private Pathmeasure msecondpathmeasure = new Pathmeasure ();


Private Inhaledir minhaledir = Inhaledir.down;


public Inhalemesh (int width, int height)


{


Super (width, height);


}


public void Setinhaledir (Inhaledir inhaledir)


{


Minhaledir = Inhaledir;


}


Public Inhaledir Getinhaledir ()


{


return minhaledir;


}


@Override


public void buildpaths (float endx, float EndY)


{


if (mbmpwidth <= 0 | | | mbmpheight <= 0)


{


throw New IllegalArgumentException (


"Bitmap size must is > 0, do I call setbitmapsize (int, int) method?");


}


Switch (MINHALEDIR)


{


Case up:


Buildpathsup (EndX, EndY);


Break


Case down:


Buildpathsdown (EndX, EndY);


Break


Case right:


Buildpathsright (EndX, EndY);


Break


Case left:


Buildpathsleft (EndX, EndY);


Break


}


}


@Override


public void buildmeshes (int index)


{


if (mbmpwidth <= 0 | | | mbmpheight <= 0)


{


throw New IllegalArgumentException (


"Bitmap size must is > 0, do I call setbitmapsize (int, int) method?");


}


Switch (MINHALEDIR)


{


Case up:


Case down:


Buildmeshbypathonvertical (index);


Break


Case right:


Case left:


Buildmeshbypathonhorizontal (index);


Break


}


}


Public path[] Getpaths ()


{


return new path[] {mfirstpath, msecondpath};


}


private void Buildpathsdown (float endx, float EndY)


{


Mfirstpathmeasure.setpath (Mfirstpath, false);


Msecondpathmeasure.setpath (Msecondpath, false);


float w = mbmpwidth;


float h = mbmpheight;


Mfirstpath.reset ();


Msecondpath.reset ();


Mfirstpath.moveto (0, 0);


Msecondpath.moveto (w, 0);


Mfirstpath.lineto (0, h);


Msecondpath.lineto (W, h);


Mfirstpath.quadto (0, (EndY + H)/2, EndX, EndY);


Msecondpath.quadto (W, (EndY + H)/2, EndX, EndY);


}


private void Buildpathsup (float endx, float EndY)


{


Mfirstpathmeasure.setpath (Mfirstpath, false);


Msecondpathmeasure.setpath (Msecondpath, false);


float w = mbmpwidth;


float h = mbmpheight;


Mfirstpath.reset ();


Msecondpath.reset ();


Mfirstpath.moveto (0, h);


Msecondpath.moveto (W, h);


Mfirstpath.lineto (0, 0);


Msecondpath.lineto (w, 0);


Mfirstpath.quadto (0, (endy-h)/2, EndX, EndY);


Msecondpath.quadto (W, (endy-h)/2, EndX, EndY);


}


private void Buildpathsright (float endx, float EndY)


{


Mfirstpathmeasure.setpath (Mfirstpath, false);


Msecondpathmeasure.setpath (Msecondpath, false);


float w = mbmpwidth;


float h = mbmpheight;


Mfirstpath.reset ();


Msecondpath.reset ();


Mfirstpath.moveto (0, 0);


Msecondpath.moveto (0, h);


Mfirstpath.lineto (w, 0);


Msecondpath.lineto (W, h);


Mfirstpath.quadto (EndX + W)/2, 0, EndX, EndY);


Msecondpath.quadto ((EndX + W)/2, H, EndX, EndY);


}


private void Buildpathsleft (float endx, float EndY)


{


Mfirstpathmeasure.setpath (Mfirstpath, false);


Msecondpathmeasure.setpath (Msecondpath, false);


float w = mbmpwidth;


float h = mbmpheight;


Mfirstpath.reset ();


Msecondpath.reset ();


Mfirstpath.moveto (w, 0);


Msecondpath.moveto (W, h);


Mfirstpath.lineto (0, 0);


Msecondpath.lineto (0, h);


Mfirstpath.quadto ((endx-w)/2, 0, EndX, EndY);


Msecondpath.quadto ((endx-w)/2, H, EndX, EndY);


}


private void buildmeshbypathonvertical (int timeindex)


{


Mfirstpathmeasure.setpath (Mfirstpath, false);


Msecondpathmeasure.setpath (Msecondpath, false);


int index = 0;


Float[] Pos1 = {0.0f, 0.0f};


Float[] Pos2 = {0.0f, 0.0f};


float Firstlen = Mfirstpathmeasure.getlength ();


float Secondlen = Msecondpathmeasure.getlength ();


float len1 = firstlen/height;


float len2 = secondlen/height;


float firstpointdist = Timeindex * LEN1;


float secondpointdist = Timeindex * LEN2;


float height = mbmpheight;


Mfirstpathmeasure.getpostan (firstpointdist, POS1, NULL);


Mfirstpathmeasure.getpostan (firstpointdist + height, pos2, null);


float x1 = pos1[0];


float x2 = pos2[0];


float y1 = pos1[1];


float y2 = pos2[1];


float first_dist = (float) math.sqrt (x1-x2) * (X1-X2) + (y1-y2) * (Y1-y2));


float first_h = first_dist/height;


Msecondpathmeasure.getpostan (secondpointdist, POS1, NULL);


Msecondpathmeasure.getpostan (secondpointdist + height, pos2, null);


x1 = pos1[0];


x2 = pos2[0];


y1 = pos1[1];


y2 = pos2[1];


float second_dist = (float) math.sqrt (x1-x2) * (X1-X2) + (y1-y2) * (Y1-y2));


float second_h = second_dist/height;


if (Minhaledir = = Inhaledir.down)


{


for (int y = 0; y <= HEIGHT; ++y)


{


Mfirstpathmeasure.getpostan (Y * first_h + firstpointdist, pos1, NULL);


Msecondpathmeasure.getpostan (Y * second_h + secondpointdist, pos2, NULL);


float w = pos2[0]-pos1[0];


Float fx1 = pos1[0];


float FX2 = pos2[0];


float fy1 = pos1[1];


float fy2 = pos2[1];


float dy = fy2-fy1;


float dx = fx2-fx1;


for (int x = 0; x <= WIDTH; ++x)


{


y = x * dy/dx


FLOAT FX = x * w/width;


float FY = FX * DY/DX;


Mverts[index * 2 + 0] = FX + fx1;


Mverts[index * 2 + 1] = fy + fy1;


Index + 1;


}


}


}


else if (Minhaledir = = inhaledir.up)


{


for (int y = HEIGHT; y >= 0;--y)


{


Mfirstpathmeasure.getpostan (Y * first_h + firstpointdist, pos1, NULL);


Msecondpathmeasure.getpostan (Y * second_h + secondpointdist, pos2, NULL);


float w = pos2[0]-pos1[0];


Float fx1 = pos1[0];


float FX2 = pos2[0];


float fy1 = pos1[1];


float fy2 = pos2[1];


float dy = fy2-fy1;


float dx = fx2-fx1;


for (int x = 0; x <= WIDTH; ++x)


{


y = x * dy/dx


FLOAT FX = x * w/width;


float FY = FX * DY/DX;


Mverts[index * 2 + 0] = FX + fx1;


Mverts[index * 2 + 1] = fy + fy1;


Index + 1;


}


}


}


}


private void Buildmeshbypathonhorizontal (int timeindex)


{


Mfirstpathmeasure.setpath (Mfirstpath, false);


Msecondpathmeasure.setpath (Msecondpath, false);


int index = 0;


Float[] Pos1 = {0.0f, 0.0f};


Float[] Pos2 = {0.0f, 0.0f};


float Firstlen = Mfirstpathmeasure.getlength ();


float Secondlen = Msecondpathmeasure.getlength ();


float len1 = firstlen/width;


float len2 = secondlen/width;


float firstpointdist = Timeindex * LEN1;


float secondpointdist = Timeindex * LEN2;


float width = mbmpwidth;


Mfirstpathmeasure.getpostan (firstpointdist, POS1, NULL);


Mfirstpathmeasure.getpostan (firstpointdist + width, pos2, null);


float x1 = pos1[0];


float x2 = pos2[0];


float y1 = pos1[1];


float y2 = pos2[1];


float first_dist = (float) math.sqrt (x1-x2) * (X1-X2) + (y1-y2) * (Y1-y2));


float first_x = first_dist/width;


Msecondpathmeasure.getpostan (secondpointdist, POS1, NULL);


Msecondpathmeasure.getpostan (secondpointdist + width, pos2, null);


x1 = pos1[0];


x2 = pos2[0];


y1 = pos1[1];


y2 = pos2[1];


float second_dist = (float) math.sqrt (x1-x2) * (X1-X2) + (y1-y2) * (Y1-y2));


float second_x = second_dist/width;


if (Minhaledir = = inhaledir.right)


{


for (int x = 0; x <= WIDTH; ++x)


{


Mfirstpathmeasure.getpostan (x * first_x + firstpointdist, pos1, NULL);


Msecondpathmeasure.getpostan (x * second_x + secondpointdist, pos2, NULL);


Float h = pos2[1]-pos1[1];


Float fx1 = pos1[0];


float FX2 = pos2[0];


float fy1 = pos1[1];


float fy2 = pos2[1];


float dy = fy2-fy1;


float dx = fx2-fx1;


for (int y = 0; y <= HEIGHT; ++y)


{


x = y * dx/dy


float fy = y * h/height;


FLOAT FX = fy * DX/DY;


index = y * (WIDTH + 1) + x;


Mverts[index * 2 + 0] = FX + fx1;


Mverts[index * 2 + 1] = fy + fy1;


}


}


}


else if (Minhaledir = = Inhaledir.left)


{


for (int x = WIDTH; x >= 0;--x)


for (int x = 0; x <= WIDTH; ++x)


{


Mfirstpathmeasure.getpostan (x * first_x + firstpointdist, pos1, NULL);


Msecondpathmeasure.getpostan (x * second_x + secondpointdist, pos2, NULL);


Float h = pos2[1]-pos1[1];


Float fx1 = pos1[0];


float FX2 = pos2[0];


float fy1 = pos1[1];


float fy2 = pos2[1];


float dy = fy2-fy1;


float dx = fx2-fx1;


for (int y = 0; y <= HEIGHT; ++y)


{


x = y * dx/dy


float fy = y * h/height;


FLOAT FX = fy * DX/DY;


index = y * (WIDTH + 1) + width-x;


Mverts[index * 2 + 0] = FX + fx1;


Mverts[index * 2 + 1] = fy + fy1;


}


}


}


}


}





The realization of mesh class


Copy Code code as follows:



/*


* System:corelib


* @version 1.00


*


* Copyright (C), Lzt Corporation.


*


*/


Package Com.nj1s.lib.mesh;


Public abstract class Mesh


{


protected int WIDTH = 40;


protected int HEIGHT = 40;


protected int mbmpwidth =-1;


protected int mbmpheight =-1;


Protected final float[] mverts;


public Mesh (int width, int height)


{


width = width;


Height = height;


Mverts = new float[(WIDTH + 1) * (HEIGHT + 1) * 2];


}


Public float[] Getvertices ()


{


return mverts;


}


public int getwidth ()


{


return WIDTH;


}


public int getheight ()


{


return HEIGHT;


}


public static void SetXY (float[] array, int index, float x, float y)


{


array[index*2 + 0] = x;


Array[index*2 + 1] = y;


}


public void Setbitmapsize (int w, int h)


{


Mbmpwidth = W;


Mbmpheight = h;


}


public abstract void Buildpaths (float endx, float endY);


public abstract void buildmeshes (int index);


public void Buildmeshes (float W, float h)


{


int index = 0;


for (int y = 0; y <= HEIGHT; ++y)


{


float fy = y * h/height;


for (int x = 0; x <= WIDTH; ++x)


{


FLOAT FX = x * w/width;


SetXY (Mverts, index, FX, FY);


Index + 1;


}


}


}


}


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.