On 15/06/2013 at 06:47, xxxxxxxx wrote:
So far so good except for one thing. Transforming the calculated circle points from a local Z-plane ( Vector(radius+Cos(angle), radius*Sin(angle), 0.0)) to the local plane representing the negative surface normal (translated away from the surface for ray collision) is resulting in elliptical circles. This is either a skewing in the matrix or the rotation (axis-angle) isn't correct. Uncertain which is the cause. All vectors are in local space for the object.
Here is my code (and some alternatives which show the same issue) :
Vector ray_dir = !(res.f_normal);
// - Move the ray system far away from the surface, orient it and put it into object space
// Rodrigues method
Vector pnormal = Vector(0.0,0.0,1.0);
// - invert normal to point at surface not away from it
ray_dir = -ray_dir;
Vector axis = !(pnormal%ray_dir);
Matrix pmat;
pmat.v1 = Vector(0.0, -axis.z, axis.y);
pmat.v2 = Vector(axis.z, 0.0, -axis.x);
pmat.v3 = Vector(-axis.y, axis.x, 0.0);
Real angle = ACos(pnormal*ray_dir);
pmat = unitMatrix + Sin(angle)*pmat + (1.0-Cos(angle))*pmat*pmat;
// Quaternion method
/*
Quaternion q;
q.SetAxis(!(pnormal%ray_dir), ACos(pnormal*ray_dir));
Matrix pmat = q.GetMatrix();
*/
// Axis-Angle method
//Matrix pmat = RotAxisToMatrix(!(pnormal%ray_dir), ACos(pnormal*ray_dir));
//pmat.Normalize();
pmat.off = res.hitpos+(ray_dir*-50000.0);
Real radius = (Real)data.GetLong(TOOLHDRLS_RADIUS);
Real dangle = 0.1745329251994329;
Vector fp;
Bool drawfp = FALSE;
bd->LineStripBegin();
// - First point
pnormal = pmat * Vector(radius*Cos(0.0), radius*Sin(0.0), 0.0);
if (m_pDrawCollider->Intersect(pnormal, ray_dir, 100000.0) && m_pDrawCollider->GetNearestIntersection(&res))
{
bd->LineStrip(res.hitpos, hicolor, NOCLIP_D|NOCLIP_Z);
fp = res.hitpos;
drawfp = TRUE;
}
for (LONG i = 1L; i != 36L; ++i, dangle += 0.1745329251994329)
{
pnormal = pmat * Vector(radius*Cos(dangle), radius*Sin(dangle), 0.0);
if (m_pDrawCollider->Intersect(pnormal, ray_dir, 100000.0) && m_pDrawCollider->GetNearestIntersection(&res))
bd->LineStrip(res.hitpos, hicolor, NOCLIP_D|NOCLIP_Z);
}
// - Back to first point
if (drawfp) bd->LineStrip(fp, hicolor, NOCLIP_D|NOCLIP_Z);
bd->LineStripEnd();