lineseg.java

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

JAVA
1,182
字号
    *   Reverse this line by a central y coordinate of this line. We make a up-down flip here.
    */ 	
   public void flipBy(){
   	double centralY	=(m_point1.getY() + m_point2.getY())/2;
   	flipBy(centralY);
   }


   /**
    *   Reverse this line by a y coordinate. We make a up-down flip here.
    *
    *   @param baseY  A flip base y coordinate.
    *
    */ 	
   public void flipBy(double baseY){
   	m_point1.flipBy(baseY);
   	m_point2.flipBy(baseY);
   }


   /**
    *   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();

   	m_point1.scaleBy(center.getX(),center.getY(),scale);
   	m_point2.scaleBy(center.getX(),center.getY(),scale);

  
	JFPoint newCenter	=Rect.newScaleCenter(center,basePoint,refPoint1,refPoint2,scale);

	//move center
	moveBy(newCenter.getX()-center.getX(),newCenter.getY()-center.getY());
   }


   /**
    *   Scale this line by its center point, and specified scale.
    *
    *   @param scale  A scale value.
    *
    */ 	
   public void scaleBy(double scale){
   	JFPoint center	=getCenter();
   	scaleBy(center.getX(),center.getY(),scale);
   }

   /**
    *   Scale this line by a point, and specified scale.
    *
    *   @param baseX, baseY  A scale reference point.
    *
    *   @param scale  A scale value.
    *
    */ 	
   public void scaleBy(double baseX, double baseY, double scale){
   	scaleBy(baseX,baseY,scale,scale);
   }

   /**
    *   Scale this line by a point, and specified scale.
    *
    *   @param baseX, baseY  A scale reference point.
    *
    *   @param xScale  A scale value in x coordinate.
    *   @param yScale  A scale value in y coordinate.
    *
    */ 	
   public void scaleBy(double baseX, double baseY, double xScale, double yScale){
   	m_point1.scaleBy(baseX,baseY,xScale,yScale);
   	m_point2.scaleBy(baseX,baseY,xScale,yScale);
   }


   /**
    *   Test if a point is on this line.
    *
    *   @param pnt A point to be measured.
    *
    *   @return True if the point is on this line, false otherwise.
    *
    */ 	
   public boolean contains(JFPoint pnt){
   	if (pnt==null)
   		return false;
   	else
   		return contains(pnt,0);
   }

   /**
    *   Test if a point is on this line.
    *   Here we used an analog offset for 'pick' this line.
    *
    *   @param pnt A point to be measured.
    *
    *   @param pickOffset An analog offset for 'pick' this line.
    *
    *   @return True if the point is on this line, false otherwise.
    *
    */ 	
   public boolean contains(JFPoint pnt,double pickOffset){
   	if (pnt==null)
   		return false;
   	else
   		return contains(pnt.getX(),pnt.getY(),pickOffset);
   }

   /**
    *   Test if a point(x, y coordinates for instead) is on this line.
    *   @param x   X coordinate of this point.
    *
    *   @param y   Y coordinate of this point.
    *
    *   @return True if the point is on this line, false otherwise.
    *
    */ 	
   public boolean contains(double x, double y){
   	return contains(x,y,0);
   }

   /**
    *   Test if a point(x, y coordinates for instead) is on this line.
    *   Here we used an analog offset for 'pick' this line.
    *
    *   @param x   X coordinate of this point.
    *
    *   @param y   Y coordinate of this point.
    *
    *   @return True if the point is on this line, false otherwise.
    *
    */ 	
   public boolean contains(double x, double y,double pickOffset){
   	double dist = distance(x,y);
   	return ((float)dist<=pickOffset);
   }


   /**
    *   Test if three points are on same line.
    *
    *   @param point1  first point one the line.
    *
    *   @param point2  second point one the line
    *
    *   @param point3  third point one the line
    *
    *   @return True if the three points are on same line, False otherwise.
    *
    */ 	
   public static boolean sameLinePoints(JFPoint point1, JFPoint point2, JFPoint point3){
   	if (point1==null || point2==null || point3==null)
   		return false;
   		
   	return sameLinePoints(point1.getX(),point1.getY(),point2.getX(),point2.getY(),point3.getX(),point3.getY());
   }

   /**
    *   Test if three points are on same line.
    *
    *   @param x1,&nbsp;y1  first point one the line.
    *
    *   @param x2,&nbsp;y2  second point one the line
    *
    *   @param x3,&nbsp;y3  third point one the line
    *
    *   @return True if the three points are on same line, False otherwise.
    *
    */ 	
   public static boolean sameLinePoints(double x1, double y1, double x2, double y2, double x3, double y3){
   	//on same vertical line
   	if ((float)x1==(float)x2 && (float)x2==(float)x3)
   		return true;

   	//on same horizontal line
   	else if ((float)y1==(float)y2 && (float)y2==(float)y3)
   		return true;
   	
   	double slope1	=getSlope(x1,y1,x2,y2);
   	double slope2	=getSlope(x2,y2,x3,y3);
   	return (slope1==slope2);
   }


    /**
     * Returns the distance from a point to this line segment.
     * The distance measured is the distance between the specified
     * point and the closest point between the specified endpoints.  
     * If the specified point is on the line segment, this method returns 0.0.     
     *
     * @param pnt the specified point being
     *	measured against the specified line segment
     *
     * @return a double value that is  the distance from the
     *			specified point to this line segment.
     */
    public  double distance(JFPoint pnt) {
    	return distance(pnt.getX(),pnt.getY());
    }
    	
    /**
     * Returns the distance from a point to this line segment.
     * The distance measured is the distance between the specified
     * point and the closest point between the specified endpoints.  
     * If the specified point is on the line segment, this method returns 0.0.     
     *
     * @param px,&nbsp;py the coordinates of the specified point being
     *		measured against the specified line segment
     *
     * @return a double value that is  the distance from the
     *			specified point to this line segment.
     */
    public  double distance(double px, double py) {
    	//get the closest point on this line to the specified point.
    	JFPoint closePnt	=closeTo(px,py);
    	
    	return closePnt.distance(px,py);
    }



    /**
     * Returns a closest point on this line segment to specified point.
     *
     * @param px,&nbsp;py the coordinates of the specified point being
     *		measured against the specified line segment
     *
     * @return a point that is  on this line segment and has a shortest distance 
     * to specified point.
     */
    public  JFPoint closeTo(double px, double py) {

    	double x1	=m_point1.getX();
    	double y1	=m_point1.getY();
    	double x2	=m_point2.getX();
    	double y2	=m_point2.getY();
    	JFPoint newPnt	=null; //upright foot
    	
    	//vertical line.
    	if ((float)x1==(float)x2){
		newPnt	=new JFPoint(x1,py);
		//upright point is on the line segment:
		if ((py>=y1 && py<=y2) || (py>=y2 && py<=y1)){
			return newPnt;
		//upright point is outside of the line segment,
		//then choose the closest endpoint to upright point:
		}else{
			if (newPnt.distance(x1,y1)<newPnt.distance(x2,y2)){
				return new JFPoint(x1,y1);
			}else{
				return new JFPoint(x2,y2);
			}
		}
	//horizontal line
    	}else if ((float)y1==(float)y2){
		newPnt	=new JFPoint(px,y1);
		//upright point is on the line segment:
		if ((px>=x1 && px<=x2) || (px>=x2 && px<=x1)){
			return newPnt;
		//upright point is outside of the line segment,
		//then choose the closest endpoint to upright point:
		}else{
			if (newPnt.distance(x1,y1)<newPnt.distance(x2,y2)){
				return new JFPoint(x1,y1);
			}else{
				return new JFPoint(x2,y2);
			}
		}
	//inclined/any line
	}else{
		/**
		 Inclined line should has a slope.
		 Assume we have two endpoints, pt1 and pt2,
		 slope k = ( pt2.y - pt1. y ) / (pt2.x - pt1.x );
		 equation of line is y = k* ( x - pt1.x) + pt1.y;
		 slope of upright line is -1/k
		 equation of upright line is y = (-1/k) * (x - point.x) + point.y
		 so we can get:
		 x = ( k^2 * pt1.x + k * (point.y - pt1.y ) + point.x ) / ( k^2 + 1),
    		 y = k * ( x - pt1.x) + pt1.y;
		 */

		
		//slope of line.
		double slope =( y2 - y1 ) / (x2 - x1 );
		
		//x coordinate of upright point.
		double x = (Math.pow(slope,2) * x1 +  slope * (py - y1) + px)/(Math.pow(slope,2)+1);
		double y = slope * (x - x1) + y1;

		newPnt	=new JFPoint(x,y);
		//upright point is on the line segment:
		if (((x>=x1 && x<=x2) || (x>=x2 && x<=x1))&&
 		    ((y>=y1 && y<=y2) || (y>=y2 && y<=y1)))	{
			return newPnt;
		//upright point is outside of the line segment,
		//then choose the closest endpoint to upright point:
		}else{
			if (newPnt.distance(x1,y1)<newPnt.distance(x2,y2)){
				return new JFPoint(x1,y1);
			}else{
				return new JFPoint(x2,y2);
			}
		}
	}
    }

    /**
     * Returns an upright foot point on this line segment to specified point.
     *
     * @param px,&nbsp;py the coordinates of the specified point being
     *		measured against the specified line segment
     *
     * @return an upright foot point that is  on this line segment or its extended line.
     */
    public  JFPoint uprightFoot(double px, double py) {

    	double x1	=m_point1.getX();
    	double y1	=m_point1.getY();
    	double x2	=m_point2.getX();
    	double y2	=m_point2.getY();
	
	double slope=0;
	    	
    	//vertical line.
    	if ((float)x1==(float)x2){
    		slope	=GeomConst.LARGE_VALUE;
	//horizontal line
	}else if ((float)y1==(float)y2){
    		slope	=0;
	//inclined/any line
	}else{
		/**
		 Inclined line should has a slope.
		 Assume we have two endpoints, pt1 and pt2,
		 slope k = ( pt2.y - pt1. y ) / (pt2.x - pt1.x );
		 */
		//slope of line.
		slope =( y2 - y1 ) / (x2 - x1 );
	}

	return uprightFoot(slope,x1,y1,px,py);
    }


    /**
     * Returns an upright foot point on a specified slope of a line accross a specified point.
     * @param slope A slope of a line.
     * @param x1,&nbsp;y1 the coordinates of a point the line accrosed.
     * @param px,&nbsp;py the coordinates of the specified point being
     *		measured against the specified line segment
     *
     * @return an upright foot point that is  on this line segment or its extended line.
     */
    public  static JFPoint uprightFoot(double slope, double x1, double y1, double px, double py) {

    	//vertical line.
    	if (slope==GeomConst.LARGE_VALUE){
    		return new JFPoint(x1,py);
	//horizontal line
	}else if (slope==0){
		return new JFPoint(px,y1);
	//inclined/any line
	}else{
		/**
		 Inclined line should has a slope.
		 Assume we have two endpoints, pt1 and pt2,
		 slope k = ( pt2.y - pt1. y ) / (pt2.x - pt1.x );
		 equation of line is y = k* ( x - pt1.x) + pt1.y;
		 slope of upright line is -1/k
		 equation of upright line is y = (-1/k) * (x - point.x) + point.y
		 so we can get:
		 x = ( k^2 * pt1.x + k * (point.y - pt1.y ) + point.x ) / ( k^2 + 1),
    		 y = k * ( x - pt1.x) + pt1.y;
		 */
		
		//x coordinate of upright point.
		double x = (Math.pow(slope,2) * x1 +  slope * (py - y1) + px)/(Math.pow(slope,2)+1);
		double y = slope * (x - x1) + y1;
		
		return new JFPoint(x,y);
	}
    }

⌨️ 快捷键说明

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