roundedrect.java

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

JAVA
642
字号
/**
 *    $Id:RoundedRect.java $
 *
 *    Copyright 2004 ~ 2005  JingFei International Cooperation LTD. All rights reserved. *
 */
package com.jfimagine.jfgraph.geom;

import com.jfimagine.jfgraph.geom.JFDimension;
import com.jfimagine.jfgraph.geom.JFPoint;
import com.jfimagine.jfgraph.geom.LineSeg;
import com.jfimagine.jfgraph.geom.Rect;
import com.jfimagine.jfgraph.geom.Arc;

 
 /**
 * RoundedRect class.  A class used to represent a rounded rectangle in the plane with double coordinates. 
 * A rounded rectangle will always be a regular rectangle, but not parallelogram or trapezoid.
 *   <p> Attention: Here we used a clockwise quadrant system.
 *   And the first quadrant is under right bottom corner.
 *
 * @author     CookieMaker    
 *
 * @version $Revision: 1.00 $
 */  
 public class RoundedRect extends Rect{

   /**
    *   radius of each rounded corner.
    */
   protected   double m_radius		=0;

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

   /**
    *   Constructor for RoundedRect.
    *   
    *   @param rect A rectangle object.
    *
    */ 	
   public RoundedRect(RoundedRect rect){
   	setValue(rect);
   }


   /**
    *   Constructor for RoundedRect.
    *
    *   @param x  X coordiate.
    *
    *   @param y  Y coordiate.
    *
    *   @param w  Width of this rectangle.
    *
    *   @param h  Height of this rectangle.
    *
    *   @param r  Radius of each rounded corner.
    *
    */ 	
   public RoundedRect(double x, double y, double w, double h, double r){
   	setValue(x,y,w,h,r);
   }

   /**
    *   Set the bounds of current rectangle.
    *
    *   @param x  X coordiate.
    *
    *   @param y  Y coordiate.
    *
    *   @param w  Width of this rectangle.
    *
    *   @param h  Height of this rectangle.
    *
    *   @param r  Radius of each rounded corner.
    *
    */ 	
   public void setValue(double x, double y, double w, double h,double r){
   	super.setValue(x,y,w,h);
   	m_radius	=r;	
   }


   /**
    *   Set the value of current rectangle.
    *
    *   @param rect A new rectangle.
    *
    */ 	
   public void setValue(Rect rect){
   	super.setValue(rect);
   	
   	if (rect!=null && (rect instanceof RoundedRect)){
   		m_radius	=((RoundedRect)rect).getRadius();
   	}
   }


   /**
    *   get the radius of current rounded rectangle.
    *
    *   @return The radius.
    *
    */ 	
   public double getRadius(){
   	return m_radius;
   }
 
   /**
    *   set the radius of current rounded rectangle.
    *
    *   @param radius The radius.
    *
    */ 	
   public void setRadius(double radius){
   	m_radius	=radius;
   }
   
   /**
    *   get an end point at the rounded corner curve.
    *
    *   @param startVertex The type of start vertex type.
    *
    *   @param endVertex The type of end vertex type.
    *
    *   @return The end point.
    *
    */ 	
   public JFPoint getCornerEndPoint(int startVertex,int endVertex){
   	JFPoint startPnt	=getVertex(startVertex);
   	JFPoint endPnt		=getVertex(endVertex);
   	return startPnt.nearPoint(endPnt,m_radius);
   }
   	
   /**
    *   get an end point at the rounded corner curve.
    *
    *   @param vertex The type of the vertex type.
    *
    *   @return The end point.
    *
    */ 	
   public JFPoint getCornerCenterPoint(int vertex){
   	JFPoint currPoint=getVertex(vertex);
   	
   	//get two end points.
   	JFPoint endPoint1=null,endPoint2=null;
   	switch (vertex){
   		case Rect.VERTEXTYPE_LEFTTOP:
   		case Rect.VERTEXTYPE_RIGHTBOTTOM:
   			endPoint1	=getVertex(Rect.VERTEXTYPE_RIGHTTOP);
   			endPoint2	=getVertex(Rect.VERTEXTYPE_LEFTBOTTOM);
   			break;
   		case Rect.VERTEXTYPE_RIGHTTOP:
   		case Rect.VERTEXTYPE_LEFTBOTTOM:
   			endPoint1	=getVertex(Rect.VERTEXTYPE_LEFTTOP);
   			endPoint2	=getVertex(Rect.VERTEXTYPE_RIGHTBOTTOM);
   			break;
   		default:
   			return null;
   	}
	
	//calculate two corner end points.
   	JFPoint cornerPoint1	=currPoint.nearPoint(endPoint1,m_radius);
   	JFPoint cornerPoint2	=currPoint.nearPoint(endPoint2,m_radius);
   	
   	if (endPoint1.getX()==currPoint.getX()){
   		return new JFPoint(cornerPoint2.getX(),cornerPoint1.getY());
   	}else if (endPoint1.getY()==currPoint.getY()){
   		return new JFPoint(cornerPoint1.getX(),cornerPoint2.getY());
   	}

   	//slope of current point related two sides.
   	double slope1	=(endPoint1.getY()-currPoint.getY())/(endPoint1.getX()-currPoint.getX());
   	double slope2	=(endPoint2.getY()-currPoint.getY())/(endPoint2.getX()-currPoint.getX());
   	
	//two line that across corner point1 or cornerPoint2, 
	//and parallel with lines from current point to endpoint1 or endpoint2.
	//y=k1(x-x1)+y1
	//y=k2(x-x2)+y2
	//so x=(y2-y1+k1*x1-k2*x2)/(k1-k2)
	double x 	=(cornerPoint2.getY() - cornerPoint1.getY() + slope1 * cornerPoint1.getX() - slope2 * cornerPoint2.getX())/(slope1-slope2);
	double y	=slope1 * (x - cornerPoint1.getX()) + cornerPoint1.getY();
	return new JFPoint(x,y);
   }

   /**
    *   get an rounded corner rectangle(include the rounded corner).
    *
    *   @param vertex The type of the vertex type.
    *
    *   @param rect  The return corner rectangle.
    *   note: the lefttop vertex of return is the corner vertex, 
    *   the rightTop vertex is the near point that under clockwise side of line from corner vertex to curve center,
    *   the rightBottom vertex is the center of corner curve,
    *   the leftBottom vertex is the near point that under counter-clockwise side of line from corner vertex to curve center.
    *
    */ 	
   public void getCornerRect(int vertex, Rect rect){
   	
   	//current corner center of arc
   	JFPoint cornerCenter	=getCornerCenterPoint(vertex);
   	
   	//current point on vertex
   	JFPoint thisPnt		=null;
   	//other two points of rectangle.
   	JFPoint pnt1=null,pnt2=null;

   	switch (vertex){
   		case Rect.VERTEXTYPE_LEFTTOP:
   			thisPnt	=m_leftTop;
   			pnt1	=thisPnt.nearPoint(m_rightTop,m_radius);
   			pnt2	=thisPnt.nearPoint(m_leftBottom,m_radius);
   			break;

   		case Rect.VERTEXTYPE_RIGHTTOP:
   			thisPnt	=m_rightTop;
   			pnt1	=thisPnt.nearPoint(m_rightBottom,m_radius);
   			pnt2	=thisPnt.nearPoint(m_leftTop,m_radius);
   			break;

   		case Rect.VERTEXTYPE_RIGHTBOTTOM:
   			thisPnt	=m_rightBottom;
   			pnt1	=thisPnt.nearPoint(m_leftBottom,m_radius);
   			pnt2	=thisPnt.nearPoint(m_rightTop,m_radius);
   			break;

   		case Rect.VERTEXTYPE_LEFTBOTTOM:
   			thisPnt	=m_leftBottom;
   			pnt1	=thisPnt.nearPoint(m_leftTop,m_radius);
   			pnt2	=thisPnt.nearPoint(m_rightBottom,m_radius);
   			break;
   	}
   	

	//get a corner rectangle
	//1)current vertex is on left-top vertex of the corner rectangle
	//2)start point of arc is on right-top vertex of the corner rectangle
	//3)center point of arc is on right-bottom vertex of the corner rectangle
	//4)end point of arc is on left-bottom vertex of the corner rectangle
   	rect.setVertex(Rect.VERTEXTYPE_LEFTTOP,thisPnt);
   	rect.setVertex(Rect.VERTEXTYPE_RIGHTTOP,pnt1);
   	rect.setVertex(Rect.VERTEXTYPE_RIGHTBOTTOM,cornerCenter);
   	rect.setVertex(Rect.VERTEXTYPE_LEFTBOTTOM,pnt2);
 	
   }

   /**
    *   get an rounded corner arc.
    *
    *   @param vertex The type of the vertex type.
    *
    *   @return The corner arc.
    *
    */ 	
   public Arc getCornerArc(int vertex){
	//get a corner rectangle
	//1)current vertex is on left-top vertex of the corner rectangle
	//2)start point of arc is on right-top vertex of the corner rectangle
	//3)center point of arc is on right-bottom vertex of the corner rectangle
	//4)end point of arc is on left-bottom vertex of the corner rectangle
	Rect rect	=new Rect();
	getCornerRect(vertex,rect);
	return getCornerArc(rect);
   }


   /**
    *   get an rounded corner arc.
    *
    *   @param rect A rectangle that is a rounded corner rectangle.
    *
    *   @return The corner arc.
    *
    */ 	
   private Arc getCornerArc(Rect rect){

	//get four vertexs of this new corner rectangle.
	JFPoint leftTop		=rect.getVertex(Rect.VERTEXTYPE_LEFTTOP);
	JFPoint rightTop	=rect.getVertex(Rect.VERTEXTYPE_RIGHTTOP);
	JFPoint rightBottom	=rect.getVertex(Rect.VERTEXTYPE_RIGHTBOTTOM);
	JFPoint leftBottom	=rect.getVertex(Rect.VERTEXTYPE_LEFTBOTTOM);
	
	if (JFVector.underClockwiseSide(leftTop,leftBottom,leftTop,rightTop)){
		//the line from leftTop to leftBottom is under clockwise side of the line from leftTop to rightTop.
		return new Arc(rightBottom,rightTop,Angle.PI/2);
	}else{
		return new Arc(rightBottom,rightTop,-1 * Angle.PI/2);
	}
   }


   /**
    *   Get a side line of this rectangle.
    *   We we must consider each side will be shorten by two 'RADIUS' distances of the rounded corner.
    *
    *   @return A side line.
    *
    */ 	
   public LineSeg getSide(int sideType){

	JFPoint pnt1=null, pnt2=null;   	
   	switch(sideType){
   		case  SIDETYPE_LEFT: //the line constructed by left-top vertex and left-bottom vertex,trucated the two end 'RADIUS' distance.
   			pnt1	=m_leftTop.nearPoint(m_leftBottom,m_radius);
   			pnt2	=m_leftBottom.nearPoint(m_leftTop,m_radius);
   			break;

   		case  SIDETYPE_TOP: //the line constructed by left-top vertex and right-top vertex,trucated the two end 'RADIUS' distance.
   			pnt1	=m_leftTop.nearPoint(m_rightTop,m_radius);
   			pnt2	=m_rightTop.nearPoint(m_leftTop,m_radius);
   			break;

   		case  SIDETYPE_RIGHT: //the line constructed by right-top vertex and right-bottom vertex,trucated the two end 'RADIUS' distance.
   			pnt1	=m_rightTop.nearPoint(m_rightBottom,m_radius);
   			pnt2	=m_rightBottom.nearPoint(m_rightTop,m_radius);
   			break;
   			

⌨️ 快捷键说明

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