gpt4 book ai didi

java - 如何绘制球体的中半部分(在代码中)

转载 作者:行者123 更新时间:2023-12-01 09:44:51 24 4
gpt4 key购买 nike

我正在尝试创建一个球体的中半部分。基本上创建一个球体,给出堆栈号和切片号,并且有两个变量 phi (对于切片)和 theta (对于堆栈)负责进度多少。该过程分为创建底盖、主体和顶盖(如下所示)。为了实现中间一半(如下所示中间50%的theta),我们需要省略大写字母,并以某种方式修改主体。我正在玩弄堆栈号( 1/4*stackNumbers to 3/4*stackNumbers ),但没有给出我想要的结果。

我应该如何修改球体生成以实现中间一半( pi/4 <theta <pi*3/4 )?我的总体问题是如何将球体分成 3 个不同的部分,上部 25%、中部 50% 和底部 25%? (角度为 25%,即 theta )

以下是以编程方式生成球体的流行代码:

enter image description here

private void generateSphere(int stackNumber, int sliceNumber, boolean facingOut) {
int capVertexNumber = 3 * sliceNumber;
int bodyVertexNumber = 4 * sliceNumber * (stackNumber - 2);
int vertexNumber = (2 * capVertexNumber) + bodyVertexNumber;
int triangleNumber = (2 * capVertexNumber) + (6 * sliceNumber * (stackNumber - 2));

vertices = new float[3 * vertexNumber];
normals = new float[3 * vertexNumber];
texCoords = new float[2 * vertexNumber];
indices = new char[triangleNumber];

// bottom cap
// createCap(stackNumber, sliceNumber, false, facingOut);

// body
createBody(stackNumber, sliceNumber, facingOut);

// top cap
createCap(stackNumber, sliceNumber, true, facingOut);
}

private void createCap(int stackNumber, int sliceNumber, boolean top, boolean facingOut) {

float stackPercentage0;
float stackPercentage1;

if (!top) {
stackPercentage0 = ((float) (stackNumber - 1) / stackNumber);
stackPercentage1 = 1.0f;

} else {
stackPercentage0 = (1.0f / stackNumber);
stackPercentage1 = 0.0f;
}

float t0 = stackPercentage0;
float t1 = stackPercentage1;
double theta0 = stackPercentage0 * Math.PI;
double theta1 = stackPercentage1 * Math.PI;
double cosTheta0 = Math.cos(theta0);
double sinTheta0 = Math.sin(theta0);
double cosTheta1 = Math.cos(theta1);
double sinTheta1 = Math.sin(theta1);

for (int slice = 0; slice < sliceNumber; slice++) {
float slicePercentage0 = ((float) (slice) / sliceNumber);
float slicePercentage1 = ((float) (slice + 1) / sliceNumber);
double phi0 = slicePercentage0 * 2.0 * Math.PI;
double phi1 = slicePercentage1 * 2.0 * Math.PI;
float s0, s1;
if (facingOut) {
s0 = 1 - slicePercentage0;
s1 = 1 - slicePercentage1;
} else {
s0 = slicePercentage0;
s1 = slicePercentage1;
}
float s2 = (s0 + s1) / 2.0f;
double cosPhi0 = Math.cos(phi0);
double sinPhi0 = Math.sin(phi0);
double cosPhi1 = Math.cos(phi1);
double sinPhi1 = Math.sin(phi1);

float x0 = (float) (sinTheta0 * cosPhi0);
float y0 = (float) cosTheta0;
float z0 = (float) (sinTheta0 * sinPhi0);

float x1 = (float) (sinTheta0 * cosPhi1);
float y1 = (float) cosTheta0;
float z1 = (float) (sinTheta0 * sinPhi1);

float x2 = (float) (sinTheta1 * cosPhi0);
float y2 = (float) cosTheta1;
float z2 = (float) (sinTheta1 * sinPhi0);

vertices[vertexCount + 0] = x0;
vertices[vertexCount + 1] = y0;
vertices[vertexCount + 2] = z0;

vertices[vertexCount + 3] = x1;
vertices[vertexCount + 4] = y1;
vertices[vertexCount + 5] = z1;

vertices[vertexCount + 6] = x2;
vertices[vertexCount + 7] = y2;
vertices[vertexCount + 8] = z2;

if (facingOut) {
normals[vertexCount + 0] = x0;
normals[vertexCount + 1] = y0;
normals[vertexCount + 2] = z0;

normals[vertexCount + 3] = x1;
normals[vertexCount + 4] = y1;
normals[vertexCount + 5] = z1;

normals[vertexCount + 6] = x2;
normals[vertexCount + 7] = y2;
normals[vertexCount + 8] = z2;
} else {
normals[vertexCount + 0] = -x0;
normals[vertexCount + 1] = -y0;
normals[vertexCount + 2] = -z0;

normals[vertexCount + 3] = -x1;
normals[vertexCount + 4] = -y1;
normals[vertexCount + 5] = -z1;

normals[vertexCount + 6] = -x2;
normals[vertexCount + 7] = -y2;
normals[vertexCount + 8] = -z2;
}

texCoords[texCoordCount + 0] = s0;
texCoords[texCoordCount + 1] = t0;
texCoords[texCoordCount + 2] = s1;
texCoords[texCoordCount + 3] = t0;
texCoords[texCoordCount + 4] = s2;
texCoords[texCoordCount + 5] = t1;

if ((facingOut && top) || (!facingOut && !top)) {
indices[indexCount + 0] = (char) (triangleCount + 1);
indices[indexCount + 1] = (char) (triangleCount + 0);
indices[indexCount + 2] = (char) (triangleCount + 2);
} else {
indices[indexCount + 0] = (char) (triangleCount + 0);
indices[indexCount + 1] = (char) (triangleCount + 1);
indices[indexCount + 2] = (char) (triangleCount + 2);
}

vertexCount += 9;
texCoordCount += 6;
indexCount += 3;
triangleCount += 3;
}

}

private void createBody(int stackNumber, int sliceNumber, boolean facingOut) {
for (int stack = 1; stack < stackNumber - 1; stack++) {
float stackPercentage0 = ((float) (stack) / stackNumber);
float stackPercentage1 = ((float) (stack + 1) / stackNumber);

float t0 = stackPercentage0;
float t1 = stackPercentage1;

double theta0 = stackPercentage0 * Math.PI;
double theta1 = stackPercentage1 * Math.PI;
double cosTheta0 = Math.cos(theta0);
double sinTheta0 = Math.sin(theta0);
double cosTheta1 = Math.cos(theta1);
double sinTheta1 = Math.sin(theta1);

for (int slice = 0; slice < sliceNumber; slice++) {
float slicePercentage0 = ((float) (slice) / sliceNumber);
float slicePercentage1 = ((float) (slice + 1) / sliceNumber);
double phi0 = slicePercentage0 * 2.0 * Math.PI;
double phi1 = slicePercentage1 * 2.0 * Math.PI;
float s0, s1;
if (facingOut) {
s0 = 1.0f - slicePercentage0;
s1 = 1.0f - slicePercentage1;
} else {
s0 = slicePercentage0;
s1 = slicePercentage1;
}
double cosPhi0 = Math.cos(phi0);
double sinPhi0 = Math.sin(phi0);
double cosPhi1 = Math.cos(phi1);
double sinPhi1 = Math.sin(phi1);

float x0 = (float) (sinTheta0 * cosPhi0);
float y0 = (float) cosTheta0;
float z0 = (float) (sinTheta0 * sinPhi0);

float x1 = (float) (sinTheta0 * cosPhi1);
float y1 = (float) cosTheta0;
float z1 = (float) (sinTheta0 * sinPhi1);

float x2 = (float) (sinTheta1 * cosPhi0);
float y2 = (float) cosTheta1;
float z2 = (float) (sinTheta1 * sinPhi0);

float x3 = (float) (sinTheta1 * cosPhi1);
float y3 = (float) cosTheta1;
float z3 = (float) (sinTheta1 * sinPhi1);

vertices[vertexCount + 0] = x0;
vertices[vertexCount + 1] = y0;
vertices[vertexCount + 2] = z0;

vertices[vertexCount + 3] = x1;
vertices[vertexCount + 4] = y1;
vertices[vertexCount + 5] = z1;

vertices[vertexCount + 6] = x2;
vertices[vertexCount + 7] = y2;
vertices[vertexCount + 8] = z2;

vertices[vertexCount + 9] = x3;
vertices[vertexCount + 10] = y3;
vertices[vertexCount + 11] = z3;

if (facingOut) {
normals[vertexCount + 0] = x0;
normals[vertexCount + 1] = y0;
normals[vertexCount + 2] = z0;

normals[vertexCount + 3] = x1;
normals[vertexCount + 4] = y1;
normals[vertexCount + 5] = z1;

normals[vertexCount + 6] = x2;
normals[vertexCount + 7] = y2;
normals[vertexCount + 8] = z2;

normals[vertexCount + 9] = x3;
normals[vertexCount + 10] = y3;
normals[vertexCount + 11] = z3;
} else {
normals[vertexCount + 0] = -x0;
normals[vertexCount + 1] = -y0;
normals[vertexCount + 2] = -z0;

normals[vertexCount + 3] = -x1;
normals[vertexCount + 4] = -y1;
normals[vertexCount + 5] = -z1;

normals[vertexCount + 6] = -x2;
normals[vertexCount + 7] = -y2;
normals[vertexCount + 8] = -z2;

normals[vertexCount + 9] = -x3;
normals[vertexCount + 10] = -y3;
normals[vertexCount + 11] = -z3;
}

texCoords[texCoordCount + 0] = s0;
texCoords[texCoordCount + 1] = t0;
texCoords[texCoordCount + 2] = s1;
texCoords[texCoordCount + 3] = t0;
texCoords[texCoordCount + 4] = s0;
texCoords[texCoordCount + 5] = t1;
texCoords[texCoordCount + 6] = s1;
texCoords[texCoordCount + 7] = t1;

// one quad looking from outside toward center
//
// @formatter:off
//
// s1 --> s0
//
// t0 1-----0
// | | |
// v | |
// t1 3-----2
//
// @formatter:on
//
// Note that tex_coord t increase from top to bottom because the
// texture image is loaded upside down.
if (facingOut) {
indices[indexCount + 0] = (char) (triangleCount + 0);
indices[indexCount + 1] = (char) (triangleCount + 1);
indices[indexCount + 2] = (char) (triangleCount + 2);

indices[indexCount + 3] = (char) (triangleCount + 2);
indices[indexCount + 4] = (char) (triangleCount + 1);
indices[indexCount + 5] = (char) (triangleCount + 3);
} else {
indices[indexCount + 0] = (char) (triangleCount + 0);
indices[indexCount + 1] = (char) (triangleCount + 2);
indices[indexCount + 2] = (char) (triangleCount + 1);

indices[indexCount + 3] = (char) (triangleCount + 2);
indices[indexCount + 4] = (char) (triangleCount + 3);
indices[indexCount + 5] = (char) (triangleCount + 1);
}

vertexCount += 12;
texCoordCount += 8;
indexCount += 6;
triangleCount += 4;
}
}

}

最佳答案

这里的代码使用 spherical coordinates来计算球体。 theta 是代表您感兴趣的上/下坐标的变量,theta 从 0 到 PI。您想从 PI/4 转到 3PI/4。 stackNumbers 只是表示球体中的划分数,因为您可以看到它用作 stack 的分母,这是要更改的错误变量。因此,您可以对代码进行以下更改。来自:

double theta0 = stackPercentage0 * Math.PI;
double theta1 = stackPercentage1 * Math.PI;

至:

double startTheta = Math.PI / 4;
double endTheta = 3 * Math.PI / 4;
double theta0 = stackPercentage0 * (endTheta - startTheta) + startTheta;
double theta1 = stackPercentage1 * (endTheta - startTheta) + startTheta;

由于您没有使用上限,因此您需要更改开始和结束堆栈编号以反射(reflect)这一点:

for (int stack = 1; stack < stackNumber - 1; stack++) { // old
for (int stack = 0; stack < stackNumber; stack++) { // new

此外,由于您现在有更多的 body 面孔,因此您需要为它们更新适当的容器。将 (stackNumber - 2) 替换为 (stackNumber - 1)

关于java - 如何绘制球体的中半部分(在代码中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38149600/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com