A quick foray into math ... reality check...
a sub-ent has to be at P with a new orientation
... the subentity notation requires (a,b,c,d,e,f,g) where (a,b,c) is the translation and (d,e,f,g) = Q is the quaternion rotation. Q can be derived by considering the new orientation as a rotation of angle T about vector r which is perpendicular to start and finish orientations.
set up the subent so that one face is at o=(0,0,0) with normal k=(0,0,1) ... at the origin, pointing along z axis. Work out the change by selecting this reference face after the shift. Wings3D tells you the center (x,y,z).
(a,b,c)=(x,y,z) ... fine.
If I have the start and end normals, then I have the rotation, vis:
if n = (h,l,m) is the end normal and o is the start then
n = Ro = YXo where R=YX is the rotation matrix - X and Y are the matrices corresponding to rotations about (1,0,0) and (0,1,0) respectively.
Or the short way:
k^n=r (rotation vector is the cross-product of the two) but k is a unit basis so:
r = (l,h,0)
n.k = s = |n||k|cos(T) => T = arccos(s/|n|)
So the problem is to find n.
For that I need three points on the plane.
Choose P as the center; choose R and S from vertices in vertex mode. The PR and PS are vectors in the surface of the face. Thus PR^PS is a normal to the face. The trick is making sure it is an outward normal.
I should be able to do the math using
GNU Octave.
Code: Select all
% Manually add in the needed data
% The final center and two edge-points on the reference face.
% choose R and S so that left-hand-rule R --> S creates an outward normal
P = (input);
R = (input);
S = (input);
% computes the rotation vector and angle
u=R-P; v=S-P; n=u*v;
r = (n(2),n(1),0);
T = arccos( n(3)/length(n) );
% Resulting quaternion
Q = ( cos(t/2), r.sin(T/2) )