rect.java

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

JAVA
1,488
字号
					//slope of the line from current vertex to friend vertex.
					slope1 = (peerFriendVertex.getY()-peerVertex.getY())/(peerFriendVertex.getX()-peerVertex.getX());

					//slope of the upright line.
					slope2 = -1/slope1;

				
					//center of the line from peerVertex to peer friend vertex.
					JFPoint friendMiddle	=peerVertex.midPoint(peerFriendVertex);
					double uprightX=0;
					double uprightY=0;					

					uprightX = (slope1 * x - y - slope2 * friendMiddle.getX()+friendMiddle.getY()) / (slope1 - slope2);
					uprightY = slope1 * (uprightX - x) + y;

				
					JFPoint _currPoint	=new JFPoint(x,y);
					JFPoint _uprightPoint	=new JFPoint(uprightX,uprightY);	
					double dist		=_currPoint.distance(_uprightPoint);
					JFPoint newPoint	=_currPoint.nearPoint(_uprightPoint,dist * 2,true);
					newx			=newPoint.getX();
					newy			=newPoint.getY();

			}
			break;
   		
	 } 
		 
	//temporary line.
	//LineSeg	line1=new LineSeg();
	//JFPoint upright1=null;

        /*
	//line that current point to peer vertex					
	line1.setPoint1(x,y);
	line1.setPoint2(peerVertex);
	upright1	=line1.uprightFoot(newx,newy);
	if (upright1==null || upright1.distance(newx,newy)<=GeomConst.MIN_LINELENGTH) return;
	
	//line that peer vertex to peer friend vertex.
	line1.setPoint1(peerVertex);
	line1.setPoint2(peerFriendVertex);
	upright1	=line1.uprightFoot(newx,newy);
	if (upright1==null || upright1.distance(newx,newy)<=GeomConst.MIN_LINELENGTH) return;
	
	upright1	=line1.uprightFoot(x,y);
	if (upright1==null || upright1.distance(x,y)<=GeomConst.MIN_LINELENGTH) return;
	*/


	if (requireChangePeerVertex){
		JFPoint	pnt=new JFPoint(newx1,newy1);
	    	if ( pnt.distance(x,y)>GeomConst.MIN_LINELENGTH){
			friendVertex.setValue(newx,newy);
			peerVertex.setValue(newx1,newy1);
			currentVertex.setValue(x,y);
		}
	}else{
		//line that current point to peer vertex					
		JFPoint tmp	=new JFPoint();
	
		tmp.setValue(peerVertex);
		if (tmp.distance(x,y)<=GeomConst.MIN_LINELENGTH) return;
	
		tmp.setValue(x,y);
		if (tmp.distance(newx,newy)<=GeomConst.MIN_LINELENGTH) return;

		tmp.setValue(peerFriendVertex);
		if (tmp.distance(newx,newy)<=GeomConst.MIN_LINELENGTH) return;

		friendVertex.setValue(newx,newy);
		currentVertex.setValue(x,y);
	}


    }


   /**
    *   Get a side line of this rectangle.
    *
    *   @return A side line.
    *
    */ 	
   public LineSeg getSide(int sideType){
   	
   	switch(sideType){
   		case  SIDETYPE_LEFT: //the line constructed by left-top vertex and left-bottom vertex
   			return new LineSeg(m_leftBottom,m_leftTop);

   		case  SIDETYPE_TOP: //the line constructed by left-top vertex and right-top vertex
   			return new LineSeg(m_leftTop,m_rightTop);

   		case  SIDETYPE_RIGHT: //the line constructed by right-top vertex and right-bottom vertex
   			return new LineSeg(m_rightTop,m_rightBottom);
   			
   		case  SIDETYPE_BOTTOM: //the line constructed by left-bottom vertex and right-bottom vertex
   			return new LineSeg(m_rightBottom,m_leftBottom);
   			
   		default:
   			return null;
  	}
   }

   /**
    *   Get a center point of this rectangle.
    *
    *   @return The center point.
    *
    */ 	
   public JFPoint getCenter(){
   	//we use the intersects point of two diagonals as the center of a rectangle.
   	LineSeg	line1	=new LineSeg(m_leftTop,m_rightBottom);
   	JFPoint center	=line1.intersectsAt(m_leftBottom,m_rightTop);
   	if (center==null){
		return new JFPoint(getX()+getWidth()/2, getY()+getHeight()/2);
	}else{
		return center;
	}
   }

   /**
    *   Scale current rectangle by specified points and scale percent.
    *   We only support a concurrent width-height scale here, suppose width as the length from
    *   basePoint to refPoint1, height as the length from basePoint to refPoint2, and 
    *   one scale percent acts on both width and height.
    *
    *   @param basePoint A base point that is unmovable.
    *   @param refPoint1 A 'width' reference point.
    *   @param refPoint2 A 'height' reference point.
    *   @param scale A reference scale percent.
    *
    */ 	
   public void scaleBy(JFPoint basePoint, JFPoint refPoint1, JFPoint refPoint2, double scale){
   	
   	JFPoint center	=getCenter();
   	
   	/*** firstly scale all points of this rectangle according to center ***/
   	m_leftTop.scaleBy(center.getX(),center.getY(),scale);
   	m_rightTop.scaleBy(center.getX(),center.getY(),scale);
   	m_leftBottom.scaleBy(center.getX(),center.getY(),scale);
   	m_rightBottom.scaleBy(center.getX(),center.getY(),scale);
   
	JFPoint newCenter	=newScaleCenter(center,basePoint,refPoint1,refPoint2,scale);
	//move center
	moveBy(newCenter.getX()-center.getX(),newCenter.getY()-center.getY());
   }

   /**
    *   Scale current object by a specified x and y scale.<br>
    *   This is a special scale method used to scale a shape in arbitrary x and y scale.<br>
    *   Please see AbstractShape.scaleBy for detailed description.
    *
    *   @param basePoint A base scale point for scaling reference.
    *   @param xScale  A scale percentage in x coordinate, default to 1.0
    *   @param yScale  A scale percentage in y coordinate, default to 1.0
    *
    */ 	
   public void scaleBy(JFPoint basePoint,double xScale, double yScale){
   	if (basePoint==null)
   		return;
   	double x	=basePoint.getX();
   	double y	=basePoint.getY();

	//if this rectangle has been rotated, we all choose a smaller scale for instead   	
	//Attention: Shape at a rotatation under 0, PI/2, PI, 3PI/2,2PI degrees would 
	//also be considered as an un-rotated shape
	if ((int)m_leftTop.getX()!=(int)m_leftBottom.getX() &&
	    (int)m_leftTop.getY()!=(int)m_leftBottom.getY()){
	    xScale	=Math.min(xScale,yScale);
	    yScale	=xScale;	
	}
   	
   	m_leftTop.scaleBy(x,y,xScale,yScale);
   	m_rightTop.scaleBy(x,y,xScale,yScale);
   	m_leftBottom.scaleBy(x,y,xScale,yScale);
   	m_rightBottom.scaleBy(x,y,xScale,yScale);
   }



   /**
    *   When a shape is scaled, its location center will be changed probably.
    *   so we need to canculate its new center acorrding to these scale parameters.
    *	
    *   @param center An old center of the scaled object.
    *   @param basePoint A base point that is unmovable.
    *   @param refPoint1 A 'width' reference point.
    *   @param refPoint2 A 'height' reference point.
    *   @param scale A reference scale percent.
    *
    */ 	
   public static JFPoint newScaleCenter(JFPoint center, JFPoint basePoint, JFPoint refPoint1, JFPoint refPoint2, double scale){

   	/*** then move all points by an offset. ***/
   	LineSeg line	=new LineSeg();
   	
   	//upright foot that an upright projective point from center to line1
   	line.setValue(basePoint,refPoint1);
   	JFPoint foot1	=line.uprightFoot(center.getX(),center.getY());


   	//upright foot that an upright projective point from center to line2
   	line.setValue(basePoint,refPoint2);
   	JFPoint foot2	=line.uprightFoot(center.getX(),center.getY());

   	
   	//clockwise?
   	boolean clockwise	=JFVector.underClockwiseSide(foot1,center,foot1,foot2);

   	
	//new foot1
	foot1		=basePoint.nearPoint(refPoint1,basePoint.distance(foot1)*scale,true);
	//new foot2
	foot2		=basePoint.nearPoint(refPoint2,basePoint.distance(foot2)*scale,true);

	
	//slope of the line from basePoit to refPoint2	
	double slope2  	=basePoint.getSlope(refPoint2);
	
	//a new center of this rectangle	
	return foot1.nearPoint(slope2,basePoint.distance(foot2),foot2,clockwise);
   }	   		



   /**
    *   Move this rectangle by specific x and y coordinates.
    *
    *   @param x   X coordiate to moveby. 
    *
    *   @param y   Y coordiate to moveby.
    *
    */ 	
   public void moveBy(double x, double y){
	m_leftTop.moveBy(x,y);
	m_rightTop.moveBy(x,y);
	m_leftBottom.moveBy(x,y);
	m_rightBottom.moveBy(x,y);
   }


   /**
    *   Rotate this rectangle by an angle theta.
    *
    *   @param theta A rotate angle.
    *
    */ 	
   public void rotateBy(double theta){
   	//get center point of this rectangle.
   	JFPoint center	=getCenter();
   	//rotate by center
   	rotateBy(center,theta);
   }

   /**
    *   Rotate this rectangle by a specified point and an angle theta.
    *   If rotate by a point, it's same as move this rectangle to a new position, 
    *   and simultaneously rotate this rectangle under proper angle.
    *   Certainly this angle is also equal to theta.
    *
    *   @param pnt  A rotate center point.
    *
    *   @param theta A rotate angle.
    *
    */ 	
   public void rotateBy(JFPoint pnt, double theta){
   	rotateBy(pnt.getX(),pnt.getY(),theta);
   }

   /**
    *   Rotate this line by a specified point and an angle theta.
    *
    *   @param baseX,&nbsp;baseY A rotate center coordinates.
    *
    *   @param theta A rotate angle.
    *
    */ 	
   public void rotateBy(double baseX,double baseY, double theta){
   	//rotate each vertex by rotate center point.
   	m_leftTop.rotateBy(baseX,baseY,theta);
   	m_rightTop.rotateBy(baseX,baseY,theta);
   	m_leftBottom.rotateBy(baseX,baseY,theta);
   	m_rightBottom.rotateBy(baseX,baseY,theta);
   }


   /**
    *   Mirror this rectangle by a central x coordinate of this rectangle. We make a up-down flip here.
    */ 	
   public void mirrorBy(){
	JFPoint center	=getCenter();
	mirrorBy(center.getX()); 
   }


   /**
    *   Mirror this rectangle by a x coordinate. We make a left-right mirror here.
    *
    *   @param baseX  A mirror base x coordinate.
    *
    */ 	
   public void mirrorBy(double baseX){
   	m_leftTop.mirrorBy(baseX);
   	m_rightTop.mirrorBy(baseX);
   	m_leftBottom.mirrorBy(baseX);
   	m_rightBottom.mirrorBy(baseX);
   }

   /**
    *   Reverse this rectangle by a central y coordinate of this rectangle. We make a up-down flip here.
    */ 	
   public void flipBy(){
	JFPoint center	=getCenter();
	flipBy(center.getY()); 
   }

   /**
    *   Reverse this rectangle by a y coordinate. We make a up-down flip here.
    *
    *   @param baseY  A flip base y coordinate.
    *
    */ 	
   public void flipBy(double baseY){
   	m_leftTop.flipBy(baseY);
   	m_rightTop.flipBy(baseY);
   	m_leftBottom.flipBy(baseY);
   	m_rightBottom.flipBy(baseY);
   }



   /**
    *   Test if a point is within this rectangle.
    *
    *   @param pnt  A point.
    *
    *   @return True if the point is inside rectangle, false if not.
    *
    */ 	
   public boolean contains(JFPoint pnt){
   	if (pnt==null)
   		return false;
   	else
   		return contains(pnt.getX(), pnt.getY());
   }

    
   /**
    *   Test if a point(x, y coordinates for instead) is within this rectangle.
    *
    *   <p> The algorithm for testing if a point is within this rectangle is at below.
    *   <p>
    *   count = 0;
    *  	[start at endpoint P, make an radial line L from right to left]
    * 	for [each side S of this rectangle] do
    *  		if [P is on one side S]
    *       		then return true;
    *     	if [side S is not a horizontal line]
    *       	then if [one endpoint of S is on L]
    *           	if [this endpoint is the max y coordinate of the two endpoints of S]
    *           	then count = count+1
    *           else if [S interacts L]
    *           then count=count+1;
    * 	if count mod 2 = 1 
    *   	then return true;
    * 	else return false;
    *
    *   @param x   X coordinate of this point.
    *
    *   @param y   Y coordinate of this point.
    *

⌨️ 快捷键说明

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