polyline.java
来自「用Java开发的、实现类似Visio功能的应用程序源码」· Java 代码 · 共 1,251 行 · 第 1/3 页
JAVA
1,251 行
midy =(firstNode.getY()+lastNode.getY())/2;
m_nodeList.add(new JFPointNode(midx,midy,JFPointNode.NODETYPE_MIDDLE));
}
//try to combine lines
if (getEndNodeCount()<4)
return true;
JFPointNode lastPriorNode =getNextNode(lastNode,true);
JFPointNode firstNextNode =getNextNode(firstNode,false);
boolean sameEnd =sameSlope(firstNode.getX(),firstNode.getY(),lastNode.getX(),lastNode.getY(),lastPriorNode.getX(),lastPriorNode.getY());
boolean sameStart =sameSlope(firstNextNode.getX(),firstNextNode.getY(),firstNode.getX(),firstNode.getY(),lastNode.getX(),lastNode.getY());
int nodeIndex=0;
int i=0;
//combine the line segments beside lastNode
if (sameEnd){
nodeIndex =getNodeIndex(lastPriorNode);
for (i=m_nodeList.size()-1; i>nodeIndex; i--){
removeNode(i);
}
distance =lastPriorNode.distance(firstNode);
if (distance>=MIN_LINELENGTH_SEGMENT){
midx =(firstNode.getX()+lastPriorNode.getX())/2;
midy =(firstNode.getY()+lastPriorNode.getY())/2;
m_nodeList.add(new JFPointNode(midx,midy,JFPointNode.NODETYPE_MIDDLE));
}
}
if (getEndNodeCount()<4)
return true;
//combine the line segments beside firstNode
if (sameStart){
lastNode =getLastNode(true);
if (lastNode!=null && lastNode.getNodeType()==JFPointNode.NODETYPE_MIDDLE){
removeNode(m_nodeList.size()-1);
lastNode =getLastNode(true);
}
nodeIndex =getNodeIndex(firstNextNode);
for (i=nodeIndex-1; i>=0; i--){
removeNode(i);
}
distance =firstNextNode.distance(lastNode);
if (distance>=MIN_LINELENGTH_SEGMENT){
midx =(firstNextNode.getX()+lastNode.getX())/2;
midy =(firstNextNode.getY()+lastNode.getY())/2;
m_nodeList.add(new JFPointNode(midx,midy,JFPointNode.NODETYPE_MIDDLE));
}
}
return true;
}
/**
* Cancel last node.
*/
public void cancelLastNode(){
if (m_nodeList.size()==0)
return;
JFPointNode lastNode =getLastNode(true);
JFPointNode lastSecNode =getNextNode(lastNode,true);
if (lastSecNode==null){
clearNodes();
}else{
int nodeIndex =getNodeIndex(lastSecNode);
int i=m_nodeList.size()-1;
while (i>nodeIndex){
removeNode(i--);
}
}
}
/**
* replace last node. and concurrently adjust the relational points.
* @param x; y A new node.
*/
public void replaceLastNode(double x, double y){
cancelLastNode();
addNode(x,y);
}
/**
* Constructor for PolyLine.
*
*/
public PolyLine(){
}
/**
* Constructor for PolyLine.
*
* @param line A polyline.
*
*/
public PolyLine(PolyLine line){
if (line!=null){
setNodeList(line.getNodeList());
m_polyState =line.m_polyState;
}
}
/**
* Constructor for PolyLine.
*
* @param xpoints an array of x coordinates
* @param ypoints an array of y coordinates
* @param npoints the total number of points in the Polygon
*
*/
public PolyLine(int[] xpoints, int[] ypoints, int npoints){
setNodeList(xpoints,ypoints,npoints);
}
/**
* Get the bounds of this polyline.
*
* @return The bounds rectangle.
*
*/
public Rect getBounds(){
double minX=GeomConst.LARGE_VALUE;
double minY=GeomConst.LARGE_VALUE;
double maxX=-GeomConst.LARGE_VALUE;
double maxY=-GeomConst.LARGE_VALUE;
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
minX =Math.min(minX,node.getX());
minY =Math.min(minY,node.getY());
maxX =Math.max(maxX,node.getX());
maxY =Math.max(maxY,node.getY());
}
if (minX>maxX) minX =maxX;
if (minY>maxY) minY =maxY;
return new Rect(minX,minY,maxX - minX, maxY - minY);
}
/**
* Get a center point on this line.
*
* @return The center point.
*
*/
public JFPoint getCenter(){
Rect rect =getBounds();
return new JFPoint(rect.getX()+rect.getWidth()/2, rect.getY()+rect.getHeight()/2);
}
/**
* Scale current polyline 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();
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
node.scaleBy(center.getX(),center.getY(),scale);
}
JFPoint newCenter =Rect.newScaleCenter(center,basePoint,refPoint1,refPoint2,scale);
//move center
moveBy(newCenter.getX()-center.getX(),newCenter.getY()-center.getY());
}
/**
* Scale current polyLine 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();
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
node.scaleBy(x,y,xScale,yScale);
}
}
/**
* Move this line 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){
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
node.moveBy(x,y);
}
}
/**
* Rotate this line by an angle theta.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(double theta){
//the center point on this line
JFPoint center =getCenter();
rotateBy(center,theta);
}
/**
* Rotate this line by a specified point and an angle theta.
*
* @param pnt A rotate center point.
*
* @param theta A rotate angle.
*
*/
public void rotateBy(JFPoint pnt, double theta){
if (pnt==null)
return;
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){
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
node.rotateBy(baseX,baseY,theta);
}
}
/**
* Mirror this line by a central x coordinate of this line. We make a up-down reverse here.
*/
public void mirrorBy(){
JFPoint center =getCenter();
mirrorBy(center.getX());
}
/**
* Mirror this line by a x coordinate. We make a left-right mirror here.
*
* @param baseX A mirror base x coordinate.
*
*/
public void mirrorBy(double baseX){
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
node.mirrorBy(baseX);
}
}
/**
* Reverse this line by a central y coordinate of this line. We make a up-down flip here.
*/
public void flipBy(){
JFPoint center =getCenter();
flipBy(center.getY());
}
/**
* Reverse this line by a y coordinate. We make a up-down flip here.
*
* @param baseY A flip base y coordinate.
*
*/
public void flipBy(double baseY){
Iterator it =m_nodeList.iterator();
while (it!=null && it.hasNext()){
JFPointNode node=(JFPointNode)it.next();
node.flipBy(baseY);
}
}
/**
* Test if a point is on this line.
*
* @param pnt A point to be measured.
*
* @return True if the point is on this line, false otherwise.
*
*/
public boolean contains(JFPoint pnt){
if (pnt==null)
return false;
else
return contains(pnt,0);
}
/**
* Test if a point is on this line.
* Here we used an analog offset for 'pick' this line.
*
* @param pnt A point to be measured.
*
* @param pickOffset An analog offset for 'pick' this line.
*
* @return True if the point is on this line, false otherwise.
*
*/
public boolean contains(JFPoint pnt,double pickOffset){
if (pnt==null)
return false;
else
return contains(pnt.getX(),pnt.getY(),pickOffset);
}
/**
* Test if a point(x, y coordinates for instead) is on this line.
* @param x X coordinate of this point.
*
* @param y Y coordinate of this point.
*
* @return True if the point is on this line, false otherwise.
*
*/
public boolean contains(double x, double y){
return contains(x,y,0);
}
/**
* Test if a point(x, y coordinates for instead) is on this line.
* Here we used an analog offset for 'pick' this line.
*
* @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 True if the point is on this line, false otherwise.
*
*/
public boolean contains(double x, double y,double pickOffset){
//test if this point picked any line segment of this polyline.
if (pickLine(x,y,pickOffset)!=null)
return true;
LineSeg line =new LineSeg();
JFPointNode lastNode=getNode(0);
JFPointNode node;
if (lastNode==null)
return false;
int i=0;
//if it's polygon, we will test if the point is inside the polygon here.
if (isPolygon()){
//we make a left radius line start at x,y here,
//then test if any side of the polygon intersects this radius line.
LineSeg radiusLine =new LineSeg();
radiusLine.setValue(x,y,x-GeomConst.LARGE_VALUE,y);
int intersectNum=0;
lastNode =getNode(0);
i=1;
while (i<m_nodeList.size()){
node=getNode(i);
if (node.getNodeType()==JFPointNode.NODETYPE_MIDDLE){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?