// graph3d.cpp --> a little bit of the libary of 3DRender engine
#include <math.h>
#include <stdio.h>
#include <point3.h>
// 1997-1998
struct face_struct {
float kb,kc,kr;
float dist;
Point3 A,B,C,M;
};
Matrix3 I(1,0,0,
0,1,0,
0,0,1);
Point2 Origin;
Point3 u;
Point3 Position,Target;
Point3 o(0,0,0),i(1,0,0),j(0,1,0),k(0,0,1);
Point3 a,b,c;
float teta,fi;
float Zoom,focal,radius;
class Matrix3;
class Point3;
void look(float,float,float);
void camera_rotation(float,float,float);
void init3d(void);
void Real(void);
void Axono(void);
void origin(int,int);
int Xp(Point3);
int Yp(Point3);
float delta(Point3);
void DoProjection(Point3,Point2 &);
int Detect_Face3D(int,int,Point3,Point3,Point3,float&,float&,float&);
//void Get_Info_Face3D(float,float,Point3,Point3,Point3,face_struct&);
int Detect_Face2D(int xp,int yp,Point2 A,Point2 B,Point2 C);
int Detect_Fast_Face3D(int,int,Point3,Point3,Point3,float&,float&,float&);
float delta(Point3 m) {
return(c.x*(m.x-Position.x)+c.y*(m.y-Position.y)+c.z*(m.z-Position.z)+radius-focal);
}
int Xp(Point3 m) {
float r = Zoom*focal/(c.x*(m.x-Position.x)+c.y*(m.y-Position.y)+c.z*(m.z-Position.z)+radius-focal);
return(r*(b.x*(m.x-Position.x)+b.y*(m.y-Position.y)+b.z*(m.z-Position.z))+Origin.x);
}
int Yp(Point3 m) {
float r = Zoom*focal/(c.x*(m.x-Position.x)+c.y*(m.y-Position.y)+c.z*(m.z-Position.z)+radius-focal);
return(r*(a.x*(m.x-Position.x)+a.y*(m.y-Position.y)+a.z*(m.z-Position.z))+Origin.y);
}
void DoProjection(Point3 m,Point2 &p) {
float r= Zoom*focal/(c.x*(m.x-Position.x)+c.y*(m.y-Position.y)+c.z*(m.z-Position.z)+radius-focal);
p.x = (long) r*(b.x*(m.x-Position.x)+b.y*(m.y-Position.y)+b.z*(m.z-Position.z))+Origin.x;
p.y = (long) r*(a.x*(m.x-Position.x)+a.y*(m.y-Position.y)+a.z*(m.z-Position.z))+Origin.y;
}
void Real(void) { focal=10; }
void Axono(void) { focal=1E5; Position=Point3(0,0,0);}
void look(float t,float f,float k) {
teta=t;fi=f;Zoom=k;
a = Point3(cos(t)*cos(f),cos(t)*sin(f),-sin(t));
b = Point3(-sin(f),cos(f),0.0);
c = Point3(-sin(t)*cos(f),-sin(t)*sin(f),-cos(t)); }
void camera_rotation(float fx,float fy,float fz) {
float l1,l2;
l1=cos(fz)*sin(fy);
l2=sin(fz)*sin(fy);
c.x=cos(fz)*cos(fy);
c.y=-sin(fz)*cos(fy);
c.z=-sin(fy);
b.x=-l1*sin(fx)+sin(fz)*cos(fx);
b.y=l2*sin(fx)+cos(fz)*cos(fx);
b.z=-cos(fy)*sin(fx);
a.x=l1*cos(fx)+sin(fz)*sin(fx);
a.y=-l2*cos(fx)+cos(fz)*sin(fx);
a.z=cos(fy)*cos(fx);
}
void origin(long x,long y) { Origin=Point2(x,y);}
void init3d(void) {
Origin=Point2(320,240);
teta=M_PI/3;fi=M_PI/3;
Real();
look(teta,fi,1);
focal=12;radius=100;
Position=Point3(0,0,0);
Zoom = 10;
}
int Test_k(float k) {
if ((k>=0) && (k<=1)) return 1; else return 0;}
int Detect_Face3D(int x,int y,Point3 A,Point3 B,Point3 C,float& kr,float& kb,float& kc) {
Point3 AB,AC,L,V;
float det;
float xp = -(x-Origin.x)/Zoom;
float yp = -(y-Origin.y)/Zoom;
AB=B-A;AC=C-A;
V = xp*b+yp*a-focal*c;
L = Position-radius*c+focal*c-A;
det = V.x*(AB.y*AC.z-AC.y*AB.z)-AB.x*(V.y*AC.z-AC.y*V.z)+
AC.x*(V.y*AB.z-AB.y*V.z);
if (det==0) return 0; else {
kb = (V.x*(L.y*AC.z-AC.y*L.z)-L.x*(V.y*AC.z-AC.y*V.z)+
AC.x*(V.y*L.z-L.y*V.z))/det;
if (!(Test_k(kb))) return 0; else {
kc = (V.x*(AB.y*L.z-L.y*AB.z)-AB.x*(V.y*L.z-L.y*V.z)+
L.x*(V.y*AB.z-AB.y*V.z))/det;
if (!(Test_k(kc))) return 0; else {
if (kb+kc>1) return 0; else {
kr = (L.x*(AB.y*AC.z-AC.y*AB.z)-AB.x*(L.y*AC.z-AC.y*L.z)+
AC.x*(L.y*AB.z-AB.y*L.z))/det;
if (kr<0) return 0; else return 1;
}}}}
}
/*void Get_Info_Face3D(float xp,float yp,Point3 A,Point3 B,Point3 C,face_struct& INFO) {
Point3 AB,AC,L,V;
float det;
AB=B-A;AC=C-A;
V = xp*b+yp*a-focal*c;
L = Position-radius*c+focal*c-A;
det = V.x*(AB.y*AC.z-AC.y*AB.z)-AB.x*(V.y*AC.z-AC.y*V.z)+
AC.x*(V.y*AB.z-AB.y*V.z);
INFO.kb = (V.x*(L.y*AC.z-AC.y*L.z)-L.x*(V.y*AC.z-AC.y*V.z)+
AC.x*(V.y*L.z-L.y*V.z))/det;
INFO.kc = (V.x*(AB.y*L.z-L.y*AB.z)-AB.x*(V.y*L.z-L.y*V.z)+
L.x*(V.y*AB.z-AB.y*V.z))/det;
INFO.kr = (L.x*(AB.y*AC.z-AC.y*AB.z)-AB.x*(L.y*AC.z-AC.y*L.z)+
AC.x*(L.y*AB.z-AB.y*L.z))/det;
INFO.dist = - INFO.kr*norm(V);
INFO.A = A;INFO.B = B;INFO.C = C;
INFO.M = INFO.kb*AB+INFO.kc*AC+A;
}
*/
/*
int Detect_Face2D(int xp,int yp,Point2 A,Point2 B,Point2 C) {
Point2 AB,AC,AP;
float kb,kc,det;
AB.x=B.x-A.x;AB.y=B.y-A.y;
AC.x=C.x-A.x;AC.y=C.y-A.y;
AP.x=xp-A.x;AP.y=yp-A.y;
det=AB.x*AC.y-AC.x*AB.y;
if (det==0) return 0; else {
kb =(AP.x*AC.y-AC.x*AP.y)/det;
if ((kb>1) || (kb<0)) return 0; else {
kc=(AB.x*AP.y-AP.x*AB.y)/det;
if ((kc>1) || (kc<0)) return 0; else {
if (kb+kc>1) return 0; else return 1;
}}}
}
*/
int Detect_Face2D(int xp,int yp,Point2 A,Point2 B,Point2 C) {
Point2 AB,AC,AP;
long kb,kc,det;
AB.x=B.x-A.x;AB.y=B.y-A.y;
AC.x=C.x-A.x;AC.y=C.y-A.y;
AP.x=xp-A.x;AP.y=yp-A.y;
det=AB.x*AC.y-AC.x*AB.y;
if (det==0) return 0; else {
if (det>0) {
kb =(AP.x*AC.y-AC.x*AP.y);
if ((kb>det) || (kb<0)) return 0; else {
kc=(AB.x*AP.y-AP.x*AB.y);
if ((kc>det) || (kc<0)) return 0; else {
if (kb+kc>det) return 0; else return 1;
}}
} else {
kb =(AP.x*AC.y-AC.x*AP.y);
if ((kb<det) || (kb>0)) return 0; else {
kc=(AB.x*AP.y-AP.x*AB.y);
if ((kc<det) || (kc>0)) return 0; else {
if (kb+kc<det) return 0; else return 1;
}}
}
}
}
int Detect_Fast_Face3D(int xp,int yp,Point3 A,Point3 B,Point3 C,float& kr,float& kb,float& kc) {
Point2 a,b,c;
DoProjection(A,a);DoProjection(B,b);DoProjection(C,c);
if (Detect_Face2D(xp,yp,a,b,c)) { Detect_Face3D(xp,yp,A,B,C,kr,kb,kc);return 1;}
else return 0;
};
Aucun commentaire:
Enregistrer un commentaire