rect.java
来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,488 行 · 第 1/4 页
JAVA
1,488 行
* @return True if the point is inside this rectangle, false otherwise.
*
*/
public boolean contains(double x, double y){
//if regular rectangle.
if (m_leftTop.getX()==m_leftBottom.getX() &&
m_leftTop.getY()==m_rightTop.getY() &&
m_rightTop.getX()==m_rightBottom.getX() &&
m_leftBottom.getY()==m_rightBottom.getY()){
double x0 = getX();
double y0 = getY();
return (x >= x0 &&
y >= y0 &&
x <= x0 + getWidth() &&
y <= y0 + getHeight());
//rectangle has been rotated or scaled.
}else{
//each side of rectangle
LineSeg side=null;
//radial line from this point to left
LineSeg radialLine = new LineSeg(x,y,x-GeomConst.LARGE_VALUE,y);
//intersect points' number between radial line and rectangle
int intersectPoints =0;
//test each side of rectangle
for (int i = SIDETYPE_LEFT; i<=SIDETYPE_BOTTOM; i++){
//Because of getSide method will be overridden by subclasses, so here
//we get side directly by each corner point.
switch(i){
case SIDETYPE_LEFT: //the line constructed by left-top vertex and left-bottom vertex
side =new LineSeg(m_leftBottom,m_leftTop);
break;
case SIDETYPE_TOP: //the line constructed by left-top vertex and right-top vertex
side =new LineSeg(m_leftTop,m_rightTop);
break;
case SIDETYPE_RIGHT: //the line constructed by right-top vertex and right-bottom vertex
side =new LineSeg(m_rightTop,m_rightBottom);
break;
case SIDETYPE_BOTTOM: //the line constructed by left-bottom vertex and right-bottom vertex
side =new LineSeg(m_rightBottom,m_leftBottom);
break;
default:
continue;
}
//point is on one side of rectangle
if (side.contains(x,y))
return true;
//this side of rectangle is not a horizontal line
else if (side.getY1()!=side.getY2()){
//if one endpoint of side is on radial line
if (radialLine.contains(side.getX1(),side.getY1())){
if (side.getY1()>side.getY2()){
intersectPoints++;
}
}else if (radialLine.contains(side.getX2(),side.getY2())){
if (side.getY1()<side.getY2()){
intersectPoints++;
}
//if radialLine intersects the side
}else{
if (radialLine.intersects(side)){
intersectPoints++;
}
}
}
}
//if count mod 2 = 1 return true
return intersectPoints%2==1;
}
}
/**
* Pick a line segment of this rectangle by a point with a pickoffset.
* @param x X coordinate of this point.
* @param y Y coordinate of this point.
* @param pickOffset An analog pick offset that great equal than 0.
*
* @return A line segment picked.
*
*/
public LineSeg pickLine(double x, double y,double pickOffset){
LineSeg line =new LineSeg();
line.setPoint1(m_leftTop);
line.setPoint2(m_rightTop);
if (line.contains(x,y,pickOffset)) return line;
line.setPoint1(m_rightTop);
line.setPoint2(m_rightBottom);
if (line.contains(x,y,pickOffset)) return line;
line.setPoint1(m_rightBottom);
line.setPoint2(m_leftBottom);
if (line.contains(x,y,pickOffset)) return line;
line.setPoint1(m_leftBottom);
line.setPoint2(m_leftTop);
if (line.contains(x,y,pickOffset)) return line;
return null;
}
/**
* Test if current rectangle can add a port according to the position x,y.
* @param x X coordinate of the port.
* @param y Y coordinate of the port.
* @param startPoint,endPoint,portPoint Three major parameters of a port.
*
* @return True if can add a new port, false otherwise.
*
*/
public boolean canAddPort(double x, double y,JFPoint startPoint, JFPoint endPoint, JFPoint portPoint){
LineSeg line =pickLine(x,y,GeomConst.PICK_OFFSET);
if (line==null)
return false;
startPoint.setValue(line.getPoint1());
endPoint.setValue(line.getPoint2());
portPoint.setValue(line.uprightFoot(x,y));
return true;
}
/**
* Tests if the specified point intersects any side of this rectangle.
*
* @param pnt the specified point.
*
* @param pickOffset An analog offset for 'pick' this line.
*
* @return <code>true</code> if the specified point intersects one side of this rectangle.
* false otherwise.
*/
public boolean intersects(JFPoint pnt, int pickOffset) {
return intersects(pnt.getX(),pnt.getY(),pickOffset);
}
/**
* Tests if the specified point intersects any side of this rectangle.
*
* @param x1, y1 the specified point.
*
* @param pickOffset An analog offset for 'pick' this line.
*
* @return <code>true</code> if the specified point intersects one side of this rectangle.
* false otherwise.
*/
public boolean intersects(double x1, double y1, int pickOffset) {
LineSeg line =new LineSeg();
line.setPoint1(m_leftTop);
line.setPoint2(m_rightTop);
if (line.contains(x1,y1,pickOffset)) return true;
line.setPoint1(m_leftTop);
line.setPoint2(m_leftBottom);
if (line.contains(x1,y1,pickOffset)) return true;
line.setPoint1(m_leftBottom);
line.setPoint2(m_rightBottom);
if (line.contains(x1,y1,pickOffset)) return true;
line.setPoint1(m_rightBottom);
line.setPoint2(m_rightTop);
if (line.contains(x1,y1,pickOffset)) return true;
return false;
}
/**
* Tests if the specified line segment intersects the interior of this
* <code>Rect</code>.
* @param x1, y1 the first endpoint of the specified
* line segment
* @param x2, y2 the second endpoint of the specified
* line segment
* @return <code>true</code> if the specified line segment intersects
* the interior of this <code>Rect</code>; <code>false</code>
* otherwise.
*/
public boolean intersects(double x1, double y1, double x2, double y2) {
return intersects(new LineSeg(x1,y1,x2,y2));
}
/**
* Tests if the specified line segment intersects the interior of this
* <code>Rect</code>.
* @param line the specified {@link LineSeg} to test for intersection
* with the interior of this <code>Rect</code>
* @return <code>true</code> if the specified <code>LineSeg</code>
* intersects the interior of this <code>Rect</code>;
* <code>false</code> otherwise.
*/
public boolean intersects(LineSeg line) {
if (line==null)
return false;
else
return line.intersects(m_leftTop.getX(),m_leftTop.getY(),m_rightTop.getX(),m_rightTop.getY()) || //if the line intersects the top line of this rectangle.
line.intersects(m_leftTop.getX(),m_leftTop.getY(),m_leftBottom.getX(),m_leftBottom.getY()) || //if the line intersects the left line of this rectangle.
line.intersects(m_rightTop.getX(),m_rightTop.getY(),m_rightBottom.getX(),m_rightBottom.getY()) || //if the line intersects the right line of this rectangle.
line.intersects(m_leftBottom.getX(),m_leftBottom.getY(),m_rightBottom.getX(),m_rightBottom.getY()); //if the line intersects the bottom line of this rectangle.
}
/**
* Tests if the specified rectangle intersects the interior of this
* <code>Rect</code>.
* @param rect the specified {@link Rect} to test for intersection
* with the interior of this <code>Rect</code>
* @return <code>true</code> if the specified <code>Rect</code>
* intersects the interior of this <code>Rect</code>;
* <code>false</code> otherwise.
*/
public boolean intersects(Rect rect) {
LineSeg side =null;
//test if each side of rectangle intersects.
for (int i = SIDETYPE_LEFT; i<=SIDETYPE_BOTTOM; i++){
//Because of getSide method will be overridden by subclasses, so here
//we get side directly by each corner point.
switch(i){
case SIDETYPE_LEFT: //the line constructed by left-top vertex and left-bottom vertex
side =new LineSeg(rect.m_leftBottom,rect.m_leftTop);
break;
case SIDETYPE_TOP: //the line constructed by left-top vertex and right-top vertex
side =new LineSeg(rect.m_leftTop,rect.m_rightTop);
break;
case SIDETYPE_RIGHT: //the line constructed by right-top vertex and right-bottom vertex
side =new LineSeg(rect.m_rightTop,rect.m_rightBottom);
break;
case SIDETYPE_BOTTOM: //the line constructed by left-bottom vertex and right-bottom vertex
side =new LineSeg(rect.m_rightBottom,rect.m_leftBottom);
break;
default:
continue;
}
if (intersects(side))
return true;
}
//test if current rectangle is inside the target rectangle.
return rect.contains(getVertex(VERTEXTYPE_LEFTTOP)) ||
rect.contains(getVertex(VERTEXTYPE_RIGHTTOP)) ||
rect.contains(getVertex(VERTEXTYPE_LEFTBOTTOM)) ||
rect.contains(getVertex(VERTEXTYPE_RIGHTBOTTOM));
}
/**
* Convert this object to String
*
* @return An string represents the content of the object
*
*/
public String toString(){
StringBuffer buf =new StringBuffer();
buf.append(";leftTop="); buf.append(m_leftTop.getX()); buf.append(','); buf.append(m_leftTop.getY());
buf.append(";rightTop="); buf.append(m_rightTop.getX()); buf.append(','); buf.append(m_rightTop.getY());
buf.append(";leftBottom="); buf.append(m_leftBottom.getX()); buf.append(','); buf.append(m_leftBottom.getY());
buf.append(";rightBottom="); buf.append(m_rightBottom.getX()); buf.append(','); buf.append(m_rightBottom.getY());
buf.append(super.toString());
return buf.toString();
}
/**
* Creates a new object of the same class and with the same contents as this object.
*
* @return A clone of this instance.
*
*/
public Object clone() throws CloneNotSupportedException{
try{
return new Rect(this);
}catch(Exception e){
throw new CloneNotSupportedException(e.getMessage());
}
}
/**
* Returns the hashcode for this Object.
*
* @return hash code for this Point2D.
*
*/
public int hashCode(){
long x1 =Double.doubleToLongBits(m_leftTop.getX());
long y1 =Double.doubleToLongBits(m_leftTop.getY());
long x2 =Double.doubleToLongBits(m_rightTop.getX());
long y2 =Double.doubleToLongBits(m_rightTop.getY());
long x3 =Double.doubleToLongBits(m_leftBottom.getX());
long y3 =Double.doubleToLongBits(m_leftBottom.getY());
long x4 =Double.doubleToLongBits(m_rightBottom.getX());
long y4 =Double.doubleToLongBits(m_rightBottom.getY());
return super.hashCode() ^
(int)(x1 ^ (x1 >>> 32)) ^ (int)(y1 ^ (y1 >>> 32))^
(int)(x2 ^ (x2 >>> 32)) ^ (int)(y2 ^ (y2 >>> 32))^
(int)(x3 ^ (x3 >>> 32)) ^ (int)(y3 ^ (y3 >>> 32))^
(int)(x4 ^ (x4 >>> 32)) ^ (int)(y4 ^ (y4 >>> 32));
}
/**
* Determines whether or not two objects are equal.
*
* @param obj an object to be compared with this object
*
* @return true if the object to be compared is an instance of Port and has the same values; false otherwise.
*
*/
public boolean equals(Object obj){
if (!super.equals(obj))
return false;
if (obj == this)
return true;
if (!(obj instanceof Rect))
return false;
Rect rect =(Rect)obj;
return m_leftTop.equals(rect.getVertex(VERTEXTYPE_LEFTTOP)) &&
m_rightTop.equals(rect.getVertex(VERTEXTYPE_RIGHTTOP)) &&
m_leftBottom.equals(rect.getVertex(VERTEXTYPE_LEFTBOTTOM)) &&
m_rightBottom.equals(rect.getVertex(VERTEXTYPE_RIGHTBOTTOM));
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?