topical media & game development
basic-visual-03-plucker.c
? /
basic-visual-03-plucker.c
// ------------------------------------------------------------------------
// This program is complementary material for the book:
//
// Frank Nielsen
//
// Visual Computing: Geometry, Graphics, and Vision
//
// ISBN: 1-58450-427-7
//
// Charles River Media, Inc.
//
//
// All programs are available at www.charlesriver.com/visualcomputing/
//
// You may use this program for ACADEMIC and PERSONAL purposes ONLY.
//
//
// The use of this program in a commercial product requires EXPLICITLY
// written permission from the author. The author is NOT responsible or
// liable for damage or loss that may be caused by the use of this program.
//
// Copyright (c) 2005. Frank Nielsen. All rights reserved.
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// File: plucker.cpp
//
// Description: Manipulating Plucker coordinates for line/point incidence,
// line/line intersection tests, etc.
// ------------------------------------------------------------------------
include <stdafx.h>
include <fstream.h>
include <math.h>
//using namespace std;
// Inhomogeneous coordinates
class Point3D{public: double x,y,z;
Point3D()
{x=y=z=0.0;}
Point3D(double xx, double yy, double zz)
{x=xx;y=yy;z=zz;}
friend ostream & operator << (ostream & os, const Point3D p)
{
os<<"["<<p.x<<","<<p.y<<","<<p.z<<"]";
return os;
}
};
class Plucker{
public: double c[6];
Plucker::Plucker(Point3D p1, Point3D p2)
{
c[0]=p2.x-p1.x;
c[1]=p2.y-p1.y;
c[2]=p2.z-p1.z;
c[3]=p1.y*p2.z-p1.z*p2.y;
c[4]=p2.x*p1.z-p1.x*p2.z;
c[5]=p1.x*p2.y-p2.x*p1.y;
}
friend ostream & operator << (ostream & os, const Plucker l)
{
os<<"Plucker Line:["<< l.c[0] <<"," << l.c[1] <<","<<l.c[2]<<","<<l.c[3]<<","<<l.c[4]<<","<<l.c[5]<<"]";
return os;
}
}; // Homogeneous coordinates
double PluckerDotProduct(Plucker l1, Plucker l2)
{
double s=0;
for(int i=0;i<6;i++)
s+=l1.c[i]*l2.c[(3+i)%6];
return s;
}
// The same primitive rewritten differently
double PluckerLineIntersect(Plucker l1, Plucker l2)
{
double s;
s=l1.c[0]*l2.c[3]+l2.c[0]*l1.c[3] +\
l1.c[1]*l2.c[4]+l2.c[1]*l1.c[4]+\
l1.c[2]*l2.c[5]+l2.c[2]*l1.c[5];
return s;
}
double PluckerPointOnLine(Plucker l, Point3D p)
{
double rx, ry, rz, rw;
rx=l.c[3]*p.x+l.c[4]*p.y+l.c[5]*p.z;
ry=-l.c[2]*p.y+l.c[1]*p.z+l.c[3];
rz=-l.c[2]*p.x+l.c[0]*p.z-l.c[4];
rw=-l.c[1]*p.x+l.c[0]*p.y+l.c[5];
//cout<<rx<<" "<<ry<< " "<<rz<<" "<<rw<<" "<<endl;
return fabs(rx)+fabs(ry)+fabs(rz)+fabs(rw);
}
inline double drand() {return rand()/(double)RAND_MAX;}
int _tmain(int argc, _TCHAR* argv[])
{
srand(2555);
Point3D p(drand(),drand(),drand()), q(drand(),drand(),drand()),r, s(drand(),drand(),drand());
double lambda=0.2;
cout<<"Visual Computing: Geometry, Graphics, and Vision (ISBN:1-58450-427-7)"<<endl;
cout<<"Demo program\n\n"<<endl;
r.x=p.x*lambda+(1-lambda)*q.x;
r.y=p.y*lambda+(1-lambda)*q.y;
r.z=p.z*lambda+(1-lambda)*q.z;
// If you replace r by this code, it is highly likely not to intersect anymore
//r=Point3D(drand(),drand(),drand());
Plucker l1(p,q), l2(r,s);
cout<<"Plucker coordinates demo.\n\n"<<endl;
cout<<"Build the line passing through point P="<<p<<" and Q="<<q<<endl;
cout<<"Plucker coordinates of the line: L1="<<l1<<endl;
cout<<"\n\nBuild the line passing through point R="<<r<<" and S="<<s<<endl;
cout<<"Plucker coordinates of the line:"<<l2<<endl;
cout<<"Those lines should be contained in a same plane."<<endl;
cout<<"The dot product of the corresponding Plucker vectors are:"<<PluckerDotProduct(l1,l2)<<endl;
cout<<"It should be exactly zero if there were no numerical imprecisions"<<endl;
cout<<"\n\nLines L1 and L2 should intersect:"<<PluckerLineIntersect(l1,l2)<<endl;
cout<<"It should be exactly zero if there were no numerical imprecisions"<<endl;
cout<<"\n\nCheck that point R is on line L1:"<<PluckerPointOnLine(l1,r)<<endl;
cout<<"It should be exactly zero if there were no numerical imprecisions"<<endl;
cout<<"\n\nPress Return to exit."<<endl;
char line[256];
gets(line);
return 0;
}
(C) Æliens
20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.