【问题标题】:Programmatically create a 3D prism from location of its vertices以编程方式从顶点位置创建 3D 棱柱
【发布时间】:2015-05-17 05:52:30
【问题描述】:

我正在使用 Unity 4.6 开发一个项目。我想知道是否有一种简单的方法可以以编程方式设置顶点位置。目前我的代码看起来像这样(C#):

public void createPoints(float x, float y, float z) {
    point [0] = new Vector3 (x, y, z);
    point [1] = new Vector3 (x, y, -z);
    point [2] = new Vector3 (x, -y, z);
    point [3] = new Vector3 (x, -y, -z);
    point [4] = new Vector3 (-x, y, z);
    point [5] = new Vector3 (-x, y, -z);
    point [6] = new Vector3 (-x, -y, z);
    point [7] = new Vector3 (-x, -y, -z);
}

其中 x、y 和 z 是预定值,point 是 Vector3[](数组)。棱镜的中心是点0,0,0(Unity 中的Vector3(0,0,0))。

例如,使用以下值:

  • x = 1
  • y = 2
  • z = 3

生成的点数应该如下(顺序无关):

  1. (1,2,3)
  2. (1,2,-3)
  3. (1,-2,3)
  4. (1,-2,-3)
  5. (-1,2,3)
  6. (-1,2,-3)
  7. (-1,-2,3)
  8. (-1,-2,-3)

我的问题:有没有一种方法可以生成这些点,而无需对其中的值进行实际硬编码?

我当前所需解决方案的代码是:

public void createPoints(float originalX, float originalY, float originalZ) {
    for (int i = 0; i < 8; i++) { //8 vertices exist of a rectangular prism
        point [i] = new Vector3 (x, y, z);
    }
}

如何更改此代码以生成这些正点和负点?我的猜测是 x、y 和 z 的正值和负值之间的某种交替,使用 i 的模数或将 i 除以其他整数的四舍五入,但是我无法绕开它。 C# 或 UnityScript 都可以。

换句话说,在 for 循环的每次迭代中,x = -x,对于每个事物 y = -y,对于每个事物 z = -z

非常感谢任何帮助。

【问题讨论】:

  • 我建议更改标题。这可能会产生误导。大多数人甚至不会阅读您的帖子并将其关闭,因为它是“基于意见的”,因为您使用了“最佳方式”这个词
  • 谢谢,我刚刚编辑了标题并删除了“最佳方式”

标签: c# arrays unity3d unityscript


【解决方案1】:

我会为此使用 linq

var alt = new[] { 1, -1 };
var result = ( from i in alt
               from j in alt
               from k in alt
               select new Vector3(i * 1, j * 2, k * 3)
              ).ToList();

【讨论】:

  • 不完全确定这是如何工作的,但确实如此,赞!
【解决方案2】:

您可以像这样使用嵌套的for 循环来做到这一点:

List<Vector3> points = new List<Vector3>();

for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++)
        for (int k = 0; k < 2; k++)
            points.Add(new Vector3(i == 0 ? originalX : -originalX,
                                   j == 0 ? originalY : -originalY,
                                   k == 0 ? originalZ : -originalZ));

Vector3[] point = points.ToArray();

可能有一种更简单、更简洁的方法来做到这一点,但它确实有效。

【讨论】:

  • 我刚想出这个:for (var i = 0; i &lt; 8; i++) { if (i % 4) { x = -x; } if (i % 2) { y = -y; } z = -z; point[i] = new Vector3(x,y,z); }(将粘贴复制到jsfiddle.net,然后点击 tidyup 以查看它是否更干净。我不确定它们会如何影响性能,你有什么想法?
  • 我在上面的评论中创建了一个小提琴:jsfiddle.net/ctwheels/260quLL0
  • 您所拥有的确实有效,但它不会以相同的顺序创建它们。如果顺序无关紧要,任何一个都可以,但是如果顺序很重要,您需要在事后订购它们。至于性能,如果顺序无关紧要,你的速度会更快,但如果顺序很重要,我让我的平均运行速度更快(尽管 0.0005 秒)。长话短说,两者都行。
【解决方案3】:

我不知道我的 Unity 语法是否正确,但这段代码应该可以修改以便在那里工作。基本上,它为您提供了 8 个向量。 x 值为 x, -x, x, -x, ... y 值为 y, y, -y, -y, y, y, ... 而 z 值为 z, z, z, z ,-z,-z,-z,-z。 这是通过将 -1 乘以偶数和奇数次方来完成的。

function createPoints(x, y, z) {
  var resp = [];
  for (var i = 0; i < 8; ++i) {
    var vect = new Vector3d(x * Math.pow(-1, i), y * Math.pow(-1, Math.floor(i / 2)), z * Math.pow(-1, Math.floor(i / 4)));
    resp.push(vect);
  }
  return resp;
}

createPoints(1,2,3);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 2015-06-09
    • 2017-10-30
    • 2017-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多