⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 curve.java

📁 用Java开发的、实现类似Visio功能的应用程序源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
			//vertical line from left-top to right-top
			rightTopX =x1;
			rightTopY =y2;	
		
		}else if ((float)divisor==0){
			//horizontal line from left-top to right-top
			rightTopX =x2;
			rightTopY =y1;	
		
		}else{

			double k2	=divisor/dividend;
			double k3	=-1/k2;
			
			rightTopX	=(y2-k3 * x2 - y1 + k2 * x1)/(k2-k3);
			rightTopY	=k2 * (rightTopX-x1) + y1;
		}
	}


	double leftBottomX=x1 - (rightTopX - x2);
	double leftBottomY=y1 - (rightTopY - y2);
	
	JFPoint mid1	=startPoint.midPoint(rightTopX,rightTopY);
	JFPoint mid2	=endPoint.midPoint(leftBottomX,leftBottomY);
	setValue(x1,y1,mid1.getX(),mid1.getY(),mid2.getX(),mid2.getY(),x2,y2);
   }


   /**
    *   Set value of a curve. We will keep two control points poistion relative to two end points.    
    *
    *   @param startPoint Coordinates of start point.
    *   @param endPoint Coordinates of end point.
    *
    */ 	
   public void setValueByKeepingShape(JFPoint startPoint, JFPoint endPoint){
   	
   	//step 1, store the shape
   	
   	//distance from old start point to old end point.
   	double dist	=m_startPoint.distance(m_endPoint);
   	
   	//angle between the line that from start point to control point1 and horizontal line
   	double angle1	=Angle.getAngle(m_startPoint,m_controlPoint1,false);
   	//scale of that the distance from start point to control point1 compares to dist above.
   	double scale1	=m_startPoint.distance(m_controlPoint1)/dist;
   	//direction of that the vector from start point to the control point1 compares to the vector from start point to end point.
	boolean direction1 = JFVector.underClockwiseSide(m_startPoint,m_controlPoint1,m_startPoint,m_endPoint);   	
   	
   	//angle between the line that from start point to control point2 and horizontal line
   	double angle2	=Angle.getAngle(m_startPoint,m_controlPoint2,false);
   	//scale that the distance from start point to control point2 compares to dist above.
   	double scale2	=m_startPoint.distance(m_controlPoint2)/dist;
   	//direction of that the vector from start point to the control point2 compares to the vector from start point to end point.
	boolean direction2 = JFVector.underClockwiseSide(m_startPoint,m_controlPoint2,m_startPoint,m_endPoint);   	
	
	//the angle between the line from start point to end point and horzontal line.
	double angleBase	=Angle.getAngle(m_startPoint,m_endPoint,false);
	
	//step 2, set new value to two endpoints.
	m_startPoint.setValue(startPoint);
	m_endPoint.setValue(endPoint);

   	//step 3, restore the shape
	dist		=m_startPoint.distance(m_endPoint);
	if ((float)dist==0)
		return;
	double dist1	=dist * scale1;
	double dist2	=dist *	scale2;

	//the angle between the line from start point to end point and horzontal line.
	double angleBase1	=Angle.getAngle(m_startPoint,m_endPoint,false);
	//angle increment
	angleBase1	-=angleBase;
	
	//new angle for controlpoints
	angle1		=Angle.getValidAngle(angle1+angleBase1);
	angle2		=Angle.getValidAngle(angle2+angleBase1);

	//new slope for line from start point to controlpoints
	double slope1	=0;
	int    angle_degree=(int)(angle1/Angle.PI*180);
	if (angle_degree==90 || angle_degree==270)
		slope1	=GeomConst.LARGE_VALUE;
	else
		slope1	=Math.tan(angle1);
		
	double slope2	=0;
	angle_degree=(int)(angle2/Angle.PI*180);
	if (angle_degree==90 || angle_degree==270)
		slope2	=GeomConst.LARGE_VALUE;
	else
		slope2	=Math.tan(angle2);


	JFPoint control1=m_startPoint.nearPoint(slope1,dist1,m_endPoint,direction1);
	JFPoint control2=m_startPoint.nearPoint(slope2,dist2,m_endPoint,direction2);
	if (control1!=null && control2!=null){
		m_controlPoint1.setValue(control1);
		m_controlPoint2.setValue(control2);
	}
   }



   //*****************  constructors *************************	

   /**
    *   Constructor for Curve.
    */ 	
   public Curve(){
   }

   /**
    *   Constructor for Curve.
    *   
    *   @param curve A Curve object.
    */ 	
   public Curve(Curve curve){
   	setValue(curve);
   }

   /**
    *   Constructor for Curve.
    *
    *   @param startPoint Coordinates of start point.
    *   @param controlPoint1 Coordinates of control point1.
    *   @param controlPoint2 Coordinates of control point2.
    *   @param endPoint Coordinates of end point.
    *
    */ 	
   public Curve(JFPoint startPoint, JFPoint controlPoint1, JFPoint controlPoint2, JFPoint endPoint){
   	setValue(startPoint,controlPoint1,controlPoint2,endPoint);
   }

   /**
    *   Constructor for Curve.
    *
    *   @param x1; y1 Coordinates of start point.
    *   @param x2; y2 Coordinates of control point1.
    *   @param x3; y3 Coordinates of control point2.
    *   @param x4; y4 Coordinates of end point.
    *
    */ 	
   public Curve(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4){
   	setValue(x1,y1,x2,y2,x3,y3,x4,y4);
   }


   //*****************  other methods *************************	

   /**
    *   Get the bounds of this curve.
    *
    *   @return The bounds rectangle.
    *
    */ 	
   public Rect getBounds(){

	double x1	=getX1();
	double y1	=getY1();
	double x2	=getX2();
	double y2	=getY2();
	double x3	=getX3();
	double y3	=getY3();
	double x4	=getX4();
	double y4	=getY4();

   	double minX	=Math.min(Math.min(x1,x2),Math.min(x3,x4));
   	double minY	=Math.min(Math.min(y1,y2),Math.min(y3,y4));
   	double maxX	=Math.max(Math.max(x1,x2),Math.max(x3,x4));
   	double maxY	=Math.max(Math.max(y1,y2),Math.max(y3,y4));
   	
   	return new Rect(minX,minY,maxX-minX,maxY-minY);
   }


   /**
    *   Get the center of this curve.
    *
    *   @return The center.
    *
    */ 	
   public JFPoint getCenter(){

	double x1	=getX1();
	double y1	=getY1();
	double x2	=getX2();
	double y2	=getY2();
	double x3	=getX3();
	double y3	=getY3();
	double x4	=getX4();
	double y4	=getY4();

   	double minX	=Math.min(Math.min(x1,x2),Math.min(x3,x4));
   	double minY	=Math.min(Math.min(y1,y2),Math.min(y3,y4));
   	double maxX	=Math.max(Math.max(x1,x2),Math.max(x3,x4));
   	double maxY	=Math.max(Math.max(y1,y2),Math.max(y3,y4));
   	
   	return new JFPoint((minX+maxX)/2,(minY+maxY)/2);
   }

 
   /**
    *   Test if a point is on the outline of this curve.
    *
    *   @param pnt A point to be measured.
    *
    *   @return True if the point is on the outline of this curve, false otherwise.
    *
    */ 	
   public boolean contains(JFPoint pnt){
   	return contains(pnt.getX(),pnt.getY());
   }

   /**
    *   Test if a point is on the outline of this curve.
    *
    *   @param x; y A point to be measured.
    *
    *   @return True if the point is on the outline of this curve, false otherwise.
    *
    */ 	
   public boolean contains(double x, double y){
	return contains(x,y,0);
   }

   /**
    *   Test if a point is on the outline of this curve.
    *
    *   @param pnt A point to be measured.
    *
    *   @param pickOffset An analog offset for 'pick' this curve.
    *
    *   @return True if the point is on the outline of this curve, false otherwise.
    *
    */ 	
   public boolean contains(JFPoint pnt,double pickOffset){
   	return contains(pnt.getX(),pnt.getY(),pickOffset);
   }

   /**
    *   Test if a point is on the outline of this curve.
    *
    *   @param x; y A point to be measured.
    *
    *   @param pickOffset An analog offset for 'pick' this curve.
    *
    *   @return True if the point is on the outline of this curve, false otherwise.
    *
    */ 	
    public boolean contains(double x, double y, double pickOffset){
   	if (m_startPoint.distance(x,y)<=pickOffset ||
   	   // m_controlPoint1.distance(x,y)<=pickOffset ||
   	    // m_controlPoint2.distance(x,y)<=pickOffset ||
   	    m_endPoint.distance(x,y)<=pickOffset)
   	    return true;	
	
	JFPoint pnt	=intersectsAt(x,y,pickOffset);
	return pnt!=null;
    }   	    


   /**
    *   Test if current curve intersects the point at a position.
    *
    *   @param x;&nbsp;y A point to be measured.
    *   @param pickOffset An analog offset for 'pick' this curve.
    *   @return A result curvePoint that represents an intersected point.
    *
    */ 	
   public JFCurvePoint intersectsAt(double x, double y, double pickOffset){

	double x1	=getX1();
	double y1	=getY1();
	double x2	=getX2();
	double y2	=getY2();
	double x3	=getX3();
	double y3	=getY3();
	double x4	=getX4();
	double y4	=getY4();
	
	return intersectsAt(x,y,x1,y1,x2,y2,x3,y3,x4,y4,pickOffset);
   }


   /**
    *   Test if current curve intersects the point at a position.
    *
    *   @param x;&nbsp;y A point to be measured.
    *   @param x1,y1   A start point of a bezier curve.
    *   @param x2,y2   A first control point of a bezier curve.
    *   @param x3,y3   A second control point of a bezier curve.
    *   @param x4,y4   An end point of a bezier curve.
    *	    
    *   @param pickOffset An analog offset for 'pick' this curve.
    *
    *   @return A result curvePoint that represents an intersected point.
    *
    */ 	
   public static JFCurvePoint intersectsAt(double x, double y, 
   				      double x1,double y1, 
   				      double x2, double y2, 
   				      double x3, double y3, 
   				      double x4, double y4,
   				      double pickOffset){
	
	JFCurvePoint	resultPoint	=new JFCurvePoint();	
	JFPoint pnt	=new JFPoint();

	pnt.setValue(x1,y1);
   	if (pnt.distance(x,y)<=pickOffset){
   		resultPoint.setValue(x1,y1);
   		resultPoint.setTimeInterval(0);
   		return resultPoint;
   	}

	pnt.setValue(x4,y4);
   	if (pnt.distance(x,y)<=pickOffset){
   		resultPoint.setValue(x4,y4);
   		resultPoint.setTimeInterval(1);
   		return resultPoint;
   	}


	double startX, startY, endX, endY; 
	LineSeg line	=new LineSeg();
	
	
	//start to test point on the whole outline of curve.		
	startX	=x1;
	startY	=y1;
	
 	double t; //the time interval 
	double k = .025; //time step value for drawing curve 
	
	for(t=k;t<=1+k;t+=k){ 
 		//use Bernstein polynomials 
 		endX=(x1+t*(-x1*3+t*(3*x1-x1*t)))+
 		      t*(3*x2+t*(-6*x2+ x2*3*t))+t*t*(x3*3-x3*3*t)+ 
 		     x4*t*t*t; 
 		     
 		endY=(y1+t*(-y1*3+t*(3*y1-y1*t)))+
 		     t*(3*y2+t*(-6*y2+ y2*3*t))+t*t*(y3*3-y3*3*t)+ 
 		   y4*t*t*t; 
		
		line.setPoint1(startX,startY);
		line.setPoint2(endX,endY);
		
		if (line.contains(x,y,GeomConst.PICK_OFFSET)){
			resultPoint.setValue(endX,endY);
			resultPoint.setTimeInterval(t);
			return resultPoint;
		}
		 		
 		startX	=endX;
 		startY	=endY;
 	} 
 	
 	return null;
   }


   /**
    *   Get a point by time interval.
    *
    *   @param interval A time interval on this curve.
    *   @return The point on the curve.
    *
    */ 	
   public JFPoint getPoint(double interval){
	double x1	=getX1();
	double y1	=getY1();
	double x2	=getX2();
	double y2	=getY2();
	double x3	=getX3();
	double y3	=getY3();
	double x4	=getX4();
	double y4	=getY4();
	return getPoint(x1,y1,x2,y2,x3,y3,x4,y4,interval);
   }


   /**
    *   Get a point by time interval.
    *
    *   @param x1,y1   A start point of a bezier curve.
    *   @param x2,y2   A first control point of a bezier curve.

⌨️ 快捷键说明

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