博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
几何球
阅读量:5282 次
发布时间:2019-06-14

本文共 9009 字,大约阅读时间需要 30 分钟。

效果图如下:

1、首先给出的是用于初始化几何球顶点坐标数据的initvertexData方法:

      //自定义的初始化顶点数据的方法    public void initVertexData(float scale, float aHalf, int n) //大小,黄金长方形长边的一半,分段数	{		aHalf*=scale;		//长边的一半		bHalf=aHalf*0.618034f;		//短边的一半		r=(float) Math.sqrt(aHalf*aHalf+bHalf*bHalf);		vCount=3*20*n*n;//顶点个数,共有20个三角形,每个三角形都有三个顶点		//正20面体坐标数据初始化		ArrayList
alVertix20=new ArrayList
();//正20面体的顶点列表(未卷绕) ArrayList
alFaceIndex20=new ArrayList
();//正20面体组织成面的顶点的索引值列表(按逆时针卷绕) //正20面体顶点 initAlVertix20(alVertix20,aHalf,bHalf); //正20面体索引 initAlFaceIndex20(alFaceIndex20); //计算卷绕顶点 float[] vertices20=VectorUtil.cullVertex(alVertix20, alFaceIndex20);//只计算顶点 //坐标数据初始化 ArrayList
alVertix=new ArrayList
();//原顶点列表(未卷绕) ArrayList
alFaceIndex=new ArrayList
();//组织成面的顶点的索引值列表(按逆时针卷绕) int vnCount=0;//前i-1行前所有顶点数的和 for(int k=0;k
alST20=new ArrayList
();//正20面体的纹理坐标列表(未卷绕) ArrayList
alTexIndex20=new ArrayList
();//正20面体组织成面的纹理坐标的索引值列表(按逆时针卷绕) //正20面体纹理坐标 float sSpan=1/5.5f;//每个纹理三角形的边长 float tSpan=1/3.0f;//每个纹理三角形的高 //按正二十面体的平面展开图计算纹理坐标 for(int i=0;i<5;i++){ alST20.add(sSpan+sSpan*i); alST20.add(0f); } for(int i=0;i<6;i++){ alST20.add(sSpan/2+sSpan*i); alST20.add(tSpan); } for(int i=0;i<6;i++){ alST20.add(sSpan*i); alST20.add(tSpan*2); } for(int i=0;i<5;i++){ alST20.add(sSpan/2+sSpan*i); alST20.add(tSpan*3); } //正20面体索引 initAlTexIndex20(alTexIndex20); //计算卷绕纹理坐标 float[] st20=VectorUtil.cullTexCoor(alST20, alTexIndex20);//只计算纹理坐标 ArrayList
alST=new ArrayList
();//原纹理坐标列表(未卷绕) for(int k=0;k
 2、接着给出的是初始化正二十面体顶点坐标数据的initAI20方法: 

public void initAlVertix20(ArrayList
alVertix20,float aHalf,float bHalf){ alVertix20.add(0f); alVertix20.add(aHalf); alVertix20.add(-bHalf);//顶正棱锥顶点 alVertix20.add(0f); alVertix20.add(aHalf); alVertix20.add(bHalf);//棱柱上的点 alVertix20.add(aHalf); alVertix20.add(bHalf); alVertix20.add(0f); alVertix20.add(bHalf); alVertix20.add(0f); alVertix20.add(-aHalf); alVertix20.add(-bHalf); alVertix20.add(0f); alVertix20.add(-aHalf); alVertix20.add(-aHalf); alVertix20.add(bHalf); alVertix20.add(0f); alVertix20.add(-bHalf); alVertix20.add(0f); alVertix20.add(aHalf); alVertix20.add(bHalf); alVertix20.add(0f); alVertix20.add(aHalf); alVertix20.add(aHalf); alVertix20.add(-bHalf); alVertix20.add(0f); alVertix20.add(0f); alVertix20.add(-aHalf); alVertix20.add(-bHalf); alVertix20.add(-aHalf); alVertix20.add(-bHalf); alVertix20.add(0f); alVertix20.add(0f); alVertix20.add(-aHalf); alVertix20.add(bHalf);//底棱锥顶点 }
3、初始化构成正二十面体的20个三角形顶点坐标编号数据的initAIfaceIndex20的方法:

public void initAlFaceIndex20(ArrayList
alFaceIndex20){ //初始化正二十面体的顶点索引数据 alFaceIndex20.add(0); alFaceIndex20.add(1); alFaceIndex20.add(2); alFaceIndex20.add(0); alFaceIndex20.add(2); alFaceIndex20.add(3); alFaceIndex20.add(0); alFaceIndex20.add(3); alFaceIndex20.add(4); alFaceIndex20.add(0); alFaceIndex20.add(4); alFaceIndex20.add(5); alFaceIndex20.add(0); alFaceIndex20.add(5); alFaceIndex20.add(1); alFaceIndex20.add(1); alFaceIndex20.add(6); alFaceIndex20.add(7); alFaceIndex20.add(1); alFaceIndex20.add(7); alFaceIndex20.add(2); alFaceIndex20.add(2); alFaceIndex20.add(7); alFaceIndex20.add(8); alFaceIndex20.add(2); alFaceIndex20.add(8); alFaceIndex20.add(3); alFaceIndex20.add(3); alFaceIndex20.add(8); alFaceIndex20.add(9); alFaceIndex20.add(3); alFaceIndex20.add(9); alFaceIndex20.add(4); alFaceIndex20.add(4); alFaceIndex20.add(9); alFaceIndex20.add(10); alFaceIndex20.add(4); alFaceIndex20.add(10); alFaceIndex20.add(5); alFaceIndex20.add(5); alFaceIndex20.add(10); alFaceIndex20.add(6); alFaceIndex20.add(5); alFaceIndex20.add(6); alFaceIndex20.add(1); alFaceIndex20.add(6); alFaceIndex20.add(11); alFaceIndex20.add(7); alFaceIndex20.add(7); alFaceIndex20.add(11); alFaceIndex20.add(8); alFaceIndex20.add(8); alFaceIndex20.add(11); alFaceIndex20.add(9); alFaceIndex20.add(9); alFaceIndex20.add(11); alFaceIndex20.add(10); alFaceIndex20.add(10); alFaceIndex20.add(11); alFaceIndex20.add(6); }
4、初始化构成正二十面体的20个三角形各个顶点坐标编号数据的initAIfaceIndex20的方法:

public void initAlTexIndex20(ArrayList
alTexIndex20) //初始化顶点纹理索引数据 { alTexIndex20.add(0); alTexIndex20.add(5); alTexIndex20.add(6); alTexIndex20.add(1); alTexIndex20.add(6); alTexIndex20.add(7); alTexIndex20.add(2); alTexIndex20.add(7); alTexIndex20.add(8); alTexIndex20.add(3); alTexIndex20.add(8); alTexIndex20.add(9); alTexIndex20.add(4); alTexIndex20.add(9); alTexIndex20.add(10); alTexIndex20.add(5); alTexIndex20.add(11); alTexIndex20.add(12); alTexIndex20.add(5); alTexIndex20.add(12); alTexIndex20.add(6); alTexIndex20.add(6); alTexIndex20.add(12); alTexIndex20.add(13); alTexIndex20.add(6); alTexIndex20.add(13); alTexIndex20.add(7); alTexIndex20.add(7); alTexIndex20.add(13); alTexIndex20.add(14); alTexIndex20.add(7); alTexIndex20.add(14); alTexIndex20.add(8); alTexIndex20.add(8); alTexIndex20.add(14); alTexIndex20.add(15); alTexIndex20.add(8); alTexIndex20.add(15); alTexIndex20.add(9); alTexIndex20.add(9); alTexIndex20.add(15); alTexIndex20.add(16); alTexIndex20.add(9); alTexIndex20.add(16); alTexIndex20.add(10); alTexIndex20.add(11); alTexIndex20.add(17); alTexIndex20.add(12); alTexIndex20.add(12); alTexIndex20.add(18); alTexIndex20.add(13); alTexIndex20.add(13); alTexIndex20.add(19); alTexIndex20.add(14); alTexIndex20.add(14); alTexIndex20.add(20); alTexIndex20.add(15); alTexIndex20.add(15); alTexIndex20.add(21); alTexIndex20.add(16); }
5、最后给出的是向量计算及圆弧拆分相关方法所属的工具类——VectorUtil:

import java.util.ArrayList;//计算三角形法向量的工具类public class VectorUtil {	//向量规格化的方法	public static float[] normalizeVector(float [] vec){		float mod=module(vec);		return new float[]{vec[0]/mod, vec[1]/mod, vec[2]/mod};//返回规格化后的向量	}	//求向量的模的方法	public static float module(float [] vec){		return (float) Math.sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);	}	//两个向量叉乘的方法	public static float[] crossTwoVectors(float[] a, float[] b)	{		float x=a[1]*b[2]-a[2]*b[1];		float y=a[2]*b[0]-a[0]*b[2];		float z=a[0]*b[1]-a[1]*b[0];		return new float[]{x, y, z};//返回叉乘结果	}	//两个向量点乘的方法	public static float dotTwoVectors(float[] a, float[] b)	{		return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];//返回点乘结果	}	//根据原纹理坐标和索引,计算卷绕后的纹理的方法	public static float[] cullTexCoor(			ArrayList
alST,//原纹理坐标列表(未卷绕) ArrayList
alTexIndex//组织成面的纹理坐标的索引值列表(按逆时针卷绕) ) { float[] textures=new float[alTexIndex.size()*2]; //生成顶点的数组 int stCount=0; for(int i:alTexIndex){ textures[stCount++]=alST.get(2*i); textures[stCount++]=alST.get(2*i+1); } return textures; } public static float[] cullVertex( ArrayList
alv,//原顶点列表(未卷绕) ArrayList
alFaceIndex//组织成面的顶点的索引值列表(按逆时针卷绕) ) { float[] vertices=new float[alFaceIndex.size()*3]; //生成顶点的数组 int vCount=0; for(int i:alFaceIndex){ vertices[vCount++]=alv.get(3*i); vertices[vCount++]=alv.get(3*i+1); vertices[vCount++]=alv.get(3*i+2); } return vertices; } //计算圆弧的n等分点坐标的方法 public static float[] devideBall( float r, //球的半径 float[] start, //指向圆弧起点的向量 float[] end, //指向圆弧终点的向量 int n, //圆弧分的份数 int i //求第i份在圆弧上的坐标(i为0和n时分别代表起点和终点坐标) ) { /* * 先求出所求向量的规格化向量,再乘以半径r即可 * s0*x+s1*y+s2*z=cos(angle1)//根据所求向量和起点向量夹角为angle1---1式 * e0*x+e1*y+e2*z=cos(angle2)//根据所求向量和终点向量夹角为angle2---2式 * x*x+y*y+z*z=1//所球向量的规格化向量模为1---3式 * x*n0+y*n1+z*n2=0//所球向量与法向量垂直---4式 * 算法为:将1、2两式用换元法得出x=a1+b1*z,y=a2+b2*z的形式, * 将其代入4式求出z,再求出x、y,最后将向量(x,y,z)乘以r即为所求坐标。 * 1式和2式是将3式代入得到的,因此已经用上了。 * 由于叉乘的结果做了分母,因此起点、终点、球心三点不能共线 * 注意结果是将劣弧等分 */ //先将指向起点和终点的向量规格化 float[] s=VectorUtil.normalizeVector(start); float[] e=VectorUtil.normalizeVector(end); if(n==0){//如果n为零,返回起点坐标 return new float[]{s[0]*r, s[1]*r, s[2]*r}; } //求两个向量的夹角 double angrad=Math.acos(VectorUtil.dotTwoVectors(s, e));//起点终点向量夹角 double angrad1=angrad*i/n;//所球向量和起点向量的夹角 double angrad2=angrad-angrad1;//所球向量和终点向量的夹角 //求法向量normal float[] normal=VectorUtil.crossTwoVectors(s, e); //用doolittle分解算法解n元一次线性方程组 double matrix[][]={//增广矩阵 {s[0],s[1],s[2],Math.cos(angrad1)}, {e[0],e[1],e[2],Math.cos(angrad2)}, {normal[0],normal[1],normal[2],0} }; double result[]=MyMathUtil.doolittle(matrix);//解 //求规格化向量xyz的值 float x=(float) result[0]; float y=(float) result[1]; float z=(float) result[2]; //返回圆弧的n等分点坐标 return new float[]{x*r, y*r, z*r}; } //计算线段的n等分点坐标的方法 public static float[] devideLine( float[] start, //线段起点坐标 float[] end, //线段终点坐标 int n, //线段分的份数 int i //求第i份在线段上的坐标(i为0和n时分别代表起点和终点坐标) ) { if(n==0){//如果n为零,返回起点坐标 return start; } //求起点到终点的向量 float[] ab=new float[]{end[0]-start[0], end[1]-start[1], end[2]-start[2]}; //求向量比例 float vecRatio=i/(float)n; //求起点到所求点的向量 float[] ac=new float[]{ab[0]*vecRatio, ab[1]*vecRatio, ab[2]*vecRatio}; //所求坐标 float x=start[0]+ac[0]; float y=start[1]+ac[1]; float z=start[2]+ac[2]; //返回线段的n等分点坐标 return new float[]{x, y, z}; }}

转载于:https://www.cnblogs.com/Anzhongliu/p/6092110.html

你可能感兴趣的文章
JavaScript高级程序设计26.pdf
查看>>
jquery 对 table 的操作
查看>>
centos7 关闭防火墙
查看>>
Android 拍照图片选取与图片剪裁
查看>>
百度地图轨迹回放,自定义路书,边走边画线
查看>>
数字操作类
查看>>
NVME SSD vs SATA SSD(转)
查看>>
搜索实时个性化模型——基于FTRL和个性化推荐的搜索排序优化
查看>>
漫画解读“跨视图粒度计算”,了解有数分析利器
查看>>
【c++ primer读书笔记】【第3章】字符串、向量和数组
查看>>
ATL CAxWindow类创建问题一则
查看>>
【Android Developers Training】 31. 序言:共享简单数据
查看>>
【BZOJ】【2693】JZPTAB
查看>>
第八篇:ORM框架SQLAlchemy 了解知识
查看>>
JavaWeb学习笔记——过滤器
查看>>
Spring MVC学习笔记——完整的用户登录
查看>>
Spark学习笔记——安装和WordCount
查看>>
简单的弹出拖拽窗口(一)
查看>>
100.Same Tree(Swift待解)
查看>>
数据结构与算法之图
查看>>