Cohen-Sutherland与Cohen-Beck直线截取算法混合版java实现

最近学习图形学,对当中两个直线截取算法颇有兴趣,于是简单实现了一下,没有继续深入测试

主要就是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

猜你喜欢

转载自blog.csdn.net/qq_39668086/article/details/81570729