【问题标题】:Measure the length using the Raycast and Triangular functions, Unity3D使用 Raycast 和三角形函数 Unity3D 测量长度
【发布时间】:2019-09-07 13:07:07
【问题描述】:

我正在使用 Unity 在移动环境中开发 AR。

* 顶部和底部已更改 :)

目前的流程如下:

1.测量移动设备的坡度。

float angle = Camera.main.transform.eulerAngles.x * Mathf.Deg2Rad;

2。在移动屏幕上的两个点向表面发射光线(顶部,底部)

  • 两点的x坐标相同

  • y 坐标是顶部,较小的是底部。

    Vector3 Top = hitTop.Pose.position;       
    Vector3 Bottom = hitBottom.Pose.position;
    

3.测量移动设备与其表面之间的高度差(Y轴)

Vector3 CameraPoint = Camera.main.transform.position;
Vector3 SurfacePoint = new Vector3(CameraPoint.x, Bottom.y, CameraPoint.z);
float H = CameraPoint.y - SurfacePoint.y; 

4.测量水平线的长度以利用比例表达式。

float W = Vector3.Distance(Top, SurfacePoint); 
float w = Vector3.Distance(Top, Bottom);   

5.使用比例表达式,计算小三角形的高度。

H:W = h:w => H * w = W * h => ∴ h = (H * w) / W

float h = ((H * w) / W);

6.用两条线(h,w)和相机的斜率,我想测量紫色线的长度。

  • 将此问题解释为坐标平面,并在斜边上创建表达式

    x/w + y/h = 1

  • 使用直线斜率,得到直线表达式。

    y = tan(90-θ)x

这两个表达式如下。

x = 1/(1/w + tan(90-θ)/h)

y = tan(90-θ)/(1/w + tan(90-θ)/h)

7.为防止无穷大,将tanθ改为cosθ、sinθ。

* tanθ = sinθ / cosθ
* tan(90 - θ) = cosθ / sinθ

x = 1/(1/w + cosθ/(h * sinθ))

y = (cosθ/sinθ)/(1/w + cosθ/(h * sinθ))

8.我做了一个简单的更改,因为表达式太复杂了。

var x = (h * w * Mathf.Sin(angle)) / (h * Mathf.Sin(angle) + w * Mathf.Cos(angle));

var y = (h * w * Mathf.Cos(angle)) / (h * Mathf.Sin(angle) + w * Mathf.Cos(angle));

9.我测量了距离(0,0),(x,y)

float Object_height = Vector2.Distance(Vector2.zero, new Vector2(x, y));

目前,所需长度是通过上述计算方法测量的。 但它不能正常工作。

我想要的是紫色的长度。

我只知道星形坐标,相机的斜率,紫线的斜率。

紫色线的斜率与相机相同。

下图为失败案例。

我认为红色和黄色Ray之间的差距越大,价值越不同。

哪一部分错了?

告诉我如何使用三角函数得到紫色线的长度。

【问题讨论】:

    标签: unity3d math trigonometry raycasting


    【解决方案1】:

    在 Unity 的 Ray 类/结构的帮助下,无需任何三角函数即可轻松实现,它提供了方便的 GetPoint(float distance) 方法。 获取从相机到您附近的光线投射的距离是微不足道的(.magnitude),而不是进行第二次光线投射,它足以创建一条光线,并在给定距离处查询一个点。从您的示例中获取紫色线的长度只是做另一个 .magnitude 的问题

        startPos=transform.position;    // to be replaced with camera position
        var hitpoint1=targetA.position; // to be replaced with raycasts hit1
        var hitpoint2=targetB.position; // to be replaced with reaycast hit2
        Ray rayB=new Ray(startPos,hitpoint2-startPos);
        float dist=(hitpoint1-startPos).magnitude;
        var purpleEndPoint=rayB.GetPoint(dist);
    
        Debug.Log("purple line length ="+(hitpoint1-purpleEndPoint).magnitude);
    

    【讨论】:

    • 为什么使用float dist=(hitpoint1-startPos).magnitude;而不是float dist=vector3.Distance(hitpoint1, startPos);
    • @akaBase 少一个字符 :) 我相信这两个电话做的事情完全一样
    • @zambari 无法与效率争论!
    • @akaBase 来自docs: Vector3.Distance(a,b) is the same as (a-b).magnitude -> 完全一样
    • @derHugo 谢谢,由于可读性,我更喜欢使用Vector3.Distance(a,b),但它是 6 of 1,其他 6 个 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 2023-01-30
    • 2016-02-28
    • 1970-01-01
    • 2013-09-17
    • 2014-03-18
    相关资源
    最近更新 更多