/**
 * @(#)algo.java
 *
 *
 * @author Mohammed hasan taha 
 * @version 1.00 2010/1/13
 */

import javax.swing.*;
import java.awt.*;

public class Cohen_And_Sutherland extends JFrame {	
	public static final int left   =0x1;
	public static final int right  =0x2;
	public static final int bottom =0x4;
	public static final int top    =0x8;
	int xmin=15,xmax=270,ymin=40,ymax=236;
	Point p1,p2;
	float m;

 
    public Cohen_And_Sutherland(Point p1, Point p2) {
    	this.p1=p1;
    	this.p2=p2;
    	m=(p2.y - p1.y)/ (float)(p2.x - p1.x);
    	setSize(400,400);
    	setVisible(true);
    }
    
    
    int encode (Point p){
    	int code =0;
    	if (p.x < xmin) 
    		code |=left;
    		else if (p.x > xmax)
    			code |=right;
    			if(p.y < ymin)
    				code |=bottom;
    				else if(p.y > ymax)
    					code |=top;
    					return code;
    	}
    	
    	    boolean accepted (int code1 ,int code2){
    	    	return (code1==0 && code2 == 0);
    	    	}
    		
    		boolean rejected (int code1,int code2){
    			return ((code1 & code2)!=0);
    			}
    		
    		boolean isInside(int code){
    		    return (code==0);	
    			}
    		
    		void swap(Point p1,Point p2){
    		   int t=p1.x;
    		   p1.x =p2.x;
    		   p2.x =t;
    		   t    =p1.y;
    		   p1.y =p2.y;
    		   p2.y =t;	
    			}
            void clipLine (Point p1, Point p2,Graphics g){
            	int code1 ,code2;
            	boolean done=false , draw =false;
            	while(!done){
            		code1 = encode(p1);
            		code2 = encode(p2);
            		if(accepted(code1,code2)){
            			done=true;
            			draw=true;
            		}
            		else if(rejected(code1,code2)){
            			done=true;
            		}
            		else{
            			if(isInside(code1))
            				swap(p1,p2);
            				if(p1.x<xmin){
            					p1.y = Math.round(p1.y+m*(xmin-p1.x));
            					p1.x =xmin;
            				}
            				else if(p1.x > xmax){
            					p1.y = Math.round(p1.y + m * (xmax - p1.x));
            					p1.x = xmax;
            				}
            				else if (p1.y < ymin){
            					p1.x = Math.round(p1.x + (ymin - p1.y)/m);
            					p1.y = ymin;
            				}
            				else if(p1.y > ymax){
            					p1.x = Math.round(p1.x + (ymax -p1.y)/m);
            					p1.y = ymax;
            				}
            		}// end else 
            	} // end while
            
             if (draw){
             	g.setColor(Color.red);
             	g.drawLine(p1.x,p1.y,p2.x,p2.y);
             }
            }// end clipLine
            
            public void paint(Graphics g){
            	super.paint(g);
            	g.drawRect(xmin,ymin,xmax-xmin,ymax-ymin);
            	clipLine(p1,p2,g);
            }
            public static void main (String args[]){
            	Point p1 = new Point (6,48);
            	Point p2 = new Point (310,200);
            	new Cohen_And_Sutherland(p1,p2);
            }
    
}