code of Liang-Barsky Line Clipping in opengl
base on my <<computer grapgics>>'s code
You can find guide of Liang-Barsky line clipping everywhere ,read them for details...
I found that Liang is the only Chinese talked by every computer graphic book. IM LOOKING FORWARD THERE WILL BE MORE LIANGS......
下面是 liang barsky 3d线段裁减的java代码,用的是定点数
liang barsky 3D line clipping, based on cldc1 (no float but fixed point)(code)
base on my <<computer grapgics>>'s code
typedef
struct
dcPttype
{
float x;
float y;
} dcPt;
typedef struct wcPt2type {
float x;
float y;
} wcPt2;
#define ROUND(a) ((int)(a+0.5))
#define TRUE 1
#define FALSE 0
int clipTest( float p, float q, float * u1, float * u2)
{
float r;
int retVal=TRUE;
if(p<0.0)
{
r=q/p;
if(r>*u2)
retVal=FALSE;
else if(r>*u1)
*u1=r;
}
else
if(p>0.0)
{
r=q/p;
if(r<*u1)
retVal=FALSE;
else if(r<*u2)
*u2=r;
}
else
if(q<0.0)
retVal=FALSE;
return (retVal);
}
void clipLine(dcPt winMin,dcPt winMax,wcPt2 p1,wcPt2 p2)
{
float u1=0.0f,u2=1.0f,dx=p2.x-p1.x,dy;
if(clipTest(-dx,p1.x-winMin.x,&u1,&u2)&&(choice>2))
{
if(clipTest(dx,winMax.x-p1.x,&u1,&u2))
{
dy=p2.y-p1.y;
if(clipTest(-dy,p1.y-winMin.y,&u1,&u2))
if(clipTest(dy,winMax.y-p1.y,&u1,&u2))
{
if(u2<1.0)
{
p2.x=p1.x+u2*dx;
p2.y=p1.y+u2*dy;
}
if(u1>0.0)
{
p1.x+=u1*dx;
p1.y+=u1*dy;
}
//draw the clipped line...
glColor3f(1,1,1);
glBegin(GL_LINES);
glVertex3f(ROUND(p1.x), ROUND(p1.y), 0.0);
glVertex3f(ROUND(p2.x), ROUND(p2.y), 0.0);
glEnd();
}
}
}
}
float x;
float y;
} dcPt;
typedef struct wcPt2type {
float x;
float y;
} wcPt2;
#define ROUND(a) ((int)(a+0.5))
#define TRUE 1
#define FALSE 0
int clipTest( float p, float q, float * u1, float * u2)
{
float r;
int retVal=TRUE;
if(p<0.0)
{
r=q/p;
if(r>*u2)
retVal=FALSE;
else if(r>*u1)
*u1=r;
}
else
if(p>0.0)
{
r=q/p;
if(r<*u1)
retVal=FALSE;
else if(r<*u2)
*u2=r;
}
else
if(q<0.0)
retVal=FALSE;
return (retVal);
}
void clipLine(dcPt winMin,dcPt winMax,wcPt2 p1,wcPt2 p2)
{
float u1=0.0f,u2=1.0f,dx=p2.x-p1.x,dy;
if(clipTest(-dx,p1.x-winMin.x,&u1,&u2)&&(choice>2))
{
if(clipTest(dx,winMax.x-p1.x,&u1,&u2))
{
dy=p2.y-p1.y;
if(clipTest(-dy,p1.y-winMin.y,&u1,&u2))
if(clipTest(dy,winMax.y-p1.y,&u1,&u2))
{
if(u2<1.0)
{
p2.x=p1.x+u2*dx;
p2.y=p1.y+u2*dy;
}
if(u1>0.0)
{
p1.x+=u1*dx;
p1.y+=u1*dy;
}
//draw the clipped line...
glColor3f(1,1,1);
glBegin(GL_LINES);
glVertex3f(ROUND(p1.x), ROUND(p1.y), 0.0);
glVertex3f(ROUND(p2.x), ROUND(p2.y), 0.0);
glEnd();
}
}
}
}
I found that Liang is the only Chinese talked by every computer graphic book. IM LOOKING FORWARD THERE WILL BE MORE LIANGS......
下面是 liang barsky 3d线段裁减的java代码,用的是定点数
liang barsky 3D line clipping, based on cldc1 (no float but fixed point)(code)
private
static
boolean
clipTest(
int
fp_p,
int
fp_q,
int
[] fp_u)
{
int fp_r;
boolean retVal=true;
if(fp_p<fp_0){
fp_r=MathFP.div(fp_q,fp_p);
if(fp_r>fp_u[1])
retVal=false;
else
if(fp_r>fp_u[0])
fp_u[0]=fp_r;
} else
if(fp_p>fp_0){
fp_r=MathFP.div(fp_q,fp_p);
if(fp_r<fp_u[0])
retVal=false;
else if(fp_r<fp_u[1])
fp_u[1]=fp_r;
} else
if(fp_q<fp_0)
retVal=false;
return retVal;
}
/**
*the default clip plane is from -1 to 1,at x, y
*/
public static void clipLine2DTest( int fp_x1, int fp_y1, int fp_x2, int fp_y2 ) {
int [] fp_u=new int[2];
fp_u[0]=fp_0;
fp_u[1]=MathFP.toFP(1);
int fp_dx=fp_x2-fp_x1;
int fp_dy;
int fp_winMin=MathFP.toFP(-1);
int fp_winMax=MathFP.toFP(1);
if(clipTest(-fp_dx, fp_x1-fp_winMin, fp_u))
if(clipTest(fp_dx, fp_winMax-fp_x1, fp_u)){
fp_dy=fp_y2-fp_y1;
if(clipTest(-fp_dy, fp_y1-fp_winMin, fp_u))
if(clipTest(fp_dy, fp_winMax-fp_y1, fp_u)){
if(fp_u[1] < fp_winMax){
fp_x2 = fp_x1 + MathFP.mul(fp_u[1] , fp_dx);
fp_y2 = fp_y1 + MathFP.mul(fp_u[1] , fp_dy);
}
if(fp_u[0] > fp_winMin){
fp_x1 += MathFP.mul(fp_u[0] , fp_dx);
fp_y1 += MathFP.mul(fp_u[0] , fp_dy);
}
System.out.println("Clipped results:");
System.out.print(MathFP.toString(fp_x1)+", ");
System.out.print(MathFP.toString(fp_y1)+", ");
System.out.print(MathFP.toString(fp_x2)+", ");
System.out.println(MathFP.toString(fp_y2)+", ");
}
}
}
/**
*the default clip plane is from -1 to 1, at x, y z
*/
public static void clipLine3DTest( int fp_x1, int fp_y1, int fp_z1, int fp_x2, int fp_y2 , int fp_z2) {
int [] fp_u=new int[2];
fp_u[0]=fp_0;
fp_u[1]=MathFP.toFP(1);
int fp_dx=fp_x2-fp_x1;
int fp_dy;
int fp_dz;
int fp_winMin=MathFP.toFP(-1);
int fp_winMax=MathFP.toFP(1);
if(clipTest(-fp_dx, fp_x1-fp_winMin, fp_u))
if(clipTest(fp_dx, fp_winMax-fp_x1, fp_u)){
fp_dy=fp_y2-fp_y1;
if(clipTest(-fp_dy, fp_y1-fp_winMin, fp_u))
if(clipTest(fp_dy, fp_winMax-fp_y1, fp_u)){
fp_dz=fp_z2-fp_z1;
if(clipTest(-fp_dz, fp_z1-fp_winMin, fp_u))
if(clipTest(fp_dz, fp_winMax-fp_z1, fp_u)){
if(fp_u[1] < fp_winMax){
fp_x2 = fp_x1 + MathFP.mul(fp_u[1] , fp_dx);
fp_y2 = fp_y1 + MathFP.mul(fp_u[1] , fp_dy);
fp_z2 = fp_z1 + MathFP.mul(fp_u[1] , fp_dz);
}
if(fp_u[0] > fp_winMin){
fp_x1 += MathFP.mul(fp_u[0] , fp_dx);
fp_y1 += MathFP.mul(fp_u[0] , fp_dy);
fp_z1 += MathFP.mul(fp_u[0] , fp_dz);
}
System.out.println("Clipped results:");
System.out.print(MathFP.toString(fp_x1)+", ");
System.out.print(MathFP.toString(fp_y1)+", ");
System.out.print(MathFP.toString(fp_z1)+", ");
System.out.print(MathFP.toString(fp_x2)+", ");
System.out.print(MathFP.toString(fp_y2)+", ");
System.out.println(MathFP.toString(fp_z2)+", ");
}
}
}
}
int fp_r;
boolean retVal=true;
if(fp_p<fp_0){
fp_r=MathFP.div(fp_q,fp_p);
if(fp_r>fp_u[1])
retVal=false;
else
if(fp_r>fp_u[0])
fp_u[0]=fp_r;
} else
if(fp_p>fp_0){
fp_r=MathFP.div(fp_q,fp_p);
if(fp_r<fp_u[0])
retVal=false;
else if(fp_r<fp_u[1])
fp_u[1]=fp_r;
} else
if(fp_q<fp_0)
retVal=false;
return retVal;
}
/**
*the default clip plane is from -1 to 1,at x, y
*/
public static void clipLine2DTest( int fp_x1, int fp_y1, int fp_x2, int fp_y2 ) {
int [] fp_u=new int[2];
fp_u[0]=fp_0;
fp_u[1]=MathFP.toFP(1);
int fp_dx=fp_x2-fp_x1;
int fp_dy;
int fp_winMin=MathFP.toFP(-1);
int fp_winMax=MathFP.toFP(1);
if(clipTest(-fp_dx, fp_x1-fp_winMin, fp_u))
if(clipTest(fp_dx, fp_winMax-fp_x1, fp_u)){
fp_dy=fp_y2-fp_y1;
if(clipTest(-fp_dy, fp_y1-fp_winMin, fp_u))
if(clipTest(fp_dy, fp_winMax-fp_y1, fp_u)){
if(fp_u[1] < fp_winMax){
fp_x2 = fp_x1 + MathFP.mul(fp_u[1] , fp_dx);
fp_y2 = fp_y1 + MathFP.mul(fp_u[1] , fp_dy);
}
if(fp_u[0] > fp_winMin){
fp_x1 += MathFP.mul(fp_u[0] , fp_dx);
fp_y1 += MathFP.mul(fp_u[0] , fp_dy);
}
System.out.println("Clipped results:");
System.out.print(MathFP.toString(fp_x1)+", ");
System.out.print(MathFP.toString(fp_y1)+", ");
System.out.print(MathFP.toString(fp_x2)+", ");
System.out.println(MathFP.toString(fp_y2)+", ");
}
}
}
/**
*the default clip plane is from -1 to 1, at x, y z
*/
public static void clipLine3DTest( int fp_x1, int fp_y1, int fp_z1, int fp_x2, int fp_y2 , int fp_z2) {
int [] fp_u=new int[2];
fp_u[0]=fp_0;
fp_u[1]=MathFP.toFP(1);
int fp_dx=fp_x2-fp_x1;
int fp_dy;
int fp_dz;
int fp_winMin=MathFP.toFP(-1);
int fp_winMax=MathFP.toFP(1);
if(clipTest(-fp_dx, fp_x1-fp_winMin, fp_u))
if(clipTest(fp_dx, fp_winMax-fp_x1, fp_u)){
fp_dy=fp_y2-fp_y1;
if(clipTest(-fp_dy, fp_y1-fp_winMin, fp_u))
if(clipTest(fp_dy, fp_winMax-fp_y1, fp_u)){
fp_dz=fp_z2-fp_z1;
if(clipTest(-fp_dz, fp_z1-fp_winMin, fp_u))
if(clipTest(fp_dz, fp_winMax-fp_z1, fp_u)){
if(fp_u[1] < fp_winMax){
fp_x2 = fp_x1 + MathFP.mul(fp_u[1] , fp_dx);
fp_y2 = fp_y1 + MathFP.mul(fp_u[1] , fp_dy);
fp_z2 = fp_z1 + MathFP.mul(fp_u[1] , fp_dz);
}
if(fp_u[0] > fp_winMin){
fp_x1 += MathFP.mul(fp_u[0] , fp_dx);
fp_y1 += MathFP.mul(fp_u[0] , fp_dy);
fp_z1 += MathFP.mul(fp_u[0] , fp_dz);
}
System.out.println("Clipped results:");
System.out.print(MathFP.toString(fp_x1)+", ");
System.out.print(MathFP.toString(fp_y1)+", ");
System.out.print(MathFP.toString(fp_z1)+", ");
System.out.print(MathFP.toString(fp_x2)+", ");
System.out.print(MathFP.toString(fp_y2)+", ");
System.out.println(MathFP.toString(fp_z2)+", ");
}
}
}
}
call these methods
int x1 = MathFP.toFP(-2);
int y1 = MathFP.toFP(-2);
int z1 = MathFP.toFP(-2);
int x2 = MathFP.toFP(2);
int y2 = MathFP.toFP(2);
int z2 = MathFP.toFP(2);
Graphics3D.clipLine2DTest(x1,y1,x2,y2);
Graphics3D.clipLine3DTest(x1,y1,z1,x2,y2,z2);
result:
Clipped results:
-1.0000, -1.0000, 1.0000, 1.0000,
Clipped results:
-1.0000, -1.0000, -1.0000, 1.0000, 1.0000, 1.0000,