Calculation of Point3Ds cuboid around a line

There are two Point3D ( A and B ), and I want to calculate the cuboid points (a, b, c ... h) surrounding the line between A and B as a body:

enter image description here

There is one degree of freedom, the angle of the cuboid, because it can rotate around the line AB . I'm not sure if this is a problem.

I tried to calculate a vector normal to AB , D , and then the cross product of ABAD = E. In the code, C is A - B so its the offset parallel to AB .

I normalized these three vectors ( C , D and E ) and multiplied them by the offset to add / subtract them from A and B. This is not quite working yet.

EDIT: see ja72 code for solution

i also implemented a method for finding a normal vector:

double ax = Vector3D.AngleBetween(E, new Vector3D(1, 0, 0)); double ay = Vector3D.AngleBetween(E, new Vector3D(0, 1, 0)); double az = Vector3D.AngleBetween(E, new Vector3D(0, 0, 1)); ax = Math.Abs(ax - 90); ay = Math.Abs(ay - 90); az = Math.Abs(az - 90); if (ax <= ay & ax <= az) { n = Vector3D.CrossProduct(E, new Vector3D(1, 0, 0)); } else if (az <= ax && az <= ay) { n = Vector3D.CrossProduct(E, new Vector3D(0, 0, 1)); } else { n = Vector3D.CrossProduct(E, new Vector3D(0, 1, 0)); } n = normalize(n); 
+6
source share
2 answers

You need two direction vectors. One is along the line AB given

 Vector3D e = Normalize(BA) 

and one to determine the upward direction for the cross section. This can be specified or it can be calculated using the following algorithm (with preference to + y)

 if( eX != 0 || eZ != 0 ) { // choose direction perpendicular to line closest to +y direction Vector3D n = [-eX*eY, eX*e.X+eZ*eZ, -eZ*eY]; } else { // if line along +y already then choose +z for up vector Vector3D n = [ 0, 0, 1]; } 

Now you can calculate the 3rd direction to form a coordinate system

 Vector3D k = Normalize( Cross(e,n) ) 

And you collect a 3 × 3 rotation matrix that converts local coordinates to world coordinates using

  | kX nX eX | R = | kY nY eY | | kZ nZ eZ | 

The local coordinate has a direction along the line as + z such that

 Point3D a = A + R*[w,h,0] Point3D b = A + R*[-w,h,0] Point3D c = A + R*[w,-h,0] Point3D d = A + R*[-w,-h,0] Point3D e = B + R*[w,h,0] Point3D f = B + R*[-w,h,0] Point3D g = B + R*[w,-h,0] Point3D h = B + R*[-w,-h,0] 

where R*[x,y,z] denotes the multiplication of the matrix vector, w and h are the width and height of the rectangular section, and A , B are the position vectors of point A and B. The addition between the vectors is element by element.


I checked the code in my own code and it works. vec3 is an alias for a 3D vector, mat3 is an alias for a 3 × 3 matrix.

Cube

  vec3 u=(BA).Normalized(); vec3 n = vec3.O; if(Math.Abs(uX)<=Math.Abs(uY)&&Math.Abs(uX)<=Math.Abs(uZ)) { n=new vec3(uY*u.Y+uZ*uZ, -uY*uX, -uZ*uX); } else if(Math.Abs(uY)<=Math.Abs(uX)&&Math.Abs(uY)<=Math.Abs(uZ)) { n=new vec3(-uX*uY, uX*u.X+uZ*uZ, -uZ*uY); } else if(Math.Abs(uZ)<=Math.Abs(uX)&&Math.Abs(uZ)<=Math.Abs(uY)) { n=new vec3(-uX*uZ, -uY*uZ, uX*u.X+uY*uY); } vec3 v=n.Cross(u); mat3 R=mat3.Combine(v, n, u); var a=A+R*new vec3(wt, ht, 0); var b=A+R*new vec3(-wt, ht, 0); var c=A+R*new vec3(wt, -ht, 0); var d=A+R*new vec3(-wt, -ht, 0); var e=B+R*new vec3(wt, ht, 0); var f=B+R*new vec3(-wt, ht, 0); var g=B+R*new vec3(wt, -ht, 0); var h=B+R*new vec3(-wt, -ht, 0); 
+3
source

I cannot give you the real part of the code, but I can give you an idea.

Well, suppose you already have the correct cuboid. I mean, it has the correct width and height. Lets find it on the xy plane. After that you need to shift it to the center (minus the displacement vector). The last thing is to rotate it according to your turn of the line.

Again:

  • Create a cuboid and find it on the xy plane
  • Move it according to your offsets.
  • Rotate it according to the rotation of the line.

You can use matrix multiplication to achieve these transformations.

+2
source

All Articles