最近学习图形学,对当中两个直线截取算法颇有兴趣,于是简单实现了一下,没有继续深入测试
主要就是Sutherland管全内和全外,Beck管与区域有交点的直线
package test.com;
public class Test4 {
//直线截取算法
public static void main(String[] args) {
float[] a = new Test4().D(1,1,5,5,0,2,6,6);
if(a != null) {
System.out.println(a[0]+","+a[1]);
System.out.println(a[2]+","+a[3]);
}else {
System.out.println("....");
}
}
float[] D(int left,int down,int right,int top,int startX,int startY,int endX,int endY) {
//得到编码
//根据编码判断直线是否在区域内
//将部分可见的直线端点求中值.
//编码过滤
//
int[] startCode,endCode;
float[] d = new float[4];
startCode = getCode(left,right,top,down,startX,startY);
endCode = getCode(left,right,top,down,endX,endY);
int a = judgeCode(startCode,endCode);
if(a == 0) {
return null;
}else if(a == 1) {
d[0] = startX;
d[1] = startY;
d[2] = endX;
d[3] = endY;
return d;
}else{
Vertex vS = new Vertex(startX,startY);
Vertex vE = new Vertex(endX,endY);
Vertex D = new Vertex(endX - startX,endY - startY);
int i = 0;
Vertex[] wi = new Vertex[2];
Vertex[] ni = new Vertex[4];
wi[0] = new Vertex(startX - left,startY - down);
wi[1] = new Vertex(startX - right,startY - top);
ni[0] = new Vertex(1,0);
ni[1] = new Vertex(0,1);
ni[2] = new Vertex(-1,0);
ni[3] = new Vertex(0,-1);
float topT[] = new float[2];
float downT[] = new float[2];
while(i != 4) {
int k = i/2;
float t = -(wi[k].mutiply(ni[i]))/(float)(D.mutiply(ni[i]));
// System.out.println(wi[k].mutiply(ni[i]));
if(i < 2) {
downT[i] = t;
}else {
topT[i - 2] = t;
}
i++;
}
float t1,t2;
if(downT[0] > downT[1]) {
t1 = downT[0];
}else {
t1 = downT[1];
}
if(topT[0] < topT[1]) {
t2 = topT[0];
}else {
t2 = topT[1];
}
d[0] = startX + (D.x * t1);
d[1] = startY + (D.y * t1);
d[2] = startX + (D.x * t2);
d[3] = startY + (D.y * t2);
//System.out.println(t1);
return d;
}
//return null;
}
int judgeCode(int[] startCode,int[] endCode) {
for(int i = 0;i < startCode.length;i++) {
if(startCode[i] == endCode[i] && startCode[i] == 1) {
return 0;
}
}
int k = 0;
for(int i = 0;i < startCode.length;i++) {
if(startCode[i] == endCode[i] && startCode[i] == 0) {
k++;
}
}
if(k == 4) {
return 1;
}else{
return 2;
}
}
private int[] getCode(int left,int right,int top,int down,int x,int y) {
int[] code = new int[4];
if(y > top) {
code[0] = 1;
}else {
code[0] = 0;
}
if(y < down) {
code[1] = 1;
}else {
code[1] = 0;
}
if(x > right) {
code[2] = 1;
}else {
code[2] = 0;
}
if(x < left) {
code[3] = 1;
}else {
code[3] = 0;
}
return code;
}
class Vertex{
int x = 0;
int y = 0;
public Vertex(int x,int y){
this.x = x;
this.y = y;
}
public Vertex(){
}
public int mutiply(Vertex v) {
return x * v.x + y * v.y;
}
}
}
测试结果
1.0 ,2.6666667
4.5 ,5.0