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();
        }
    }
}


 

 

 

该代码原是一个圆柱体的,后来我在其座标基础上改动而来。其他没有改动,后期我想改

 

成触摸向上滑动自动生成螺线的效果,有想法的朋友请留言。。。我会尽快回复

 

 

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