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 + -
显示快捷键?