gpt4 book ai didi

c# - 如何从与球体相切的点 P 中随机找到向量之一

转载 作者:行者123 更新时间:2023-12-04 13:31:12 24 4
gpt4 key购买 nike

我想随机选择一个起源于 P 点的向量,这样在这个向量旁边形成的线与某个球体的表面相切。为此,我需要在球体上形成一个圆的所有点 S 的集合,使得线 SP 在点 S 处与球体相切。然后,根据这些信息,我可以选择一个点 S',并创建一个从点 P 到点 S' 的方向向量。
我想在 Unity 中做到这一点。我对矢量本身的创建方式没有太多偏好,只要它可以随机化并指向上述圆圈上的一个点。我相信理想的解决方案会考虑角度 θ ∈ [0, 2π]它可以随机给出一个从圆(不是球体)的原点到相关 S' 点的向量。
我很感激 C# 中的解决方案,但我对其他语言也很满意。请注意,虽然数学解决方案受到赞赏,但我特别在寻找实现细节,因为我对 Unity 引擎、它们的坐标系和矢量操作还不是很熟练。
下面的可视化:
Visualisation

最佳答案

Unity中的解决方法如下:

  • 计算圆的中心点
  • 计算圆的半径
  • 使用 3D 坐标中随机选择的点和点 P
  • 创建投影
  • 使用中心点和半径来定位该点,从而找到 S',使得 PS' 与球体相切
  • using UnityEngine;

    public class Script : MonoBehaviour
    {
    private readonly float _accuracy = 0.1f;
    private readonly int _vectorsCount = 1000;
    private readonly Vector3 _point = new Vector3(600, 600, 600);
    private readonly float _sphereRadius = 500f;

    private void Start()
    {
    // This value will be used to calculate both the circle coordinates and its radius.
    var quadraticSum = Mathf.Pow(_point.x, 2) + Mathf.Pow(_point.y, 2) + Mathf.Pow(_point.z, 2);

    // Find out coordinates of the circle created by the intersection of the plane with the sphere
    Vector3 circleCenter;
    circleCenter.x = _point.x * Mathf.Pow(_sphereRadius, 2) / quadraticSum;
    circleCenter.y = _point.y * Mathf.Pow(_sphereRadius, 2) / quadraticSum;
    circleCenter.z = _point.z * Mathf.Pow(_sphereRadius, 2) / quadraticSum;

    // Find out radius of the above circle
    var circleRadius = _sphereRadius * Mathf.Sqrt(quadraticSum - Mathf.Pow(_sphereRadius, 2)) /
    Mathf.Sqrt(quadraticSum);

    /*
    * At this point, we can start drawing - let's draw:
    *
    * - the point using red colour
    * - the sphere using blue colour
    * - the circle using green colour
    *
    * Below assumes center of the sphere is at (0, 0, 0)
    */
    Debug.DrawLine(Vector3.zero, _point, Color.red, 1000);
    DrawSphere();
    DrawCircle(circleCenter, circleRadius);
    }

    private void DrawSphere()
    {
    for (var theta = -Mathf.PI; theta < Mathf.PI; theta += _accuracy)
    {
    for (var phi = -Mathf.PI; phi < Mathf.PI; phi += _accuracy)
    {
    var ray = new Vector3(
    _sphereRadius * Mathf.Sin(theta) * Mathf.Cos(phi),
    _sphereRadius * Mathf.Sin(theta) * Mathf.Sin(phi),
    _sphereRadius * Mathf.Cos(theta)
    );
    Debug.DrawLine(Vector3.zero, ray, Color.blue, 1000);
    }
    }
    }

    private void DrawCircle(Vector3 center, float radius)
    {
    for (int i = 0; i < _vectorsCount; i++)
    {
    // Since I wanted random vectors, I am repeatedly drawing a random vector on the circle
    var tangentPoint = Vector3.ProjectOnPlane(Random.insideUnitSphere, _point).normalized * radius + center;
    Debug.DrawLine(Vector3.zero, tangentPoint, Color.green, 1000);
    //Debug.DrawLine(_point, tangentPoint, Color.cyan, 1000);
    }
    }
    }
    请参阅屏幕截图以进行可视化:
    Angle1
    Angle3
    Cone
    这是绘制球体和圆后绘制的红线的角度,以查看球体的中心:
    AngleBonus

    关于c# - 如何从与球体相切的点 P 中随机找到向量之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64945214/

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