使用Vuforia ARCamera在Unity中如何获取图像目标的四个角的屏幕位置?

huangapple go评论79阅读模式
英文:

How to get the screen position of the four corners of an image target using Vuforia ARCamera in Unity?

问题

"GetLocalCorners" 返回一个表示矩形形状角落的四个角的数组,但我需要图像角。

我想要获取黄点的屏幕位置(像素)。

英文:

How to find the screen position of the four corners of an image target in Vuforia for perspective transform?

"GetLocalCorners" returns an array of four corners that represent the corners of the rectangular shape. but I need image corners.

I want to get screen position(pixel) in yellow points

使用Vuforia ARCamera在Unity中如何获取图像目标的四个角的屏幕位置?

答案1

得分: 0

以下是代码部分的翻译:

自从你提到了`GetLocalCorners`,假设你有一个`RectTransform` => 首先通过[GetWorldCorners](https://docs.unity3d.com/ScriptReference/RectTransform.GetWorldCorners.html)获取其世界坐标,然后通过[WorldToScreenPoint](https://docs.unity3d.com/ScriptReference/Camera.WorldToScreenPoint.html)将其转换为屏幕坐标。

例如:

```csharp
RectTransform rectTransform = YOUR_TARGET_RECT_TRANSFORM;
var corners = new Vector3[4];
rectTransform.GetWorldCorners(corners);
var camera = Camera.main;
for(var i = 0; i < corners.Length; i++)
{
    corners[i] = camera.WorldToScreenPoint(corners[i]);
}

现在corners中的坐标是以像素为单位的屏幕坐标。

如果目标实际上不是RectTransform,你需要首先自己在世界坐标中计算角点。可能看起来像:

var position = YOUR_TARGET_Transform.position;
// 假设缩放已经应用到目标上,以使其与目标尺寸匹配
var size = YOUR_TARGET_Transform.lossyScale;
// 假设目标默认在XZ平面上是平的
// => 默认情况下,transform.up朝向天空
// 如果目标实际上旋转了,你需要调整这些值
var x = YOUR_TARGET_Transform.right * size.x * 0.5f;
var z = YOUR_TARGET_Transform.forward * size.z * 0.5f;
var corners = new Vector3[4];
corners[0] = position - x - z;
corners[1] = position - x + z;
corners[2] = position + x + z;
corners[3] = position + x - z;

这是一个小示例:

public class TEST : MonoBehaviour
{
    public RectTransform[] images;

    // 在每帧调用一次
    void Update()
    {
        var position = transform.position;

        // 假设缩放已经应用到目标上,以使其与目标尺寸匹配
        var size = transform.lossyScale;

        // 假设目标默认在XZ平面上是平的
        // => transform.up默认朝向天空
        // 如果目标实际上旋转了,你需要调整这些值
        var x = transform.right * size.x * 0.5f;
        var z = transform.forward * size.z * 0.5f;
        var corners = new Vector3[4];
        corners[0] = position - x - z;
        corners[1] = position - x + z;
        corners[2] = position + x + z;
        corners[3] = position + x - z;

        for (var i = 0; i < 4; i++)
        {
            corners[i] = Camera.main.WorldToScreenPoint(corners[i]);

            images[i].position = (Vector2)corners[i];
        }
    }
}

使用Vuforia ARCamera在Unity中如何获取图像目标的四个角的屏幕位置?


这就是你提供的代码的翻译。

<details>
<summary>英文:</summary>

Since you speak of `GetLocalCorners` assuming you have a `RectTransform` =&gt; You would first go through [GetWorldCorners](https://docs.unity3d.com/ScriptReference/RectTransform.GetWorldCorners.html) then pass those through [WorldToScreenPoint](https://docs.unity3d.com/ScriptReference/Camera.WorldToScreenPoint.html)

so e.g.

    RectTransform rectTransform = YOUR_TARGET_RECT_TRANSFORM;
    var corners = new Vector3[4];
    rectTransform.GetWorldCorners(corners);
    var camera = Camera.main;
    for(var i = 0; i &lt; corners.Length; i++)
    {
        corners[i] = camera.WorldToScreenPoint(corners[i]);
    }

Now the `corners` are in pixel screen space.

---

If the target is actually not a `RectTransform` you would need to calculate the corners in worldspace yourself first. Might look somewhat like e.g.

    var position = YOUR_TARGET_Transform.position;
    // assuming that scale is applied to the target so that it matches with the target dimensions 
    var size = YOUR_TARGET_Transform.lossyScale;
    // assuming your target is by default flat on the XZ plane
    // =&gt; transform.up points towards the sky by default
    // if the target is actually rotated you need to adjust those
    var x = YOUR_TARGET_Transform.right * size.x * 0.5f;
    var z = YOUR_TARGET_Transform.forward * size.z * 0.5f;
    var corners = new Vector3[4];
    corners[0] = position - x - z;
    corners[1] = position - x + z;
    corners[2] = position + x + z;
    corners[3] = position + x - z;

Little demo of that

    public class TEST : MonoBehaviour
    {
        public RectTransform[] images;
    
        // Update is called once per frame
        void Update()
        {
            var position = transform.position;
    
            // assuming that scale is applied to the target so that it matches with the target dimensions 
            var size = transform.lossyScale;
    
            // assuming your target is by default flat on the XZ plane
            // =&gt; transform.up points towards the sky by default
            // if the target is actually rotated you need to adjust those
            var x = transform.right * size.x * 0.5f;
            var z = transform.forward * size.z * 0.5f;
            var corners = new Vector3[4];
            corners[0] = position - x - z;
            corners[1] = position - x + z;
            corners[2] = position + x + z;
            corners[3] = position + x - z;
    
            for (var i = 0; i &lt; 4; i++)
            {
                corners[i] = Camera.main.WorldToScreenPoint(corners[i]);
    
                images[i].position = (Vector2)corners[i];
            }
        }
    }

[![enter image description here][1]][1]


  [1]: https://i.stack.imgur.com/nTUPZ.gif

</details>



huangapple
  • 本文由 发表于 2023年3月9日 16:41:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75682171.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定