garrilla
garrilla

Reputation: 569

how to reflect an object about a plane?

given a plane gameobject, I would like to reflect an object about that plane

a simple case of this would be a plane at 0,0,0 with no rotation with the object at 0,-1,0 which results in a reflected position on 0,1,0

a more complex case, is the plane at 0,0,0 with rotation on the x-axis of 45` with the object at 0,-1,-1 which results in a reflected position on 0,1,1

I'm looking for a solution that can take any case of a plane in any position with any rotation.

Upvotes: 1

Views: 961

Answers (3)

Kurbol
Kurbol

Reputation: 101

This is the code I use:

  /// <summary>
  /// Mirror point to opposite side of a plane
  /// </summary>
  public static Vector3 Mirror(this Vector3 point, Plane plane)
    => 2f * plane.ClosestPointOnPlane(point) - point;

Upvotes: 2

derHugo
derHugo

Reputation: 90724

You can use Plane.ClosestPointOnPlane to get the according position on the plane.

Therefore you need to create a Plane first. As inNormal you have to use a vector perpendicular to the planes surface.

  • For a Quad Primitive this is the negative forward vector
  • for a Plane Primitive it is the up vector instead.

Than you can simply use the Vector between the original object and that ClosestPointOnPlane in order to move to the same relative position but with an inverted Vector:

public class ReflectPosition : MonoBehaviour
{
    public Transform Source;
    public Transform Plane;

    // Update is called once per frame
    private void Update()
    {
        // create a plane object representing the Plane
        var plane = new Plane(-Plane.forward, Plane.position);

        // get the closest point on the plane for the Source position
        var mirrorPoint = plane.ClosestPointOnPlane(Source.position);

        // get the position of Source relative to the mirrorPoint
        var distance = Source.position - mirrorPoint;

        // Move from the mirrorPoint the same vector but inverted
        transform.position = mirrorPoint - distance;
    }
}

Result (blue ball has this component attached and reflects white balls position)

enter image description here

Upvotes: 6

Ali Kanat
Ali Kanat

Reputation: 1889

You can use Vector3.ProjectOnPlane like this:

//I used a cube and a quad. So i am finding the projection of cube's position onto quad
public GameObject cube;
private Vector3 point;
private Vector3 projectedPoint;
void Start () {
    point = cube.transform.position;
    planeOrigin = gameObject.transform.position;
    Vector3 v = point - planeOrigin;
    Vector3 d = Vector3.Project(v, -gameObject.transform.forward);
    projectedPoint = point - d;
}   

void OnDrawGizmos()
{
    Gizmos.color = Color.red;
    Gizmos.DrawLine(point, projectedPoint);
}

You can see how it works from the image below:

enter image description here

Then you can calculate the reflection by calculating direction between point and projected point and multiplying it with two times of distance between them like this:

 Vector3 reflection = point + 2*(projectedPoint - point);

Upvotes: 1

Related Questions