Determining (euler) orientation from 4 points / quad?

Tl;dr question: How can I derive the orientation of the upper and lower mid points respective of the other points? I only have vertex information, no direction information (other than world)

I have a quad with 4 points, such that:

Each point represents a vertex in world space. From that, I’m trying to derive the orientation of both the upper and lower mid point relative to the other points.

Each of the points can move independently - you could probably imagine this as P1 & P2 being your left/right shoulders and P3 & P4 being your left/right hip, e.g.

image

I’ve tried the following methods with pretty poor results:

  1. Derive the back, up and right vector and create a matrix:
MidLower = P4:Lerp(P2, 0.5)
Right = (P4 - P2).unit()
Up = (P1 - MidLower):Cross(P2 - MidLower).unit()
Look = Right:Cross(Up)

Orientation = CFrame.fromMatrix(Vector3.new(), Right, Up, -Look)
  1. Signed angle of each right, up and look vector relative to world axis
  2. Project into 2d space and derive 2d angles → euler angles

Does anyone have any other ideas as to how I might derive the orientation? I would greatly appreciate it

What exactly do you mean by orientation? It’s a 0-dimensional point, can you draw a vector from the midpoint to show us the orientation you’re trying to achieve?

Ah sorry, I was hoping my pictures were clear enough. I’ve followed the original post’s analogy of P1 + P2 and P3 + P4 being your shoulders/hips so you can get a feel for it IRL, but hopefully the following picture helps:

image

Ignore the other red points, but if you were to take the P1 → P4 points in the picture that represent the quad, with each point being a Vec3, I was hoping I could derive the back, look and right vec of the mid point(s) (drawn in orange here).

Hopefully that makes more sense?

You definitely could, just with some confusing math

For the LookVector, you can use cross product but on different points; so if you’re trying to get the bottom midpoint you will need to use P1 and P2

local vec1: Vector3 = midpoint - P1 --get the displacement vectors
local vec2: Vector3 = midpoint - P2
local lookVec: Vector3 = vec1:Cross(vec2) --if its inverted then just negate the vector

And then to get the UpVector, you will use the LookVector you just obtained and perform a cross product on it again with a point that’s on the same line as the midpoint; if its the bottom midpoint you would use P3 or P4

local upVec: Vector3 = lookVec:Cross(P3 or P4) --once again, if its inverted you can just negate the vector

And then from there, getting the RightVector should be self-explanatory

local rightVec: Vector3 = lookVec:Cross(upVec)