rect.java
来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,488 行 · 第 1/4 页
JAVA
1,488 行
//slope of the line from current vertex to friend vertex.
slope1 = (peerFriendVertex.getY()-peerVertex.getY())/(peerFriendVertex.getX()-peerVertex.getX());
//slope of the upright line.
slope2 = -1/slope1;
//center of the line from peerVertex to peer friend vertex.
JFPoint friendMiddle =peerVertex.midPoint(peerFriendVertex);
double uprightX=0;
double uprightY=0;
uprightX = (slope1 * x - y - slope2 * friendMiddle.getX()+friendMiddle.getY()) / (slope1 - slope2);
uprightY = slope1 * (uprightX - x) + y;
JFPoint _currPoint =new JFPoint(x,y);
JFPoint _uprightPoint =new JFPoint(uprightX,uprightY);
double dist =_currPoint.distance(_uprightPoint);
JFPoint newPoint =_currPoint.nearPoint(_uprightPoint,dist * 2,true);
newx =newPoint.getX();
newy =newPoint.getY();
}
break;
}
//temporary line.
//LineSeg line1=new LineSeg();
//JFPoint upright1=null;
/*
//line that current point to peer vertex
line1.setPoint1(x,y);
line1.setPoint2(peerVertex);
upright1 =line1.uprightFoot(newx,newy);
if (upright1==null || upright1.distance(newx,newy)<=GeomConst.MIN_LINELENGTH) return;
//line that peer vertex to peer friend vertex.
line1.setPoint1(peerVertex);
line1.setPoint2(peerFriendVertex);
upright1 =line1.uprightFoot(newx,newy);
if (upright1==null || upright1.distance(newx,newy)<=GeomConst.MIN_LINELENGTH) return;
upright1 =line1.uprightFoot(x,y);
if (upright1==null || upright1.distance(x,y)<=GeomConst.MIN_LINELENGTH) return;
*/
if (requireChangePeerVertex){
JFPoint pnt=new JFPoint(newx1,newy1);
if ( pnt.distance(x,y)>GeomConst.MIN_LINELENGTH){
friendVertex.setValue(newx,newy);
peerVertex.setValue(newx1,newy1);
currentVertex.setValue(x,y);
}
}else{
//line that current point to peer vertex
JFPoint tmp =new JFPoint();
tmp.setValue(peerVertex);
if (tmp.distance(x,y)<=GeomConst.MIN_LINELENGTH) return;
tmp.setValue(x,y);
if (tmp.distance(newx,newy)<=GeomConst.MIN_LINELENGTH) return;
tmp.setValue(peerFriendVertex);
if (tmp.distance(newx,newy)<=GeomConst.MIN_LINELENGTH) return;
friendVertex.setValue(newx,newy);
currentVertex.setValue(x,y);
}
}
/**
* Get a side line of this rectangle.
*
* @return A side line.
*
*/
public LineSeg getSide(int sideType){
switch(sideType){
case SIDETYPE_LEFT: //the line constructed by left-top vertex and left-bottom vertex
return new LineSeg(m_leftBottom,m_leftTop);
case SIDETYPE_TOP: //the line constructed by left-top vertex and right-top vertex
return new LineSeg(m_leftTop,m_rightTop);
case SIDETYPE_RIGHT: //the line constructed by right-top vertex and right-bottom vertex
return new LineSeg(m_rightTop,m_rightBottom);
case SIDETYPE_BOTTOM: //the line constructed by left-bottom vertex and right-bottom vertex
return new LineSeg(m_rightBottom,m_leftBottom);
default:
return null;
}
}
/**
* Get a center point of this rectangle.
*
* @return The center point.
*
*/
public JFPoint getCenter(){
//we use the intersects point of two diagonals as the center of a rectangle.
LineSeg line1 =new LineSeg(m_leftTop,m_rightBottom);
JFPoint center =line1.intersectsAt(m_leftBottom,m_rightTop);
if (center==null){
return new JFPoint(getX()+getWidth()/2, getY()+getHeight()/2);
}else{
return center;
}
}
/**
* 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();
/*** firstly scale all points of this rectangle according to center ***/
m_leftTop.scaleBy(center.getX(),center.getY(),scale);
m_rightTop.scaleBy(center.getX(),center.getY(),scale);
m_leftBottom.scaleBy(center.getX(),center.getY(),scale);
m_rightBottom.scaleBy(center.getX(),center.getY(),scale);
JFPoint newCenter =newScaleCenter(center,basePoint,refPoint1,refPoint2,scale);
//move center
moveBy(newCenter.getX()-center.getX(),newCenter.getY()-center.getY());
}
/**
* Scale current object by a specified x and y scale.<br>
* This is a special scale method used to scale a shape in arbitrary x and y scale.<br>
* Please see AbstractShape.scaleBy for detailed description.
*
* @param basePoint A base scale point for scaling reference.
* @param xScale A scale percentage in x coordinate, default to 1.0
* @param yScale A scale percentage in y coordinate, default to 1.0
*
*/
public void scaleBy(JFPoint basePoint,double xScale, double yScale){
if (basePoint==null)
return;
double x =basePoint.getX();
double y =basePoint.getY();
//if this rectangle has been rotated, we all choose a smaller scale for instead
//Attention: Shape at a rotatation under 0, PI/2, PI, 3PI/2,2PI degrees would
//also be considered as an un-rotated shape
if ((int)m_leftTop.getX()!=(int)m_leftBottom.getX() &&
(int)m_leftTop.getY()!=(int)m_leftBottom.getY()){
xScale =Math.min(xScale,yScale);
yScale =xScale;
}
m_leftTop.scaleBy(x,y,xScale,yScale);
m_rightTop.scaleBy(x,y,xScale,yScale);
m_leftBottom.scaleBy(x,y,xScale,yScale);
m_rightBottom.scaleBy(x,y,xScale,yScale);
}
/**
* When a shape is scaled, its location center will be changed probably.
* so we need to canculate its new center acorrding to these scale parameters.
*
* @param center An old center of the scaled object.
* @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 static JFPoint newScaleCenter(JFPoint center, JFPoint basePoint, JFPoint refPoint1, JFPoint refPoint2, double scale){
/*** then move all points by an offset. ***/
LineSeg line =new LineSeg();
//upright foot that an upright projective point from center to line1
line.setValue(basePoint,refPoint1);
JFPoint foot1 =line.uprightFoot(center.getX(),center.getY());
//upright foot that an upright projective point from center to line2
line.setValue(basePoint,refPoint2);
JFPoint foot2 =line.uprightFoot(center.getX(),center.getY());
//clockwise?
boolean clockwise =JFVector.underClockwiseSide(foot1,center,foot1,foot2);
//new foot1
foot1 =basePoint.nearPoint(refPoint1,basePoint.distance(foot1)*scale,true);
//new foot2
foot2 =basePoint.nearPoint(refPoint2,basePoint.distance(foot2)*scale,true);
//slope of the line from basePoit to refPoint2
double slope2 =basePoint.getSlope(refPoint2);
//a new center of this rectangle
return foot1.nearPoint(slope2,basePoint.distance(foot2),foot2,clockwise);
}
/**
* Move this rectangle by specific x and y coordinates.
*
* @param x X coordiate to moveby.
*
* @param y Y coordiate to moveby.
*
*/
public void moveBy(double x, double y){
m_leftTop.moveBy(x,y);
m_rightTop.moveBy(x,y);
m_leftBottom.moveBy(x,y);
m_rightBottom.moveBy(x,y);
}
/**
* Rotate this rectangle by an angle theta.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(double theta){
//get center point of this rectangle.
JFPoint center =getCenter();
//rotate by center
rotateBy(center,theta);
}
/**
* Rotate this rectangle by a specified point and an angle theta.
* If rotate by a point, it's same as move this rectangle to a new position,
* and simultaneously rotate this rectangle under proper angle.
* Certainly this angle is also equal to theta.
*
* @param pnt A rotate center point.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(JFPoint pnt, double theta){
rotateBy(pnt.getX(),pnt.getY(),theta);
}
/**
* Rotate this line by a specified point and an angle theta.
*
* @param baseX, baseY A rotate center coordinates.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(double baseX,double baseY, double theta){
//rotate each vertex by rotate center point.
m_leftTop.rotateBy(baseX,baseY,theta);
m_rightTop.rotateBy(baseX,baseY,theta);
m_leftBottom.rotateBy(baseX,baseY,theta);
m_rightBottom.rotateBy(baseX,baseY,theta);
}
/**
* Mirror this rectangle by a central x coordinate of this rectangle. We make a up-down flip here.
*/
public void mirrorBy(){
JFPoint center =getCenter();
mirrorBy(center.getX());
}
/**
* Mirror this rectangle by a x coordinate. We make a left-right mirror here.
*
* @param baseX A mirror base x coordinate.
*
*/
public void mirrorBy(double baseX){
m_leftTop.mirrorBy(baseX);
m_rightTop.mirrorBy(baseX);
m_leftBottom.mirrorBy(baseX);
m_rightBottom.mirrorBy(baseX);
}
/**
* Reverse this rectangle by a central y coordinate of this rectangle. We make a up-down flip here.
*/
public void flipBy(){
JFPoint center =getCenter();
flipBy(center.getY());
}
/**
* Reverse this rectangle by a y coordinate. We make a up-down flip here.
*
* @param baseY A flip base y coordinate.
*
*/
public void flipBy(double baseY){
m_leftTop.flipBy(baseY);
m_rightTop.flipBy(baseY);
m_leftBottom.flipBy(baseY);
m_rightBottom.flipBy(baseY);
}
/**
* Test if a point is within this rectangle.
*
* @param pnt A point.
*
* @return True if the point is inside rectangle, false if not.
*
*/
public boolean contains(JFPoint pnt){
if (pnt==null)
return false;
else
return contains(pnt.getX(), pnt.getY());
}
/**
* Test if a point(x, y coordinates for instead) is within this rectangle.
*
* <p> The algorithm for testing if a point is within this rectangle is at below.
* <p>
* count = 0;
* [start at endpoint P, make an radial line L from right to left]
* for [each side S of this rectangle] do
* if [P is on one side S]
* then return true;
* if [side S is not a horizontal line]
* then if [one endpoint of S is on L]
* if [this endpoint is the max y coordinate of the two endpoints of S]
* then count = count+1
* else if [S interacts L]
* then count=count+1;
* if count mod 2 = 1
* then return true;
* else return false;
*
* @param x X coordinate of this point.
*
* @param y Y coordinate of this point.
*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?