- Home /
How to create vector within triangle plane, from perpendiculor vector3
Hi, I've been working with Unity for a few months, but now I'm stuck - beginners Unity books don't include math primers ;)... I would like to know how to find a Vector3 position (p1) within a triangle in 3D space and I also need to know the distance from a point (p0) to the new point (p1). The new Vector3 needs to be created from a right angle between the triangle and p0 (perpendicular to the triangle). I'd also rather avoid RayCasting as I think that would be overkill and this operation needs to happen often. Note: There is 100% certainty that p0 is perpendicular to the triangle's underside.
I'm guessing the solution involves using the Vector3.Distance function at the end, but first calculating angles between some of the original vectors - which I can do using this but then I'm clueless. I've attached a picture of what I am trying to achieve.
Description and example code snippet would be much appreciated. Natural English explanation is preferable as my Greek is terrible. Alternatively (I've read asking for code is bad...?) if there's a link to a similar post, or simply a broken down list of things I need to do, where I can search more informed, then that would be great, but I have searched on several math sites, programming sites and unity without any luck - I've been googling for hours :( made worse as I'm not sure what I'm looking for ;) ANY Help would be much appreciated, please.
PS - my first post, so if I've broken protocol somehow, please let me know. Thanks
$$anonymous$$ight want to edit your question and fix the broken link to your image. Images really help in this situation. A couple of links to get you started:
Unity's mathematical Plane Class
$$anonymous$$ath3d in the Unity Wiki
I think you might be interested in this two functions in particular from $$anonymous$$ath3d: PlaneFrom3Points(), SignedDistancePlanePoint().
Edited link, think it works now? I'd assumed uploading images from local drive would mean answers forum would make a local copy automatically, evidently not. Checking out your links...
Pain that the image did not work initially, please let me know someone if it is still not working - I used http://i58.tinypic.com/2dquigx.png ins$$anonymous$$d this time for the pic.
Thanks for the links robertu, but they only form part of the solution. The Plane.GetDistanceToPoint is cool alternative to Vector3.Distance for some situations, but I still need to find the new point on the existing triangle. The math functions are interesting - can use for other problems, but in this instance the triangle point is unknown, I apologise if this was unclear, doesn't help when the image doesn't work! Unless I've misunderstood the function descriptors, the functions assume we are making a centre point on the triangle, which is not the case in this instance.
I have no trouble uploading a local image. Not sure why you hand problems. Your comment came after my solution below, so I'm not sure if you did not see it or if I missed something in your problem.
Note about GetDistanceToPoint() or the similar function in $$anonymous$$ath3D, all the ProjectPoinOnPlane() does to find the point on the plane is to first find the signed distance and then walk the reversed normal back to the plane back that distance to the plane.
Answer by robertbu · Mar 22, 2014 at 05:51 PM
Given the diagram, the calculation is just ProjectPontOnPlane() availabe in Math3D. The solution in Mathf3D is a bit 'wordy' with an unnecessary function call or two. Here is a single function version:
function ProjectPointOnPlane(planeNormal : Vector3 , planePoint : Vector3 , point : Vector3 ) : Vector3 {
planeNormal.Normalize();
var distance = -Vector3.Dot(planeNormal.normalized, (point - planePoint));
return point + planeNormal * distance;
}
Once you have p1 you can do this to get the distance:
var dist = Vector3.Distance(p0, p1);
Or if you look at the code I posted above, 'distance' in that code is the distance you are looking for. So if you pull the code out of function form and use it inline, you have the distance. Note it is the signed distance.
@robertbu, you can further reduce the square root overhead by removing the planeNormal.normalized use (just use planeNormal), because you're already calling planeNormal.Normalize() above that.
Time sync problems? been a long day ;) - I did not see your new code before posting, though did refresh. Will study the latest stuff, thanks.
@supernat - yep, as long at the planeNormal co$$anonymous$$g in is guaranteed to be normalized, you don't need the call. I pulled the function from code elsewhere where the inco$$anonymous$$g 'normal' was not normalized.
Thanks very much. That solved it for me. Yours extremely grateful... before this I'd visited sooo many websites and was feeling somewhat dejected! This is great. I've posted my test code here. Thanks Robertu and also supernat for the time saver
public class PointOnPlaneSnippet : $$anonymous$$onoBehaviour {
public GameObject goTestPos;
public GameObject spherePoint;
//$$anonymous$$odified ProjectPointOnPlane
Vector3 ProjectPointOnPlane(Vector3 planeNormal, Vector3 planePoint, Vector3 point, out float distance){
planeNormal.Normalize();
distance = -Vector3.Dot(planeNormal, (point - planePoint));
return point + planeNormal * distance;
}
// Update is called once per frame
void Update () {
$$anonymous$$esh mesh = transform.GetComponent<$$anonymous$$eshFilter>().mesh;
Vector3 planeNormal= mesh.normals[0]; //$$anonymous$$y test mesh only has one triangle, pick first vertex
Vector3 planePoint = mesh.vertices[0]; //Pick normal of vertex
Vector3 pointToProject = goTestPos.transform.position; //Use position of test GameObject
Vector3 transPlaneNormal= transform.TransformDirection (planeNormal); //Global coords
Vector3 transPlanePoint = transform.TransformPoint (planePoint); //Global coords
float distance; //distance from projection origin to point on triangle
Vector3 newPlanePoint = ProjectPointOnPlane(transPlaneNormal, transPlanePoint, pointToProject, out distance);
spherePoint.transform.position=newPlanePoint; //Test with location
Debug.DrawLine (pointToProject,newPlanePoint,Color.cyan); //Checking movement of test object, moves new point on plane
}
}
If someone could close this, that would be great. I don't seem to have the super powers to do so myself. I'm also unable to vote, though I have accepted the answer. Thanks.
Your answer
Follow this Question
Related Questions
Procedural Cylinder Generation 2 Answers
Get Vertices of Circle Facing Any Direction 1 Answer
How to build a perpendicular of a certain length for a segment rotated to some angle? 1 Answer
How to calculate a Vector3 point having three given Vector3 points and an angle of 90 degrees? 1 Answer
Solved | Rotating Object in Single Axis while staying Perpendicular to a Rotating Plane 1 Answer