android繪製一個圓柱的螺線曲線

好吧,其實這個問題是因爲我想做一個小玩意的時候想要做一個效果需要用到螺線的一個效果,但是沒人分享過,可能太簡單了‘,

但是我是菜鳥,所以自己搞了兩天,寫了一個能實現的代碼,有點亂,不過有註釋,其實也挺簡單的

 

Activity_GL_Cylinder.java代碼

package wyf.lgz;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class Activity_GL_Cylinder extends Activity {
	private MyGLSurfaceView mGLSurfaceView;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        
        mGLSurfaceView = new MyGLSurfaceView(this);
        setContentView(mGLSurfaceView);
        mGLSurfaceView.setFocusableInTouchMode(true);//設置爲可觸控
        mGLSurfaceView.requestFocus();//獲取焦點
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        mGLSurfaceView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mGLSurfaceView.onPause();
    }   
}


 

 

DrawCylineder.java代碼

package wyf.lgz;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.lang.Math;

import javax.microedition.khronos.opengles.GL10;

public class DrawCylinder
{
	private FloatBuffer myVertexBuffer;//頂點座標緩衝 
	
	int vCount;//頂點數量
	
	float length;//圓柱長度   10f
	float circle_radius;//圓截環半徑   2f
	float degreespan;  //圓截環每一份的度數大小    20f
	int col;//圓柱塊數   5f
	
	public float mAngleX;
	public float mAngleY;
	public float mAngleZ;
	
	private float x1=0f;//直線上端點
	private float y1=0f;
	private float z1=0f;
	
	private float x4=0f;//直線下端點
	private float y4=0f;
	private float z4=0f;
	
	public DrawCylinder(float length,float circle_radius,float degreespan,int col)
	{
		this.circle_radius=circle_radius;
		this.length=length;
		this.col=col;
		this.degreespan=degreespan;
		
		float collength=2.0f;//圓柱每塊所佔的長度
		
		ArrayList<Float> val=new ArrayList<Float>();//頂點存放列表
		
//		for(float circle_degree=360.0f;circle_degree>0.0f;circle_degree-=degreespan)//循環行
//		{//控制點數
//			for(int j=0;j<col;j++)//循環列,控制塊數
//			{
//				x1 =(float)(j*collength-length/2);
//				y1=(float) (circle_radius*Math.sin(Math.toRadians(circle_degree)));
//				z1=(float) (circle_radius*Math.cos(Math.toRadians(circle_degree)));
//				
//				float x2 =(float)(j*collength-length/2);
//				float y2=(float) (circle_radius*Math.sin(Math.toRadians(circle_degree-degreespan)));
//				float z2=(float) (circle_radius*Math.cos(Math.toRadians(circle_degree-degreespan)));
//				
//				float x3 =(float)((j+1)*collength-length/2);
//				float y3=(float) (circle_radius*Math.sin(Math.toRadians(circle_degree-degreespan)));
//				float z3=(float) (circle_radius*Math.cos(Math.toRadians(circle_degree-degreespan)));
//				
//				x4 =(float)((j+1)*collength-length/2);
//				y4=(float) (circle_radius*Math.sin(Math.toRadians(circle_degree)));
//				z4=(float) (circle_radius*Math.cos(Math.toRadians(circle_degree)));
//
//				
////				val.add(x1);val.add(y1);val.add(z1);//每條線兩個頂點確定,有6條線,共12個頂點。
////				val.add(x2);val.add(y2);val.add(z2);//頂部圓圈
//				
////				val.add(x2);val.add(y2);val.add(z2);//斜曲線
////				val.add(x4);val.add(y4);val.add(z4);
//				
////				val.add(x4);val.add(y4);val.add(z4);//豎直的直線
////				val.add(x1);val.add(y1);val.add(z1);
////				
////				val.add(x2);val.add(y2);val.add(z2);//豎直的直線
////				val.add(x3);val.add(y3);val.add(z3);
//				
////				val.add(x3);val.add(y3);val.add(z3);//底部圓圈
////				val.add(x4);val.add(y4);val.add(z4);
//				
////				val.add(x4);val.add(y4);val.add(z4);//斜曲線
////				val.add(x2);val.add(y2);val.add(z2);
//			}
//		}
		
//		for (float circle_degree = 360.0f; circle_degree > 0.0f; circle_degree -= degreespan)// 循環行
//		{// 控制點數
			for (int j = 0; j < col; j++) {

				float circle_degree = 360.0f;
				x1 = (float) (j * collength - length / 2);
				y1 = (float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree)));
				z1 = (float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree)));
				
				float xm0 = (float) ((j + 0.0625) * collength - length / 2);
				float ym0 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree + 157.5f)));
				float zm0 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree + 157.5f)));
				
				float xm1 = (float) ((j + 0.125) * collength - length / 2);
				float ym1 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree + 135.0f)));
				float zm1 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree + 135.0f)));
				
				float xm2 = (float) ((j + 0.1875) * collength - length / 2);
				float ym2 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree + 112.5f)));
				float zm2 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree + 112.5f)));

				float xm3 = (float) ((j + 0.25) * collength - length / 2);
				float ym3 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree + 90.0f)));
				float zm3 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree + 90.0f)));
				
				float xm4 = (float) ((j + 0.3125) * collength - length / 2);
				float ym4 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree + 67.5f)));
				float zm4 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree + 67.5f)));
				
				float xm5 = (float) ((j + 0.375) * collength - length / 2);
				float ym5 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree + 45.0f)));
				float zm5 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree + 45.0f)));
				
				float xm6 = (float) ((j + 0.4375) * collength - length / 2);
				float ym6 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree + 22.5f)));
				float zm6 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree + 22.5f)));

				float xm7 = (float) ((j + 0.5) * collength - length / 2);
				float ym7 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree)));
				float zm7 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree)));
				
				float xm8 = (float) ((j + 0.5625) * collength - length / 2);
				float ym8 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree - 22.5f)));
				float zm8 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree - 22.5f)));
				
				float xm9 = (float) ((j + 0.625) * collength - length / 2);
				float ym9 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree - 45.0f)));
				float zm9 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree - 45.0f)));
				
				float xm10 = (float) ((j + 0.6875) * collength - length / 2);
				float ym10 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree-67.5)));
				float zm10 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree-67.5)));

				float xm11 = (float) ((j + 0.75) * collength - length / 2);
				float ym11 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree - 90.0f)));
				float zm11 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree - 90.0f)));
				
				float xm12 = (float) ((j + 0.8125) * collength - length / 2);
				float ym12 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree - 112.5f)));
				float zm12 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree - 112.5f)));
				
				float xm13 = (float) ((j + 0.875) * collength - length / 2);
				float ym13 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree - 135.0f)));
				float zm13 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree - 135.0f)));
				
				float xm14 = (float) ((j + 0.9375) * collength - length / 2);
				float ym14 = -(float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree - 157.5f)));
				float zm14 = -(float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree - 157.5f)));
				
				x4 = (float) ((j + 1) * collength - length / 2);
				y4 = (float) (circle_radius * Math.sin(Math
						.toRadians(circle_degree)));
				z4 = (float) (circle_radius * Math.cos(Math
						.toRadians(circle_degree)));
				
				float x2 = -1000f;
				float y2 = 0f;
				float z2 = 0f;
				
				float x3 = 1000f;
				float y3 = 0f;
				float z3 = 0f;
				
				val.add(x2);val.add(y2);val.add(z2);
				val.add(x3);val.add(y3);val.add(z3);

				val.add(x1);val.add(y1);val.add(z1);
				val.add(xm0);val.add(ym0);val.add(zm0);
				
				val.add(xm0);val.add(ym0);val.add(zm0);
				val.add(xm1);val.add(ym1);val.add(zm1);

				val.add(xm1);val.add(ym1);val.add(zm1);
				val.add(xm2);val.add(ym2);val.add(zm2);

				val.add(xm2);val.add(ym2);val.add(zm2);
				val.add(xm3);val.add(ym3);val.add(zm3);

				val.add(xm3);val.add(ym3);val.add(zm3);
				val.add(xm4);val.add(ym4);val.add(zm4);
				
				val.add(xm4);val.add(ym4);val.add(zm4);
				val.add(xm5);val.add(ym5);val.add(zm5);
				
				val.add(xm5);val.add(ym5);val.add(zm5);
				val.add(xm6);val.add(ym6);val.add(zm6);
				
				val.add(xm6);val.add(ym6);val.add(zm6);
				val.add(xm7);val.add(ym7);val.add(zm7);
				
				val.add(xm7);val.add(ym7);val.add(zm7);
				val.add(xm8);val.add(ym8);val.add(zm8);
				
				val.add(xm8);val.add(ym8);val.add(zm8);
				val.add(xm9);val.add(ym9);val.add(zm9);
				
				val.add(xm9);val.add(ym9);val.add(zm9);
				val.add(xm10);val.add(ym10);val.add(zm10);
				
				val.add(xm10);val.add(ym10);val.add(zm10);
				val.add(xm11);val.add(ym11);val.add(zm11);
				
				val.add(xm11);val.add(ym11);val.add(zm11);
				val.add(xm12);val.add(ym12);val.add(zm12);
				
				val.add(xm12);val.add(ym12);val.add(zm12);
				val.add(xm13);val.add(ym13);val.add(zm13);
				
				val.add(xm13);val.add(ym13);val.add(zm13);
				val.add(xm14);val.add(ym14);val.add(zm14);
				
				val.add(xm14);val.add(ym14);val.add(zm14);
				val.add(x4);val.add(y4);val.add(z4);
			}
//		}
		 
		vCount=val.size()/3;//確定頂點數量
		
		//頂點
		float[] vertexs=new float[vCount*3];
		for(int i=0;i<vCount*3;i++)
		{
			vertexs[i]=val.get(i);
		}
		ByteBuffer vbb=ByteBuffer.allocateDirect(vertexs.length*4);
		vbb.order(ByteOrder.nativeOrder());
		myVertexBuffer=vbb.asFloatBuffer();
		myVertexBuffer.put(vertexs);
		myVertexBuffer.position(0);
	}
	
	public void drawSelf(GL10 gl)
	{
		gl.glRotatef(mAngleX, 1, 0, 0);//旋轉
		gl.glRotatef(mAngleY, 0, 1, 0);
		gl.glRotatef(mAngleZ, 0, 0, 1);
		
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//打開頂點緩衝
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, myVertexBuffer);//指定頂點緩衝
		
		gl.glColor4f(0, 0, 0, 0);//設置繪製線爲黑色
		gl.glDrawArrays(GL10.GL_LINES, 0, vCount);//繪製圖像
		
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}
}


 

 

MyGlSurfaceView.java代碼

package wyf.lgz;

import java.io.IOException;
import java.io.InputStream;

import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.MotionEvent;

public class MyGLSurfaceView extends GLSurfaceView {
    private final float TOUCH_SCALE_FACTOR = 180.0f/320;//角度縮放比例
    private SceneRenderer mRenderer;//場景渲染器
    private float mPreviousY;//上次的觸控位置Y座標
    private float mPreviousX;//上次的觸控位置X座標
	
	public MyGLSurfaceView(Context context) {
        super(context);
        mRenderer = new SceneRenderer();	//創建場景渲染器
        setRenderer(mRenderer);				//設置渲染器		
        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//設置渲染模式爲主動渲染   
    }   
   
    //觸摸事件回調方法 
    @Override 
    public boolean onTouchEvent(MotionEvent e) {
        float y = e.getY();
        float x = e.getX();
        switch (e.getAction()) {
        case MotionEvent.ACTION_MOVE:
            float dy = y - mPreviousY;//計算觸控筆Y位移
            float dx = x - mPreviousX;//計算觸控筆X位移
            mRenderer.cylinder.mAngleX += dy * TOUCH_SCALE_FACTOR;//設置沿x軸旋轉角度
            mRenderer.cylinder.mAngleZ += dx * TOUCH_SCALE_FACTOR;//設置沿z軸旋轉角度
            requestRender();//重繪畫面
        }
        mPreviousY = y;//記錄觸控筆位置
        mPreviousX = x;//記錄觸控筆位置
        return true;
    }

	private class SceneRenderer implements GLSurfaceView.Renderer 
    {   
    	DrawCylinder cylinder;//創建圓柱體
    	
        public void onDrawFrame(GL10 gl) {                	
        	//清除顏色緩存
        	gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        	//設置當前矩陣爲模式矩陣
            gl.glMatrixMode(GL10.GL_MODELVIEW);
            //設置當前矩陣爲單位矩陣
            gl.glLoadIdentity();     
                  
            gl.glPushMatrix();//保護變換矩陣現場     
            gl.glTranslatef(0, 0, -8f);//平移
            cylinder.drawSelf(gl);//繪製 
            gl.glPopMatrix();//恢復變換矩陣現場
        }

        public void onSurfaceChanged(GL10 gl, int width, int height) {
            //設置視窗大小及位置 
        	gl.glViewport(0, 0, width, height);
        	//設置當前矩陣爲投影矩陣
            gl.glMatrixMode(GL10.GL_PROJECTION);
            //設置當前矩陣爲單位矩陣
            gl.glLoadIdentity();
            //計算透視投影的比例
            float ratio = (float) width / height;
            //調用此方法計算產生透視投影矩陣
            gl.glFrustumf(-ratio, ratio, -1, 1, 1, 100);
        }

        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            //關閉抗抖動 
        	gl.glDisable(GL10.GL_DITHER);
        	//設置特定Hint項目的模式,這裏爲設置爲使用快速模式
            gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
            //設置屏幕背景色白色RGBA
            gl.glClearColor(1,1,1,1);
            //設置着色模型爲平滑着色   
            gl.glShadeModel(GL10.GL_SMOOTH);
            //啓用深度測試
            gl.glEnable(GL10.GL_DEPTH_TEST);
          
            cylinder=new DrawCylinder(10f,2f,20f,10);//創建圓柱體
            
//            //開啓一個線程自動旋轉物體
//            new Thread()
//            {
//          	  public void run()
//          	  {
//          		  while(true)
//          		  {
//          			mRenderer.cylinder.mAngleY+=2*TOUCH_SCALE_FACTOR;//球沿Y軸轉動
//                    requestRender();//重繪畫面
//                    try
//                    {
//                  	  Thread.sleep(50);//休息10ms再重繪
//                    }
//                    catch(Exception e)
//                    {
//                  	  e.printStackTrace();
//                    }        			  
//          		  }
//          	  }
//            }.start();
        }
    }
}


 

 

 

該代碼原是一個圓柱體的,後來我在其座標基礎上改動而來。其他沒有改動,後期我想改

 

成觸摸向上滑動自動生成螺線的效果,有想法的朋友請留言。。。我會盡快回復

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章