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;&nbsp;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,&nbsp;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 + -
显示快捷键?