본문 바로가기
개발/Unity

유니티 - 평면과 점 사이의 최단거리를 만드는 평면 위의 점 구하기

by 피로물든딸기 2022. 11. 11.
반응형

Unity 전체 링크

 

참고

- 평면과 점 사이의 최단거리 구하기

- Vector3.Cross로 평면 위에서 시계 방향 판단하기

 

파란색 공과 평면 사이의 최단거리를 구하고, 평면 위에 최단거리를 만드는 점을 빨간색 공으로 표시해보자.

 

Plane과 파란색 공을 만들고 DotOnthePlane.cs를 파란색 공에 추가한다.

그리고 planeObject에 Plane을 할당하고 OnDrawGizmos로 평면의 노멀 벡터를 그려보자.

    public GameObject planeObject;
    public GameObject dotOnthePlane;

    void OnDrawGizmos()
    {
        Gizmos.color = Color.blue;
        Gizmos.DrawRay(planeObject.transform.position, planeObject.transform.up);
    }

 

아래와 같이 적절히 오브젝트를 배치하자.

참고로 Plane의 transform.up노멀 벡터가 된다.

 

빨간색 공을 만들고 dotOnthePlane에 할당한다.


구현

 

평면과 점 사이의 최단거리는 아래의 함수로 구할 수 있다.

    float distancePlaneToPoint(Vector3 normal, Vector3 planeDot, Vector3 point)
    {
        Plane plane = new Plane(normal, planeDot);
        return plane.GetDistanceToPoint(point);
    }

 

최단거리를 알 수 있으니

파란색 공에서 평면의 노멀 벡터 반대 방향으로 최단거리만큼 옮기면 빨간색 공의 위치가 된다.

 

따라서 빨간색 공의 위치는 아래의 함수로 구할 수 있다.

    Vector3 getPositionOnthePlane(Vector3 normal, Vector3 planeDot, Vector3 position)
    {
        float distance = distancePlaneToPoint(normal, planeDot, position);
        return position - normal * distance;
    }

 

이제 Update에서 빨간색 공의 위치를 계속 갱신하면 된다.

    void Update()
    {
        Vector3 normal = planeObject.transform.up;
        Vector3 planeDot = planeObject.transform.position;
        Vector3 point = this.transform.position;

        dotOnthePlane.transform.position = getPositionOnthePlane(normal, planeDot, point);
    }

 

게임을 실행하면 평면과 최단거리를 만드는 빨간색 공파란색 공을 따라 움직인다.

 

전체 코드는 다음과 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DotOnthePlane : MonoBehaviour
{
    public GameObject planeObject;
    public GameObject dotOnthePlane;

    void OnDrawGizmos()
    {
        Gizmos.color = Color.blue;
        Gizmos.DrawRay(planeObject.transform.position, planeObject.transform.up);
    }

    float distancePlaneToPoint(Vector3 normal, Vector3 planeDot, Vector3 point)
    {
        Plane plane = new Plane(normal, planeDot);
        return plane.GetDistanceToPoint(point);
    }

    Vector3 getPositionOnthePlane(Vector3 normal, Vector3 planeDot, Vector3 position)
    {
        float distance = distancePlaneToPoint(normal, planeDot, position);
        return position - normal * distance;
    }

    void Update()
    {
        Vector3 normal = planeObject.transform.up;
        Vector3 planeDot = planeObject.transform.position;
        Vector3 point = this.transform.position;

        dotOnthePlane.transform.position = getPositionOnthePlane(normal, planeDot, point);
    }
}

 

위의 실행결과는 아래의 unitypackage에서 확인 가능하다

DotOnthePlane.unitypackage
0.03MB

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글