Today, I accidentally saw a menu in the disc shape, and it was quite interesting to turn it. Then I thought about it and made a simple effect.
The idea is this: Set an origin and a radius, and evenly distribute each menu around the circle. For easy calculation, the coordinates of the menu are expressed in degrees and then converted to polar coordinates.
Set a vertex as the starting point, and determine the degree of increase for each vertex based on the total number of menus. Then, determine the degree of each vertex in sequence, and then determine the coordinates.
Java code
- Package chroya. Demo. roundspin;
- Import Android. content. context;
- Import Android. Graphics. Bitmap;
- Import Android. Graphics. bitmapfactory;
- Import Android. Graphics. Canvas;
- Import Android. Graphics. color;
- Import Android. Graphics. paint;
- Import Android. util. log;
- Import Android. View. motionevent;
- Import Android. View. view;
- /**
- * Disc View
- * @ Author chroya
- *
- */
- Public class roundspinview
Extends view {
- Private paint mpaint = new paint ();
- // Stone list
- Private bigstone [] mstones;
- // Number
- Private Static
Final int stone_count =
6;
- // Center Coordinate
- Private int mpointx = 0, mpointy = 0;
- // Radius
- Private int mradius =
0;
- // Angle of interval between two points
- Private int mdegreedelta;
- Public roundspinview (context,
Int PX, int py,
Int radius ){
- Super (context );
- Mpaint. setcolor (color. Red );
- Mpaint. setstrokewidth (2 );
- Setbackgroundresource (R. drawable. menubkground );
- Mpointx = px;
- Mpointy = py;
- Mradius = radius;
- Setupstones ();
- Computecoordinates ();
- }
- /**
- * Initialize each vertex
- */
- Private void setupstones (){
- Mstones = new bigstone [stone_count];
- Bigstone stone;
- Int angle = 0;
- Mdegreedelta = 360/stone_count;
- For (INT Index = 0; index <stone_count; index ++ ){
- Stone = new bigstone ();
- Stone. angle = angle;
- Stone. Bitmap = bitmapfactory. decoderesource (getresources (), R. drawable. menu1 + index );
- Angle + = mdegreedelta;
- Mstones [Index] = stone;
- }
- }
- /**
- * Re-calculate the angle of each vertex
- */
- Private void resetstonesangle (float X,
Float y ){
- Int angle = computecurrentangle (x, y );
- Log. D ("roundspinview ",
"Angle:" + angle );
- For (INT Index = 0; index <stone_count; index ++ ){
- Mstones [Index]. angle = angle;
- Angle + = mdegreedelta;
- }
- }
- /**
- * Calculate the coordinates of each vertex.
- */
- Private void computecoordinates (){
- Bigstone stone;
- For (INT Index = 0; index <stone_count; index ++ ){
- Stone = mstones [Index];
- Stone. x = mpointx + (float) (mradius * Math. Cos (stone. Angle * Math. PI/180 ));
- Stone. Y = mpointy + (float) (mradius * Math. Sin (stone. Angle * Math. PI/180 ));
- }
- }
- /**
- * Calculate the angle of the first vertex.
- * @ Param x
- * @ Param y
- * @ Return
- */
- Private int computecurrentangle (float X,
Float y ){
- Float distance = (float) math. SQRT (X-mpointx) * (X-mpointx) + (Y-mpointy) * (Y-mpointy )));
- Int degree = (INT) (math. ACOs (X-mpointx)/distance) * 180/Math. Pi );
- If (Y <mpointy ){
- Degree =-degree;
- }
- Log. D ("roundspinview ",
"X:" + x + ", Y:" + Y + ", Degree:" + degree );
- Return degree;
- }
- @ Override
- Public Boolean dispatchtouchevent (motionevent event ){
- Resetstonesangle (event. getx (), event. Gety ());
- Computecoordinates ();
- Invalidate ();
- Return true;
- }
- @ Override
- Public void ondraw (canvas ){
- Canvas. drawpoint (mpointx, mpointy, mpaint );
- For (INT Index = 0; index <stone_count; index ++ ){
- If (! Mstones [Index]. isvisible)
Continue;
- Drawincenter (canvas, mstones [Index]. bitmap, mstones [Index]. X, mstones [Index]. y );
- // Skip the following sentence if you do not want a red line
- // Canvas. drawline (mpointx, mpointy, mstones [Index]. X, mstones [Index]. Y, mpaint );
- }
- }
- /**
- * Place the center point in the center
- * @ Param canvas
- * @ Param bitmap
- * @ Param left
- * @ Param top
- */
- Void drawincenter (canvas, Bitmap bitmap,
Float left, float top ){
- Canvas. drawpoint (left, top, mpaint );
- Canvas. drawbitmap (bitmap, left-bitmap.getWidth ()/2, top-bitmap.getHeight ()/2,
Null );
- }
- Class bigstone {
- // Image
- Bitmap bitmap;
- // Angle
- Int angle;
- // X coordinate
- Float X;
- // Y coordinate
- Float y;
- // Visible
- Boolean isvisible = true;
- }
- }
Package chroya. demo. roundspin; import android. content. context; import android. graphics. bitmap; import android. graphics. bitmapfactory; import android. graphics. canvas; import android. graphics. color; import android. graphics. paint; import android. util. log; import android. view. motionevent; import android. view. view;/*** disc view * @ author chroya **/public class roundspinview extends view {private paint mpaint = New paint (); // stone list private bigstone [] mstones; // Number of Private Static final int stone_count = 6; // center coordinate private int mpointx = 0, mpointy = 0; // radius private int mradius = 0; // The angle between each two points Private int mdegreedelta; Public roundspinview (context, int PX, int py, int radius) {super (context); mpaint. setcolor (color. red); mpaint. setstrokewidth (2); setbackgroundresource (R. drawable. menubkground); mpointx = px; mpointy = PY; mradius = radius; setupstones (); computecoordinates ();}/*** initialize each vertex */private void setupstones () {mstones = new bigstone [stone_count]; bigstone stone; int angle = 0; mdegreedelta = 360/stone_count; For (INT Index = 0; index <stone_count; index ++) {stone = new bigstone (); stone. angle = angle; stone. bitmap = bitmapfactory. decoderesource (getresources (), R. drawable. menu1 + index); angle + = mdegreedelta; mstones [I Ndex] = stone ;}}/*** recalculate the angle of each vertex */private void resetstonesangle (float X, float y) {int angle = computecurrentangle (x, y ); log. D ("roundspinview", "angle:" + angle); For (INT Index = 0; index <stone_count; index ++) {mstones [Index]. angle = angle; angle + = mdegreedelta;}/*** calculate the coordinates of each vertex */private void computecoordinates () {bigstone stone; For (INT Index = 0; index <stone_count; index ++) {stone = mstones [Index]; ston E. X = mpointx + (float) (mradius * Math. cos (stone. angle * Math. PI/180); stone. y = mpointy + (float) (mradius * Math. sin (stone. angle * Math. PI/180);}/*** calculate the angle of the first vertex * @ Param x * @ Param y * @ return */private int computecurrentangle (float X, float y) {float distance = (float) math. SQRT (X-mpointx) * (X-mpointx) + (Y-mpointy) * (Y-mpointy); int degree = (INT) (math. ACOs (X-mpointx)/distance) * 180/math. pi); If (Y <Mpointy) {degree =-degree;} log. D ("roundspinview", "X:" + x + ", Y:" + Y + ", Degree:" + degree); Return degree ;} @ overridepublic Boolean dispatchtouchevent (motionevent event) {resetstonesangle (event. getx (), event. gety (); computecoordinates (); invalidate (); Return true ;}@ overridepublic void ondraw (canvas) {canvas. drawpoint (mpointx, mpointy, mpaint); For (INT Index = 0; index <stone_count; index ++) {If (! Mstones [Index]. isvisible) continue; drawincenter (canvas, mstones [Index]. bitmap, mstones [Index]. x, mstones [Index]. y); // if you do not want to have a red line, delete the following sentence: // canvas. drawline (mpointx, mpointy, mstones [Index]. x, mstones [Index]. y, mpaint) ;}}/*** place the central point to the center * @ Param canvas * @ Param bitmap * @ Param left * @ Param top */void drawincenter (canvas, bitmap bitmap, float left, float top) {canvas. drawpoint (left, top, mpaint); canvas. drawbitmap (bitmap, left-bitmap.getWidth ()/2, top-bitmap.getHeight ()/2, null);} class bigstone {// picture Bitmap bitmap; // angle int angle; // X coordinate float X; // y coordinate float y; // Boolean isvisible = true ;}}
The comments in the Code are also clear. Stone_count indicates the number of menus, which can be set to 1 to 7. A larger number must be supported by images. I only put seven images.
If the touch point is not on the circumference, the intersection of the straight line from the point to the center of the circle is automatically calculated and mapped.
The following figure shows the effect of the five menus:
Effects of the six menus:
OK, and the code is also contributed.
Zhuanzi: http://chroya.iteye.com/blog/830682