IT Share you

3D에서 평면에 점을 투영하는 방법은 무엇입니까?

shareyou 2020. 12. 14. 21:04
반응형

3D에서 평면에 점을 투영하는 방법은 무엇입니까?


3D 점 (point_x, point_y, point_z)이 있고 점 좌표 (orig_x, orig_y, orig_z)와 단항 수직 벡터 (normal_dx)로 정의되는 (평면) 3D 공간의 2D 평면에 투영하고 싶습니다. , normal_dy, normal_dz).

어떻게 처리해야합니까?여기에 이미지 설명 입력


1) orig지점에서 관심 지점까지 벡터를 만듭니다 .

v = point-orig (in each dimension);

2) 단위 법선 벡터로 해당 벡터의 내적을 취하십시오 n.

dist = vx*nx + vy*ny + vz*nz; dist = 법선을 따라 점에서 평면까지의 스칼라 거리

3) 단위 법선 벡터에 거리를 곱하고 그 벡터를 점에서 뺍니다.

projected_point = point - dist*normal;

사진으로 편집 : 사진을 약간 수정했습니다. 빨간색은 v; vnormal= 파란색과 녹색의 길이 ( dist위). 파란색은 normal*dist. Green = blue * -1: planar_xyz를 찾으려면 시작 point하여 녹색 벡터를 추가합니다.

여기에 이미지 설명 입력


이것은 정말 쉽습니다. 당신이해야 할 일은 |_P에서 평면 까지 의 수직 (abbr here ) 거리를 찾은 다음 , 평면 법선 방향의 수직 거리만큼 다시 변환 하는 것 입니다. 결과는 번역 된 것이 비행기에 앉는 것입니다.P P

간단한 예를 들어 보겠습니다 (검사를 통해 확인할 수 있음).

n = (0,1,0) 및 P = (10,20, -5)를 설정합니다.

여기에 이미지 설명 입력

투영 된 점은 (10,10, -5) 여야합니다. 검사를 통해 Pproj가 평면에서 수직으로 10 단위라는 것을 알 수 있으며 평면에 있다면 y = 10이됩니다.

그렇다면이를 분석적으로 어떻게 찾을 수 있을까요?

평면 방정식은 Ax + By + Cz + d = 0입니다. 이 방정식이 의미하는 것은 "점 (x, y, z)이 평면에 있으려면 Ax + By + Cz + d = 0을 만족해야합니다" 입니다.

위에 그려진 평면에 대한 Ax + By + Cz + d = 0 방정식은 무엇입니까?

평면은 법선 n = (0,1,0)입니다. d는 평면에 이미 있는 테스트 포인트를 사용하여 간단히 찾을 수 있습니다 .

(0)x + (1)y + (0)z + d = 0

점 (0,10,0)은 평면에 있습니다. 위의 플러그를 꽂으면 d = -10이됩니다. 평면 방정식은 0x + 1y + 0z-10 = 0입니다 (단순화하면 y = 10이됩니다).

A nice interpretation of d is it speaks of the perpendicular distance you would need to translate the plane along its normal to have the plane pass through the origin.

Anyway, once we have d, we can find the |_ distance of any point to the plane by the following equation:

여기에 이미지 설명 입력

There are 3 possible classes of results for |_ distance to plane:

  • 0: ON PLANE EXACTLY (almost never happens with floating point inaccuracy issues)
  • +1: >0: IN FRONT of plane (on normal side)
  • -1: <0: BEHIND plane (ON OPPOSITE SIDE OF NORMAL)

Anyway,

여기에 이미지 설명 입력

Which you can verify as correct by inspection in the diagram above


This answer is an addition to two existing answers. I aim to show how the explanations by @tmpearce and @bobobobo boil down to the same thing, while at the same time providing quick answers to those who are merely interested in copying the equation best suited for their situation.

Method for planes defined by normal n and point o

This method was explained in the answer by @tmpearce.

Given a point-normal definition of a plane with normal n and point o on the plane, a point p', being the point on the plane closest to the given point p, can be found by:

1) p' = p - (n ⋅ (p - o)) * n

Method for planes defined by normal n and scalar d

This method was explained in the answer by @bobobobo.

Given a plane defined by normal n and scalar d, a point p', being the point on the plane closest to the given point p, can be found by:

2) p' = p - (np + d) * n

If instead you've got a point-normal definition of a plane (the plane is defined by normal n and point o on the plane) @bobobobo suggests to find d:

3) d = -no

and insert this into equation 2. This yields:

4) p' = p - (np - no) * n

A note about the difference

Take a closer look at equations 1 and 4. By comparing them you'll see that equation 1 uses n ⋅ (p - o) where equation 2 uses np - no. That's actually two ways of writing down the same thing:

5) n ⋅ (p - o) = np - no = np + d

One may thus choose to interpret the scalar d as if it were a 'pre-calculation'. I'll explain: if a plane's n and o are known, but o is only used to calculate n ⋅ (p - o), we may as well define the plane by n and d and calculate np + d instead, because we've just seen that that's the same thing.

Additionally for programming using d has two advantages:

  1. Finding p' now is a simpler calculation, especially for computers. Compare:
    • using n and o: 3 subtractions + 3 multiplications + 2 additions
    • using n and d: 0 subtractions + 3 multiplications + 3 additions.
  2. Using d limits the definition of a plane to only 4 real numbers (3 for n + 1 for d), instead of 6 (3 for n + 3 for o). This saves ⅓ memory.

It's not sufficient to provide only the plane origin and the normal vector. This does define the 3d plane, however this does not define the coordinate system on the plane.

Think that you may rotate your plane around the normal vector with regard to its origin (i.e. put the normal vector at the origin and "rotate").

You may however find the distance of the projected point to the origin (which is obviously invariant to rotation).

Subtract the origin from the 3d point. Then do a cross product with the normal direction. If your normal vector is normalized - the resulting vector's length equals to the needed value.

EDIT

A complete answer would need an extra parameter. Say, you supply also the vector that denotes the x-axis on your plane. So we have vectors n and x. Assume they're normalized.

The origin is denoted by O, your 3D point is p.

Then your point is projected by the following:

x = (p - O) dot x

y = (p - O) dot (n cross x)


Let V = (orig_x,orig_y,orig_z) - (point_x,point_y,point_z)

N = (normal_dx,normal_dy,normal_dz)

Let d = V.dotproduct(N);

Projected point P = V + d.N


I think you should slightly change the way you describe the plane. Indeed, the best way to describe the plane is via a vector n and a scalar c

(x, n) = c

The (absolute value of the) constant c is the distance of the plane from the origin, and is equal to (P, n), where P is any point on the plane.

So, let P be your orig point and A' be the projection of a new point A onto the plane. What you need to do is find a such that A' = A - a*n satisfies the equation of the plane, that is

(A - a*n, n) = (P, n)

Solving for a, you find that

a = (A, n) - (P, n) = (A, n) - c

which gives

A' = A - [(A, n) - c]n

Using your names, this reads

c = orig_x*normal_dx + orig_y*normal_dy+orig_z*normal_dz;
a = point_x*normal_dx + point_y*normal_dy + point_z*normal_dz - c;
planar_x = point_x - a*normal_dx;
planar_y = point_y - a*normal_dy;
planar_z = point_z - a*normal_dz;

Note: your code would save one scalar product if instead of the orig point P you store c=(P, n), which means basically 25% less flops for each projection (in case this routine is used many times in your code).


Let r be the point to project and p be the result of the projection. Let c be any point on the plane and let n be a normal to the plane (not necessarily normalised). Write p = r + m d for some scalar m which will be seen to be indeterminate if their is no solution. Since (p - c).n = 0 because all points on the plane satisfy this restriction one has (r - c).n + m(d . n) = 0 and so m = [(c - r).n ] / [ d . n ] 여기서 내적 (.)이 사용됩니다. 그러나 d . n = 0 솔루션이 없습니다. 예를 들어 dn 이 서로 직각 이면 솔루션을 사용할 수 없습니다.

참고 URL : https://stackoverflow.com/questions/9605556/how-to-project-a-point-onto-a-plane-in-3d

반응형