-3

I have a global coordinates system (X, Y, Z), and a triangle with points (A, B, C and Center). I know all coordinates of those points.

  1. I need to move global coordinates system from (0; 0; 0) to the triangle center, so that all the points: A, B, C and Center would have new coordinates where Z = 0. After that i need to know new coordinates of those points in the relation with new coordinates system. The orientation of new coordinate system is not important.
  2. Also, if there is a possibility to convert a 3D points (triangle points) to 2D plane without loosing its geometry (size). It shouldn’t be a projection to 2D plane.

>> A=[10.63307; -7.72528; 21.26636];
B=[4.06139; -12.49988; 21.26636];
C=[-6.57172; -20.22529; 13.14344];
Centr=[-4.38113; -13.48349; 18.55872];

>> V1=(B-A)/(norm(B-A))

V1 =

   -0.8090
   -0.5878
         0

>> V2=((C-A)-(dot((C-A),V1)*V1))/(norm((C-A)-(dot((C-A),V1)*V1)))

V2 =

    0.0000
   -0.0000
   -1.0000

>> V3=cross(V1,V2)

V3 =

    0.5878
   -0.8090
    0.0000

>> M=[V1,V2,V3]

M =

   -0.8090    0.0000    0.5878
   -0.5878   -0.0000   -0.8090
         0   -1.0000    0.0000

>> Anew=inv(M)*(A-Centr)

Anew =

  -15.5313
   -2.7076
    4.1666

>> Bnew=inv(M)*(B-Centr)

Bnew =

   -7.4083
   -2.7076
    4.1666

>> Cnew=inv(M)*(C-Centr)

Cnew =

    5.7350
    5.4153
    4.1666

This is what i got: From this

To this

  • 1
    this is a maths only question and has little to do with c++ or matlab (unless you need code for either of the two in which case you should show what you already tried) – 463035818_is_not_a_number Jul 26 '16 at 12:02
  • btw this is very basic geometry. z is normal to the triangle and the other two directions you simply pick to lie on the triangle. What is the problem? – 463035818_is_not_a_number Jul 26 '16 at 12:06
  • Set `Z` to `0` on all and you will get the conversion from 3D to 2D. And if you want to transform coordinates to a new (0,0) system which is at (2, 2) for example, then you need to subtract (2,2) from all and every other coordinate. Then the result is the new (0,0) system. Could you now please show some [MCVE]? – Khalil Khalaf Jul 26 '16 at 12:07
  • @FirstStep this does not necessarly map a triangle to a triangle (if two points differ only by their z coordinate). Also he mentioned that the size of the triangle should stay the same – 463035818_is_not_a_number Jul 26 '16 at 12:09
  • I think it's a very good question, and it can be useful to people who programmatically manipulate 3D coordinates, in C++ or Matlab (OpenGL, ...). – Ghislain Fourny Jul 26 '16 at 12:37
  • Which center is meant here (orthocenter, circumcenter, centroid...)? The `Center` specified does not seem to be on the ABC triangle's plane, which is why the z coordinates are not 0 in the new system. A quick check of `((B-A) x (C-A)).(P-A) ` should always give 0 for any point P on the plane. – Ghislain Fourny Jul 28 '16 at 11:46

1 Answers1

2

The problem can be expressed as finding the 3-by-3 matrix M such that the coordinates of a point P can be converted between the old coordinate system (P_old, 3 rows) and the new coordinate system (P_new, 3 rows). This is an affine transformation:

P_old = Center + M * P_new     (1)

The (matrix-vector) multiplication with M orientates it back to the old system, and adding Center's coordinates translates it back to the old origin.

The equation (1) can then be turned into:

P_new = M^{-1} * (P_old - Center)     (2)

where M^{-1} is the inverse of M, to compute the new coordinates from the old ones (the third row will have a 0 if the point belongs to the plane of the triangle).

The matrix M is made of the coordinates of the new basis in the old system, one basis vector in each column. One must now find such a basis.

This basis can be taken from (this is all pseudo-code):

  1. Renormalizing AB

           AB
    V1 = ______
        || AB ||
    
    • AB here is meant as the vector AB (with an arrow on top):

      |b_x - a_x|
      |b_y - a_y|
      |b_z - a_z|
      
    • || . || is the Euclidian norm (^2 means the square, not xor):

      || V || = sqrt(V_x^2 + V_y^2 + V_z^2)
      
  2. AC (also a vector, defined like AB), but minus its projection on V1 to make it orthogonal to V1, and renormalized (this will fail with a division by zero if the triangle is not really a triangle):

            AC - (AC.V_1) V1
    V2 = _______________________
         || AC - (AC.V_1) V1 ||
    
    • M.N is the scalar product:

      M.N = M_x * N_x + M_y * N_y + M_z * N_z
      
    • (AC.V_1) V1 is simply the product of a scalar, (AC.V_1), with a vector, V1

  3. A third vector that can be taken as the cross product to get a Cartesian coordinate system:

    V3 = V1 x V2
    
    • The cross product is defined as:

                |V1_y*V2_z - V1_z*V2_y|
      V1 x V2 = |V1_z*V2_x - V1_x*V2_z|
                |V1_x*V2_y - V1_y*V2_x|
      

Then M can be taken as |V1 V2 V3| (each Vx is on 3 rows) and, then its inverse computed to use formula (2).

This transformation (with the inverted M) should both generate new coordinates for the points on the plane of the triangle that have 0 on the third axis (which makes it 2D-coordinates on that plane), and preserve the size in terms of Euclidian norm.

Ghislain Fourny
  • 6,423
  • 1
  • 27
  • 33
  • Where `x^2` means `Pow(x, 2)` and not `x xor 2` – Khalil Khalaf Jul 26 '16 at 12:26
  • Yes, thank you for the precision, @FirstStep. I have edited the answer. – Ghislain Fourny Jul 26 '16 at 12:31
  • Thank you, i tried your solution and mannaged to get "Z" coordinates of all points exacelly equal, but not 0. Also, my triangle changed. Maybe i did something wrong? I edited my question and added Matlab code and some pictures. – supporteriukas Jul 27 '16 at 12:18
  • `ACV1=AC(1)*V1(1)+AC(2)*V1(2)+AC(3)+V1(3)`: the last `+` should be a `*` :-) – Ghislain Fourny Jul 27 '16 at 23:04
  • I changed + to * in ACV1=AC(1)*V1(1)+AC(2)*V1(2)+AC(3)*V1(3), still "z" coordinates ar not 0, and my triangle changes it's shape. What i do wrong? I edited my code and a picture representing the result. – supporteriukas Jul 28 '16 at 07:36
  • Hi supporteriukas, in `AC1e=AC1(1)^2+AC1(2)^2+AC1(3)^2` the `sqrt()` is missing, so that V2 is not normalized. V2 should be (0,0,-1). – Ghislain Fourny Jul 28 '16 at 08:08
  • I found my mistakes, and this time did it correctly. Everything works perfectly. Thanks, this was very helpfull – supporteriukas Jul 28 '16 at 12:03
  • That's good to hear! It would be great if you could update your question with the working snippet, stating that this is a working implementation, for future reference. Thanks a lot! – Ghislain Fourny Jul 28 '16 at 12:43