# 在unity向量空间内绘制几何(2)：球面---重构《黑客帝国》的‘上帝机器’，Deus Ex Machina

x=rsinθcosϕ$x=r*\sin\theta*\cos\phi$
y=rsinθsinϕ$y=r*\sin\theta*\sin\phi$
y=rcosθ$y=r*\cos\theta$
(公式-1)

    public Vector3[] GenerateSSphereVectro3(int radius,Vector3 centre,int thetaPortion,int phiPortion){

Vector3[] coordinates=new Vector3[thetaPortion*phiPortion];

float thetaMultiplier=360f/(float)thetaPortion;
float phiMultiplier=360f/(float)phiPortion;

for(int i=0,index=0;i<thetaPortion;i++){
for(int j=0;j<phiPortion;j++){
index+=1;
}
}

return coordinates;
}

Vector3 centre:球体圆心。
int thetaPortion:将θ$\theta$角平均分成的份数。
int phiPortion:将ϕ$\phi$角平均分成的份数。

Vector3 coordinates:一组分布在球面的三维坐标向量。数量为thetaPortion*phiPortion个。

1，根据传进的thetaPortion与phiPortion参数声明一组三维坐标数组

Vector3[] coordinates=new Vector3[thetaPortion*phiPortion];

2,根据传进的thetaPortion与phiPortion参数计算坐标点在极坐标公式中相差的角度。

float thetaMultiplier=360f/(float)thetaPortion;
float phiMultiplier=360f/(float)phiPortion;

3，通过两个for循环，依次寻找球面上的每个坐标点。

for(int i=0,index=0;i<thetaPortion;i++){
for(int j=0;j<phiPortion;j++){
index+=1;
}
}

Unity自带的几何模型中没有圆锥体。以下是生成圆锥体的代码，并非我原创，源码地址http://wiki.unity3d.com/index.php?title=CreateCone，作者Wolfram Kresse。将此脚本放在/Assets/Editor 文件夹下。然后上方菜单的GameObject/CreatOther里会出现cone。

using UnityEngine;
using UnityEditor;
using System.Collections;

// an Editor method to create a cone primitive (so far no end caps)
// the top center is placed at (0/0/0)
// the bottom center is placed at (0/0/length)
// if either one of the radii is 0, the result will be a cone, otherwise a truncated cone
// note you will get inevitable breaks in the smooth shading at cone tips
// note the resulting mesh will be created as an asset in Assets/Editor
// Author: Wolfram Kresse
public class CreateCone : ScriptableWizard {

public int numVertices = 10;
public float length = 1f;
public float openingAngle = 0f; // if >0, create a cone with this angle by setting radiusTop to 0, and adjust radiusBottom according to length;
public bool outside = true;
public bool inside = false;

static void CreateWizard()
{
ScriptableWizard.DisplayWizard("Create Cone", typeof(CreateCone));
}

void OnWizardCreate(){
GameObject newCone=new GameObject("Cone");
if(openingAngle>0&&openingAngle<180){
}
string meshName = newCone.name + numVertices + "v" + radiusTop + "t" + radiusBottom + "b" + length + "l" + length + (outside?"o":"") + (inside?"i":"");
string meshPrefabPath = "Assets/Editor/" + meshName + ".asset";
if(mesh==null){
mesh=new Mesh();
mesh.name=meshName;
// can't access Camera.current
//newCone.transform.position = Camera.current.transform.position + Camera.current.transform.forward * 5.0f;
int multiplier=(outside?1:0)+(inside?1:0);
int offset=(outside&&inside?2*numVertices:0);
Vector3[] vertices=new Vector3[2*multiplier*numVertices]; // 0..n-1: top, n..2n-1: bottom
Vector3[] normals=new Vector3[2*multiplier*numVertices];
Vector2[] uvs=new Vector2[2*multiplier*numVertices];
int[] tris;
float slopeSin=Mathf.Sin(slope);
float slopeCos=Mathf.Cos(slope);
int i;

for(i=0;i<numVertices;i++){
float angle=2*Mathf.PI*i/numVertices;
float angleSin=Mathf.Sin(angle);
float angleCos=Mathf.Cos(angle);
float angleHalf=2*Mathf.PI*(i+0.5f)/numVertices; // for degenerated normals at cone tips
float angleHalfSin=Mathf.Sin(angleHalf);
float angleHalfCos=Mathf.Cos(angleHalf);

normals[i]=new Vector3(angleHalfCos*slopeCos,angleHalfSin*slopeCos,-slopeSin);
else
normals[i]=new Vector3(angleCos*slopeCos,angleSin*slopeCos,-slopeSin);
normals[i+numVertices]=new Vector3(angleHalfCos*slopeCos,angleHalfSin*slopeCos,-slopeSin);
else
normals[i+numVertices]=new Vector3(angleCos*slopeCos,angleSin*slopeCos,-slopeSin);

uvs[i]=new Vector2(1.0f*i/numVertices,1);
uvs[i+numVertices]=new Vector2(1.0f*i/numVertices,0);

if(outside&&inside){
// vertices and uvs are identical on inside and outside, so just copy
vertices[i+2*numVertices]=vertices[i];
vertices[i+3*numVertices]=vertices[i+numVertices];
uvs[i+2*numVertices]=uvs[i];
uvs[i+3*numVertices]=uvs[i+numVertices];
}
if(inside){
// invert normals
normals[i+offset]=-normals[i];
normals[i+numVertices+offset]=-normals[i+numVertices];
}
}
mesh.vertices = vertices;
mesh.normals = normals;
mesh.uv = uvs;

// create triangles
// here we need to take care of point order, depending on inside and outside
int cnt=0;
// top cone
tris=new int[numVertices*3*multiplier];
if(outside)
for(i=0;i<numVertices;i++){
tris[cnt++]=i+numVertices;
tris[cnt++]=i;
if(i==numVertices-1)
tris[cnt++]=numVertices;
else
tris[cnt++]=i+1+numVertices;
}
if(inside)
for(i=offset;i<numVertices+offset;i++){
tris[cnt++]=i;
tris[cnt++]=i+numVertices;
if(i==numVertices-1+offset)
tris[cnt++]=numVertices+offset;
else
tris[cnt++]=i+1+numVertices;
}
// bottom cone
tris=new int[numVertices*3*multiplier];
if(outside)
for(i=0;i<numVertices;i++){
tris[cnt++]=i;
if(i==numVertices-1)
tris[cnt++]=0;
else
tris[cnt++]=i+1;
tris[cnt++]=i+numVertices;
}
if(inside)
for(i=offset;i<numVertices+offset;i++){
if(i==numVertices-1+offset)
tris[cnt++]=offset;
else
tris[cnt++]=i+1;
tris[cnt++]=i;
tris[cnt++]=i+numVertices;
}
}else{
// truncated cone
tris=new int[numVertices*6*multiplier];
if(outside)
for(i=0;i<numVertices;i++){
int ip1=i+1;
if(ip1==numVertices)
ip1=0;

tris[cnt++]=i;
tris[cnt++]=ip1;
tris[cnt++]=i+numVertices;

tris[cnt++]=ip1+numVertices;
tris[cnt++]=i+numVertices;
tris[cnt++]=ip1;
}
if(inside)
for(i=offset;i<numVertices+offset;i++){
int ip1=i+1;
if(ip1==numVertices+offset)
ip1=offset;

tris[cnt++]=ip1;
tris[cnt++]=i;
tris[cnt++]=i+numVertices;

tris[cnt++]=i+numVertices;
tris[cnt++]=ip1+numVertices;
tris[cnt++]=ip1;
}
}
mesh.triangles = tris;
AssetDatabase.CreateAsset(mesh, meshPrefabPath);
AssetDatabase.SaveAssets();
}

mf.mesh = mesh;

mc.sharedMesh=mf.sharedMesh;
}

Selection.activeObject = newCone;
}
}

        if(rotateFlag){
for(int i=0;i<thetaPortion;){
parents[i].transform.Rotate(Vector3.forward,rotateSpeed);
i+=2;
}
for(int i=1;i<thetaPortion;){
parents[i].transform.Rotate(Vector3.back,rotateSpeed);
i+=2;
}
}

    IEnumerator lightingMove(){
for(int i=0;i<100;i++){
for(int j=0;j<21;j++){
lightingEmitters[j].transform.position=Ball[Random.Range(0,1296)];
yield return new WaitForSeconds(0.2f);
}
}
}

    private Vector3[] circlePoints=new Vector3[200];
// Use this for initialization
void Start () {
for(int i=0;i<200;i++){
circlePoints=Circle(200,18,new Vector3(0f,5f,0f));
}
transform.position=circlePoints[0];
transform.DOPath(circlePoints,130f);
}

// Update is called once per frame
void Update () {
transform.LookAt(Vector3.zero);
}

• 本文已收录于以下专栏：

## Unity之Handles绘制圆锥体立方体圆柱体五

Unity编辑器类在Scene下绘制圆锥体，立方体，球体 在Editor文件夹下创建脚本HandlerTest using UnityEngine; using System.C...
• LIQIANGEASTSUN
• 2014年12月26日 18:47
• 2594

## [unity]在unity中创建圆锥体

• u013508264
• 2016年05月16日 16:06
• 1971

## 【OpenGL】详解第一个OpenGL程序

OpenGL能做的事情太多了！很多程序也看起来很复杂。但是！所有O
• candycat1992
• 2014年11月26日 16:00
• 60024

## Unity Vector3.Slerp() 球形插值详解

• ZFSR05255134
• 2015年10月13日 20:48
• 2328

## Unity Mesh(三) Mesh画球

• HeBiReChenAi
• 2017年01月23日 17:44
• 5787

## 在unity向量空间内绘制几何(2)：球面---重构《黑客帝国》的‘上帝机器’，Deus Ex Machina

• liu_if_else
• 2016年06月01日 12:10
• 868

## 从头开始绘制一个圆锥体

• zxx43
• 2014年12月13日 14:39
• 1026

## Deus Ex：人类革命 - 图形研究

• tailiangliang
• 2017年07月30日 08:30
• 261

## 1.B向量空间的定义

• my_live_123
• 2017年08月03日 00:04
• 300

## unity中光照模型和光照计算

• u010006851
• 2016年10月21日 19:56
• 1829

举报原因： 您举报文章：在unity向量空间内绘制几何(2)：球面---重构《黑客帝国》的‘上帝机器’，Deus Ex Machina 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)