0

I have three datasets (numpy arrays) of coordinates (X, Y and X) representing a planar surface. I need to create a line that is perpendicular to the plane surface.

A visual representation of the coordinates in a coordinate system

I got the data from another file, because I can't share it easily with you, I created a random pandas dataset the code I used to generate the data surface is as following:

cor_CTV = pd.DataFrame(np.random.randint(0,100,size=(100, 3)), columns = list('xyz'))

linear_data = np.c_[cor_CTV["x"], cor_CTV["y"], cor_CTV["z"]]
mn = np.min(linear_data, axis=0)
mx = np.max(linear_data, axis=0)
X,Y = np.meshgrid(np.linspace(mn[0], mx[0], 20), np.linspace(mn[1], mx[1], 20))

XX = X.flatten()
YY = Y.flatten()

A = np.c_[linear_data[:,0], linear_data[:,1], np.ones(linear_data.shape[0])]
C,_,_,_ = scipy.linalg.lstsq(A, linear_data[:,2])
Z = C[0]*X + C[1]*Y + C[2]

I would be very grateful if anyone can help me.

theo lam
  • 25
  • 5
  • 3
    Hi, please create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) by including example X, Y, Z data. – tituszban Sep 20 '19 at 12:56

1 Answers1

3

You can use the cross product of the relative position of any two non-colinear points:

O = np.array([X[0][0], Y[0][0], Z[0][0]])   # Corner to be used as the origin

V1 = np.array([X[1][0], Y[1][0], Z[1][0]]) - O  # Relative vectors
V2 = np.array([X[0][1], Y[0][1], Z[0][1]]) - O

V1 = V1 / scipy.linalg.norm(V1)  # Normalise vectors
V2 = V2 / scipy.linalg.norm(V2)

# Take the cross product
perp = np.cross(V1, V2)

Example result:

[ 0.18336919 -0.0287231  -0.98260979]
tituszban
  • 4,797
  • 2
  • 19
  • 30
  • The two vectors relative to the corner of my surface are not perpendicular to each other. When I take the cross product of the two vectors it won't give me the vector perpendicular to the other two. – theo lam Sep 23 '19 at 13:38
  • Hi, the two vectors (`V1` and `V2`) do not have to be perpendicular. As long as they're not co-linear, perp (`V1 x V2`) will always be perpendicular to both. The two vectors define a plane, and the cross product is perpendicular to that plane. You can read more about [cross product](https://en.wikipedia.org/wiki/Cross_product) here. (The only effect `V1` and `V2` being at an angle other than 90° to each other has, is the length of the cross product) – tituszban Sep 23 '19 at 17:32
  • 1
    Thanks, I found the mistake I made. The scale of the axis in my figure weren't equal to each other. This is why my vectors didn't seem perpendicular to each other, while they actually were. Silly mistake, thanks – theo lam Sep 24 '19 at 06:46
  • Always happy to help! – tituszban Sep 24 '19 at 08:06