rect.java

来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,488 行 · 第 1/4 页

JAVA
1,488
字号
			neighborVertex2	=m_leftBottom;
			peerVertex	=m_leftTop;
			break;
			
		default:
			return;
	}
	
	
	switch(moveType){
		case	VERTEXMOVETYPE_SCALE:
			moveRectangle(currVertex,neighborVertex1,neighborVertex2,peerVertex,x,y,true);
			break;
		
		case	VERTEXMOVETYPE_RECTANGLE:
			moveRectangle(currVertex,neighborVertex1,neighborVertex2,peerVertex,x,y,false);
			break;

		case	VERTEXMOVETYPE_PARALLEL:
			moveParallel(vertexType,x,y,moveType,this);
			break;

		case	VERTEXMOVETYPE_TRAPEZOID:
		case	VERTEXMOVETYPE_ISOSCELESTRAPEZOID:
			moveParallel(vertexType,x,y,moveType,this);
			break;
	}

    }


   /**
    *   Move a vertex of a rectangle, but force it as a rectangle.
    *
    *   @param currVertex A vertex currently moved.
    *
    *   @param neighborVertex1, neighborVertex2 Neibor vertexes nearby current vertex.
    *
    *   @param peerVertex A peer vertex of current vertex, this vertex will always be a fixed one.
    *
    *   @param x, y  Coordinates of a new vertex point.
    *   @param isScale  True if forcing a same scale on width and height, false otherwise.
    *
    */
    private static void moveRectangle(JFPoint currVertex,JFPoint neighborVertex1, JFPoint neighborVertex2, JFPoint peerVertex,double x, double y,boolean isScale){

   		/** In scaling a rectangle, we will always get a rectangle by making two uprightFeet
    		 *  that from currently moving vertex to peer two sides of the rectangle.
     		 */ 
     		 
     		 int vertexChanged	=0;

		 LineSeg   line1, line2;
     		 JFPoint   uprightFoot1,uprightFoot2;
     		 
     		 //one peer side and its upright foot.
     		 line1=new LineSeg(peerVertex,neighborVertex1);
    		 uprightFoot1	= line1.uprightFoot(x,y);

     		 //other peer side and its upright foot.
     		 line2=new LineSeg(peerVertex,neighborVertex2);
    		 uprightFoot2	= line2.uprightFoot(x,y);

		 //if is under scale situation, we need to force a same width-height scale.
     		 if (isScale){
     		 	double oldLen1	=peerVertex.distance(neighborVertex1);
     		 	double oldLen2	=peerVertex.distance(neighborVertex2);
     		 	double newLen1	=peerVertex.distance(uprightFoot1);
     		 	double newLen2	=peerVertex.distance(uprightFoot2);
     		 	
     		 	if (oldLen1<1) oldLen1=1;
     		 	if (oldLen2<1) oldLen2=1;
     		 	
     		 	double scale1	=newLen1/oldLen1;
     		 	double scale2	=newLen2/oldLen2;
     		 	
     		 	//get a maximum scale from scale1 and scale2
     		 	double scale	=Math.max(scale1,scale2);
			
			//re-calculate upright feet by one scale.
			newLen1		=oldLen1 * scale;
			newLen2		=oldLen2 * scale;
			uprightFoot1	=peerVertex.nearPoint(neighborVertex1,newLen1,true);
			uprightFoot2	=peerVertex.nearPoint(neighborVertex2,newLen2,true);
		}
     		 	
     		 //check the uprightfoot and restrict a minmum side length of rectangle.
    		 if (line2.distance(uprightFoot1)>GeomConst.MIN_LINELENGTH){
    		 	//move this neibor vertex to a new position
    		 	neighborVertex1.setValue(uprightFoot1);
    		 	vertexChanged++;
    		 }
    		 
     		 //check the uprightfoot and restrict a minmum side length of rectangle.
    		 if (line1.distance(uprightFoot2)>GeomConst.MIN_LINELENGTH){
    		 	//move this neibor vertex to a new position
    		 	neighborVertex2.setValue(uprightFoot2);
    		 	vertexChanged++;
    		 }
    		 
    		 //if two relational vertex of current vertex has been changed,
    		 //we will consider that current vertex has successfully changed
    		 // to new x,y position, otherwise we need to calculate the 
    		 // actual position of current vertex.
    		 if (vertexChanged==2 && !isScale){
    		 	currVertex.setValue(x,y);
    		 }else{
    		 	double slope1	=line1.getSlope();
    		 	double slope2	=line2.getSlope();
    		 	if (slope1==GeomConst.LARGE_VALUE || slope2==0){
    		 		//vertical line
				currVertex.setValue(neighborVertex2.getX(),neighborVertex1.getY());
    		 		
    		 	}else if (slope1==0 || slope2==GeomConst.LARGE_VALUE){
				currVertex.setValue(neighborVertex1.getX(),neighborVertex2.getY());
				
    		 	}else{
    		 		//two line here:
    		 		//y=slope1 * (x-neighbor2.x) + neighbor2.y
    		 		//y=slope2 * (x-neighbor1.x) + neighbor1.y
    		 		//so:
    		 		//x=(neighbor1.y-neighbor2.y -slope2 * neighbor1.x + slope1 * neighbor2.x)/(slope1-slope2)
    		 		double newx = (neighborVertex1.getY()-neighborVertex2.getY() -slope2 * neighborVertex1.getX() + slope1 * neighborVertex2.getX())/(slope1-slope2);
    		 		double newy = slope1 * (newx-neighborVertex2.getX()) + neighborVertex2.getY();
    		 		currVertex.setValue(newx,newy);
    		 	}
    		 }
    }




   /**
    *   Move a vertex of a parallel rectangle, e.g. parallelogram,trapezoid, isosceles trapezoid.
    *
    *   @param vertexType An vertex type of a rectangle.
    *
    *   @param x,&nbsp;y  Coordinates of a new vertex point.
    *
    *   @param moveType  Arbitrary trapezoid, or isosceles trapezoid
    *
    *   @param rect  Currently changed trapezoid.
    *
    */
    private static void moveParallel(int vertexType,double x, double y,int moveType,Rect rect){
	/**
	 *  We will aways consider that the line left-top to right-top and 
	 *  line left-bottom to right-bottom are parallel lines.
	 *
	 *  When one vertex of trapezoid is moved, the two vertex on the other parallel line
	 *  will not move, and the other vertex on the same parallel line will move considering
	 *  rules below.
	 *
	 *  If moveType is arbitrary trapezoid, the other vertex on the same parallel line
	 *  will maintain it's relationship(angle, slope) with the other parallel line;
	 *  If moveType is isosceles trapezoid, the other vertex on the same parallel line
	 *  will be forced into an isosceles trapezoid vertex.
	 */
	
	 //currently moving vertex.
	 JFPoint  currentVertex=null;
	 //friend vertex that on the same parallel line
	 JFPoint  friendVertex=null;
	 //neibor vertex of current vertex, but on the other parallel line
	 JFPoint  peerVertex=null;
	 //peer vertex of current vertex, on the other parallel line.
	 JFPoint  peerFriendVertex=null;	
	
	 switch(vertexType){
	 	case VERTEXTYPE_LEFTTOP:
	 		currentVertex		=rect.getVertex(VERTEXTYPE_LEFTTOP);
	 		friendVertex		=rect.getVertex(VERTEXTYPE_RIGHTTOP);
	 		peerVertex		=rect.getVertex(VERTEXTYPE_LEFTBOTTOM);
	 		peerFriendVertex	=rect.getVertex(VERTEXTYPE_RIGHTBOTTOM);
	 		break;
	 		
	 	case VERTEXTYPE_RIGHTTOP:
	 		currentVertex		=rect.getVertex(VERTEXTYPE_RIGHTTOP);
	 		friendVertex		=rect.getVertex(VERTEXTYPE_LEFTTOP);
	 		peerVertex		=rect.getVertex(VERTEXTYPE_RIGHTBOTTOM);
	 		peerFriendVertex	=rect.getVertex(VERTEXTYPE_LEFTBOTTOM);
	 		break;
	 		
	 	case VERTEXTYPE_LEFTBOTTOM:
	 		currentVertex		=rect.getVertex(VERTEXTYPE_LEFTBOTTOM);
	 		friendVertex		=rect.getVertex(VERTEXTYPE_RIGHTBOTTOM);
	 		peerVertex		=rect.getVertex(VERTEXTYPE_LEFTTOP);
	 		peerFriendVertex	=rect.getVertex(VERTEXTYPE_RIGHTTOP);
	 		break;
	 		
	 	case VERTEXTYPE_RIGHTBOTTOM:
	 		currentVertex		=rect.getVertex(VERTEXTYPE_RIGHTBOTTOM);
	 		friendVertex		=rect.getVertex(VERTEXTYPE_LEFTBOTTOM);
	 		peerVertex		=rect.getVertex(VERTEXTYPE_RIGHTTOP);
	 		peerFriendVertex	=rect.getVertex(VERTEXTYPE_LEFTTOP);
	 		break;
	 	
	 	default:
	 		return;
	 		
	 }
	
	 //we want to get a new friend vertex here.	 
	 double slope1=0;
	 double slope2=0;
	 double newx=0; //for new friend vertex
	 double newy=0; //for new friend vertex
	 
	 double newx1=0; //for new peer vertex
	 double newy1=0; //for new peer vertex
	 
	 boolean requireChangePeerVertex =false;
	 
	 switch(moveType){
	 	case VERTEXMOVETYPE_PARALLEL:  //parallelogram
			
			if (x==peerVertex.getX()){
				newx	=peerFriendVertex.getX();
				newy	=peerFriendVertex.getY() - peerVertex.getY() + y;
			
			}else if (y==peerVertex.getY()){
				newy    =peerFriendVertex.getY();
				newx	=peerFriendVertex.getX() - peerVertex.getX() + x;
			}else{
	 			switch(vertexType){
	 				case VERTEXTYPE_LEFTTOP:
	 				case VERTEXTYPE_RIGHTTOP: 
   				         	//only friend vertex changed here.
	 				
						//slope of the line that current vertex(current mouse position instead) to peer vertex
						//this slope will be changed while moving current vertex.
						slope1	=(peerVertex.getY()-y)/(peerVertex.getX()-x);
						//slope of the line that current vertex(current mouse position instead) to friend vertex
						slope2	=(peerFriendVertex.getY()-peerVertex.getY())/(peerFriendVertex.getX()-peerVertex.getX());
						
						//two lines below:
						//peer friend vertex to friend vertex, y=k1 * (x-peerFriend.x) +peerFriend.y
						//current vertex to friend vertex, y=k2 * (x-current.x) +current.y
						//so x=(current.y - peerFriend.y + k1 * peerFriend.x - k2 * current.x) /(k1-k2)
						newx = (y-peerFriendVertex.getY()+ slope1 * peerFriendVertex.getX() - slope2 * x)/(slope1-slope2);
						newy = slope1 * (newx - peerFriendVertex.getX()) + peerFriendVertex.getY();
					
	 					break;
	 		
	 				case VERTEXTYPE_LEFTBOTTOM:
	 				case VERTEXTYPE_RIGHTBOTTOM:
   				         	//both friend vertex and peer vertex will change here.

						//slope of the line that current vertex to peer vertex
						//this slope will NOT be changed while moving current vertex.
						slope1	=(peerVertex.getY()-currentVertex.getY())/(peerVertex.getX()-currentVertex.getX());
						//slope of the line that current vertex to friend vertex
						slope2	=(peerFriendVertex.getY()-peerVertex.getY())/(peerFriendVertex.getX()-peerVertex.getX());
   				         	
   				         	//calculate new friend vertex.
						//two lines below:
						//peer friend vertex to friend vertex, y=k1 * (x-peerFriend.x) +peerFriend.y
						//current vertex to friend vertex, y=k2 * (x-current.x) +current.y
						//so x=(current.y - peerFriend.y + k1 * peerFriend.x - k2 * current.x) /(k1-k2)
						newx = (y-peerFriendVertex.getY() + slope1 * peerFriendVertex.getX() - slope2 * x)/(slope1-slope2);
						newy = slope1 * (newx-peerFriendVertex.getX()) + peerFriendVertex.getY();
   				         	
   				         	//calculate new peer vertex.
						//two lines below:
						//peer vertex to current vertex, y=k1 * (x-current.x) + current.y
						//peer friend vertex to peer vertex, y=k2 * (x-peerFriend.x) +peerFriend.y
						//so x=(peerFriend.y-current.y +k1 * current.x -k2 * peerFriend.x) /(k1-k2)
						newx1 = (peerFriendVertex.getY()-y + slope1 * x - slope2 * peerFriendVertex.getX())/(slope1-slope2);
						newy1 = slope1 * (newx1-x) + y;
						
						requireChangePeerVertex	=true;
   				         	
	 					break;
	 			}
	 		}
			break;	 	
	 	
	 	
	 	case VERTEXMOVETYPE_TRAPEZOID: //arbitrary trapezoid

			//slope of the line from peer vertex to peer friend vertex.
			if ((float)peerFriendVertex.getX()==(float)peerVertex.getX())
				slope1  = GeomConst.LARGE_VALUE; //this value will never be used below.
			else
				slope1  = (peerFriendVertex.getY()-peerVertex.getY())/(peerFriendVertex.getX()-peerVertex.getX());
				
			//slope of the line from friend vertex to peer friend vertex.
			if ((float)peerFriendVertex.getX()==(float)friendVertex.getX())
				slope2  = GeomConst.LARGE_VALUE; //this value will never be used below.
			else
				slope2  = (peerFriendVertex.getY()-friendVertex.getY())/(peerFriendVertex.getX()-friendVertex.getX());

	 	        //friend vertex and peer friend vertex are in same x coordinates.
	 	        //so we keep the x coordinate of friend vertex here.
			if ((float)friendVertex.getX()==(float)peerFriendVertex.getX()){

				newx	=friendVertex.getX(); //save friend vertex's x coordinate
				
				if ((float)peerFriendVertex.getY()==(float)peerVertex.getY()){
					newy	=y;
				//peer friend vertex and peer vertex will never under same x coordinates here.
				}else{
					//equation of line from current vertex to friend vertex.
					//y=k *(x-currentVertex.x) + currentVertex.y;
					newy     =  slope1 * (newx - x) + y;
				}

	 	        //friend vertex and peer friend vertex are in same y coordinates,
	 	        //so we keep the y coordinate of friend vertex here.
			}else if ((float)friendVertex.getY()==(float)peerFriendVertex.getY()){

				newy	= friendVertex.getY();

				if ((float)peerFriendVertex.getX()==(float)peerVertex.getX())
					newx	=x;
				//peer friend vertex and peer vertex will never under same y coordinates here.
				else{
					//equation of line from current vertex to friend vertex.
					//y=k *(x-currentVertex.x) + currentVertex.y;
					newx     =  (newy-y)/slope1 + x;
				}
			
			}else{
				if ((float)peerFriendVertex.getX()==(float)peerVertex.getX()){
					//equation of line from peer friend vertex to friend vertex.
					//y=k *(x-peerFriend.x) + peerFriend.y;
					newx     =  x;
					newy     =  slope2 * (x - peerFriendVertex.getX()) + peerFriendVertex.getY();
				}else{
					/**
					 * equation of line from current vertex to friend vertex.
					 * y=k1 *(x-currentVertex.x) + currentVertex.y;
					 *
					 * equation of line from current vertex to peer vertex.
					 * y=k2 *(x-peerFriend.x) + peerFriend.y;
					 *
					 * so we get: 
					 * x=(k1 * currentVertex.x - currentVertex.y - k2 * peerFriend.x + peerFriend.y) / (k1-k2)
					 *
					 */

					 newx = (slope1 * x - y - slope2 * peerFriendVertex.getX()+peerFriendVertex.getY()) / (slope1 - slope2);
					 newy = slope1 * (newx - x) + y;
				}
			}
			break;

   		case VERTEXMOVETYPE_ISOSCELESTRAPEZOID: //isosceles trapezoid
			
		
				if ((int)peerFriendVertex.getX()==(int)peerVertex.getX()){
					newx     =  x;
					newy     =  peerFriendVertex.getY() - (y - peerVertex.getY());
				
				}else if ((int)peerFriendVertex.getY()==(int)peerVertex.getY()){

					newx     =  peerFriendVertex.getX() - (x - peerVertex.getX());
					newy     =  y;

				}else{

					/**
					 * equation of line from current vertex to friend vertex.
					 * y=k1 *(x-currentVertex.x) + currentVertex.y;
					 *
					 * equation of the upright line  of line from current vertex to friend vertex.
					 * y=k2 *(x-friendMiddle.x) + friendMiddle.y;
					 *
					 * so we get: 
					 * x=(k1 * currentVertex.x - currentVertex.y - k2 * friendMiddle.x + friendMiddle.y) / (k1-k2)
					 *
					 */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?