如何确定厚度与宽度? (使用光线投射) [英] How to determine thickness vs width? (Using Raycasting)

查看:179
本文介绍了如何确定厚度与宽度? (使用光线投射)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

视觉辅助工具
厚度与宽度:此处

Visual aids
Thickness vs width: here

请查看简短的gif.
此处的厚度与宽度不同,因为有多个壁,并且有外部圆柱体和内部圆柱体.厚度是圆柱体任何一侧的外壁/内壁之间的距离的度量,而厚度是指从一端到另一端的距离,包括两端之间的中空空间.

Please view the short gif.
Thickness here is different from width as there are multiple walls as there are outer and inner cylinders. Thickness is the measurement of the distance between the outer/inner wall of any side of the cylinder where as thickness is the distance from one end to the other encompassing the hollow space between.

提供的gif简介
-每次单击时,都会创建起点(蓝色)和终点(橙色)球,以表示用户单击的位置以及用于计算距离的解释终点(在GUI上显示).

Quick synopsis on the gifs provided
-On every click the origin point (blue) and destination point (orange) orbs are created to denote where the user clicks and the interpreted end point used to calculate the distance (displayed on the GUI).

原点定义了用户单击对象碰撞器表面的位置,目的地定义了与原点的世界Y轴垂直的点,第二条射线向第一条射线投射在该点上对撞机.

The origin defines where the user clicks on the surface of an objects collider and the destination defines the point, perpendicular with the world Y axis of the origin, where a second ray cast towards the first ray, hits the other side of the collider.

当前:

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{

//obtain the vector where the ray hit the collider.
    hitPoint = hit.point; //origin point
//offset the ray, keeping it along the XZ plane of the hit
    Vector3 offsetDirection = -1 * hit.normal;
//offset a long way, minimum thickness of the object
    ray.origin = hit.point  + offsetDirection * 100;
//point the ray back at the first hit point
    ray.direction = (hit.point - ray.origin).normalized;
//raycast all, because there might be other objects in the way
    RaycastHit[] hits = Physics.RaycastAll(ray);
    foreach (RaycastHit h in hits)
    {
        if (h.collider == hit.collider)
        {
            hitBack = h.point; //destination point
        }
    }
}

当前,宽度是适当的功能.我想计算厚度而不必进入对象内部(如gif所示).

Currently, width is the functionality in place. I want to calculate thickness without having to go inside of an object (as seen in the gif).

惊人的参考
http://answer.unity3d.com/questions/386698/detecting-how-many-times-a-raycast-collides-with-a.html

这个人基本上和我有同样的问题,并且有一个可能可行的解决方案.我不确定Linecasting与Raycasting的工作方式.

This guy basically had the same question as me and has a solution that could possibly work. I'm not sure how Linecasting works vs Raycasting.

推荐答案

保持:

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{

//obtain the vector where the ray hit the collider.
    hitPoint = hit.point; //origin point
//offset the ray, keeping it along the XZ plane of the hit
    Vector3 offsetDirection = -1 * hit.normal;
//offset a long way, minimum thickness of the object
    ray.origin = hit.point  + offsetDirection * 100;
//point the ray back at the first hit point
    ray.direction = (hit.point - ray.origin).normalized;

替换:

//raycast all, because there might be other objects in the way
    RaycastHit[] hits = Physics.RaycastAll(ray);
    foreach (RaycastHit h in hits)
    {
        if (h.collider == hit.collider)
        {
            hitBack = h.point; //destination point
        }
    }

使用(对

With (credits to MirrorMirror's insightful post, and @ryemoss for his instrumental advice and assistance):

int counter = 0;
bool calculating = false; //set this to true on click
Vector3 Point, PreviousPoint, Goal, Direction;
Point = ray.origin;
Goal = hit.point;
Direction = ray.direction;

PreviousPoint = Vector3.zero;
while (calculating == true)
{
    counter++;
    RaycastHit hit2;
    if (Physics.Linecast(Point, Goal, out hit2))
    {
        if(counter > 100)
        {
            hitBack = hitPoint;
            counter = 0;
            calculating = false;
            break;
        }
        PreviousPoint = hit2.point;
        Point = hit2.point + (Direction / 10000f);
    }
    else
    {
        if (PreviousPoint == Vector3.zero)
            hitBack = hitPoint;
        else
            hitBack = PreviousPoint;

        calculating = false;
        counter = 0;
    }
}

Linecast vs Raycast
通过射线广播,您可以设置起点,方向和要在该方向上检查的距离;通过射线广播,您可以简单地设置起点和终点,并在这两个点之间进行检查.

Linecast vs Raycast
With a raycast you set the start point, the direction, and the distance to check in that direction, with a linecast you simply set start and end points and it checks between those 2 points.

因此,如果您确切地知道终点,请使用线路广播;如果要检查特定方向但没有特定终点,请使用raycast.

So, if you know the end destination specifically, use linecast, if you want to check in a specific direction but have no specific end point, use raycast.

解决方案
首先,使用初始光线投射获得第一个点hit.point.然后,将ray.origin设置到对撞机(我们首先与之碰撞的对象的对撞机,以获得hit.point的对撞机)之外的世界空间中的一个点,并将ray.direction设置为在第一个点向后面向射线点.

Solution
First, use the initial raycast to obtain the first point, hit.point. Then, set the ray.origin to a point in world space outside the collider (the collider of the object we first collided with to obtain hit.point), and set the ray.direction to face the ray back at the first point, hit.point.

最后,使用ray循环在ray.origins创建一个新位置(每次通过while循环更新,直到linecast到达hit.point),每次与对象发生碰撞,直到linecast到达一个新位置命中点.一旦到达hit.point,则意味着物体的每个表面都被命中,并且在每次命中时都会创建一条新线,直到一条线到达第一个初始点hit.point.要计算厚度,请计算第一个匹配点hit.point与反向线播匹配的匹配点hit.point,PreviousPoint之间的距离.

Finally, use a while loop to create a new linecast, at ray.origins new position (updated each time through the while loop until a linecast reaches hit.point), each time a collision with the object occurs until a linecast reaches hit.point. Once hit.point has been reached, it means every surface of the object was hit and on each hit, a new line was created until a line reached the first initial point, hit.point. To calculate thickness, take the distance between the first hit, hit.point, and the hit previous to the reverse linecast hitting hit.point, PreviousPoint.

更新
1修改代码以正确处理1面对象(例如:Planes).
2添加了计数器,以防止无法进行计算的特殊情况.
3-提高可读性.

UPDATE
1-Revise the code to properly handle 1-sided objects (ex: Planes).
2-Added counter to prevent special cases in which calculation not possible.
3-Improve readability.

这篇关于如何确定厚度与宽度? (使用光线投射)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆