【问题标题】:Make ring of vectors "flat" relative to world space使向量环相对于世界空间“平坦”
【发布时间】:2020-01-25 02:00:35
【问题描述】:

我正在尝试模拟容器中的液体一致性。容器是 Unity 圆柱体,液体也是如此。我跟踪当前音量和最大音量,并使用它们来确定表面中心的坐标。当容器倾斜时,圆柱体上环中的每个顶点都应保持其当前的局部 x 和 z 值,但具有一个新的局部 y 值,该值在全局空间中与表面中心的高度相同。

在我最接近的尝试中,表面相对于世界空间是平坦的,但液体不会接触容器的壁。

Vector3 v = verts[i];

Vector3 newV = new Vector3(v.x, globalSurfaceCenter.y, v.z);
verts[i] = transform.InverseTransformPoint(newV);

(我知道在使用 v.x 和 v.z 后反转点会改变它们,但如果我在表面不再平坦之后改变它们......)

我尝试了许多不同的方法,但我总是以同样的方式结束,或者是陌生的方式。

另外,我不是在寻找任何根本不同的方法来解决这个问题。改变圆柱体的顶点很重要。

编辑

感谢大家的反馈。它帮助我在这个问题上取得了进展,但我遇到了另一个障碍。我使我的代码更加美观,并截取了一些结果以及图形模型,以帮助您可视化正在发生的事情并提供变量名称以供参考。

在下面的图像中,彩色立方体被实例化,并给出了我用来获得结果的一些不同向量的坐标。

F(red) A(green) B(blue)

H(green) E(blue)

Graphed Model

注意:当我提到大写字母 A 和 B 时,我指的是代码中的 Vector3。

图像中的圆柱体具有以下旋转(从左到右): (0,0,45) (45,45,0) (45,0,20)

从图 1 中可以看出,当仅应用一维旋转时,F 是正确的。当应用两个或多个时,表面是平坦的,但方向不正确。

如果我在生成这些结果后调整圆柱体的旋转,我可以让表面的方向变得有意义,但数字不是你所期望的。

例如:圆柱体 3(在右侧),调整为具有与世界空间平坦的表面,需要大约 (42.2, 0, 27.8) 的旋转。

不确定这是否有帮助,但这会增加我的困惑。

我的代码:(变量名参考图模型)

Vector3 v = verts[iter];

Vector3 D = globalSurfaceCenter;
Vector3 E = transform.TransformPoint(new Vector3(v.x, surfaceHeight, v.z));
Vector3 H = new Vector3(gsc.x, E.y, gsc.z);

float a = Vector3.Distance(H, D);
float b = Vector3.Distance(H, E);
float i = (a / b) * a;

Vector3 A = H - D;
Vector3 B = H - E;
Vector3 F = ((A + B)) + ((A + B) * i);

Instantiate(greenPrefab, transform).transform.position = H;
Instantiate(bluePrefab, transform).transform.position = E;

//Instantiate(redPrefab, transform).transform.position = transform.TransformPoint(F);
//Instantiate(greenPrefab, transform).transform.position = transform.TransformPoint(A);
//Instantiate(bluePrefab, transform).transform.position = transform.TransformPoint(B);

我的代码和图形模型中的一些变量最终可能不是必需的,但我希望它能给你更多的工作。

请记住,我一般不太精通几何和数学。请使用外行人的术语。谢谢!

再次感谢您花时间帮助我。

【问题讨论】:

  • 你是如何创建圆柱体的?你自己计算了顶点吗?
  • 我在统一编辑器中创建了容器圆柱体,将我的 LiquidDisplay 组件附加到它,从该组件中实例化了液体圆柱体并将其设置为容器的子级。
  • 您可以尝试verts[i] = new Vector3(v.x, 0, v.z); 而不是设置transform.position = globalSurfaceCenter; transform.rotation = Quaternion.Identity;,但是您仍然需要调整其比例,使其再次与父母边界匹配。
  • 在这种情况下,@derHugo 转换将引用容器转换。顶点是 Vector3 的。我只需要让每个人都保持它当前的局部 xz 并使局部 y 对应于表面中心的全局 y。
  • 我以为这个液缸会是容器的孩子?这将有助于查看您的完整脚本,以便也能够重现该问题。位置、旋转和比例当然需要应用于那个子/液缸。如果您还有父顶点,您可以尝试使用Vector3.Project,以便始终将顶点投影在父圆柱体的相应边缘上。

标签: unity3d vector geometry mesh


【解决方案1】:

作为第一步,我们可以计算圆柱体局部坐标系中上圆柱体表面的法线。鉴于您的圆柱体transform 的世界变换,这很简单:

localNormal = inverse(transform) * (0, 1, 0, 0)

使用这个法线和圆柱体高度h,我们可以将法线形式的上圆柱体的平面定义为

dot(localNormal, (x, y, z) - (0, h / 2, 0)) = 0

我假设你的圆柱体以原点为中心。

使用它,我们可以计算任何x/z 对的y 坐标

y = h / 2 - (localNormal.x * x + localNormal.z * z) / localNormal.y

【讨论】:

  • 感谢您的回答。我不擅长数学,也不知道如何将其解释为代码,但这让我想到了我所知道的一些事情。我取得了一些进展,但我仍然遇到问题。我用更多信息和结果更新了我的帖子。使用我提供的内容,如果在阅读我的编辑后您的答案确实相同,我将如何将您的答案应用于我的代码?仅供参考,我正在使用 C#。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 2019-05-12
  • 2011-12-18
  • 1970-01-01
  • 2022-06-12
  • 1970-01-01
  • 2021-12-14
相关资源
最近更新 更多