2010-03-24 6 views
2

어도비 플렉스 3을 사용하여 다이어그램 도구를 만들고 있습니다. 나는 연결선을 구현하려고하는데 질문이 있습니다.플렉스 : 도형 사이의 연결선 그리기

캔버스의 임의의 위치에 2 개의 사각형이 있다고 가정 해보십시오. 그들 사이에 화살표가있는 연결선을 그려야합니다. 대상 광장의 중심으로 향하고 국경에서 끝내야합니다. alt text http://i44.tinypic.com/25tw4n4.jpg

줄을 그리는 정확한 지점을 어떻게 알 수 있습니까? 가장 간단한 것은 아마도 flash.geom.Point을 사용

답변

-1

감사합니다. 센터 c1c2 모두 가져 가십시오. 그 차이점은 벡터 d입니다. 각도 (315에서 45, 45에서 135, 135에서 225, 225에서 315)에 따라 어떤면이 포함되어 있는지 알 수 있습니다 (각각 좌우 : 상하 좌우, 상하, 상단).

그런 다음 각면과 가운데를 연결하는 선 간의 교차점을 계산합니다.

센터를 연결하는 선은 p=t*v+c1 (벡터로 말하기)로 표시 할 수 있습니다. 옆면을 선으로 표시 한 다음 두 방정식이 같은 점 p을 얻도록 t을 계산합니다.이 교차점은 찾고있는 교차점입니다.

5

다음은 원하는 작업의 예입니다.

package 
{ 
    import flash.display.Shape; 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.geom.Matrix; 
    import flash.geom.Point; 
    import flash.ui.Mouse; 

    /** 
    * Sample class to draw squares and arrows between them. 
    */ 
    public class SquareArrows extends Sprite 
    { 
     /** 
     * Initialize the scene as soon as we can. 
     */ 
     public function SquareArrows() 
     { 
      if(stage) { 
       init(); 
      } 
      else { 
       addEventListener(Event.ADDED_TO_STAGE, init); 
      } 
     } 

     /** 
     * Draw two squares and an arrow between them. 
     */ 
     private function init(e : Event = null) : void 
     { 
      if(hasEventListener(Event.ADDED_TO_STAGE)) { 
       removeEventListener(Event.ADDED_TO_STAGE, init); 
      } 

      // Drawing random-sized squares. 
      var squareOne : Shape = 
        getSquareShape((Math.random() * 50) + 20, 0xBBBBBB); 
      var squareTwo : Shape = 
        getSquareShape((Math.random() * 50) + 20, 0xDDDDDD); 
      addChild(squareOne); 
      addChild(squareTwo); 

      // Draw the connector. 
      var connector : Shape = getConnectorShape(squareOne, squareTwo); 
      addChild(connector); 
     } 

     /** 
     * Draw a connector arrow between two square shapes. 
     */ 
     private function getConnectorShape(connectFrom : Shape, connectTo : Shape) : Shape 
     { 
      // Getting the center of the first square. 
      var centerFrom : Point = new Point(); 
      centerFrom.x = connectFrom.x + (connectFrom.width/2); 
      centerFrom.y = connectFrom.y + (connectFrom.height/2); 

      // Getting the center of the second square. 
      var centerTo : Point = new Point(); 
      centerTo.x = connectTo.x + (connectTo.width/2); 
      centerTo.y = connectTo.y + (connectTo.height/2); 

      // Getting the angle between those two. 
      var angleTo : Number = 
       Math.atan2(centerTo.x - centerFrom.x, centerTo.y - centerFrom.y); 
      var angleFrom : Number = 
       Math.atan2(centerFrom.x - centerTo.x, centerFrom.y - centerTo.y); 

      // Getting the points on both borders. 
      var pointFrom : Point = getSquareBorderPointAtAngle(connectFrom, angleTo); 
      var pointTo : Point = getSquareBorderPointAtAngle(connectTo, angleFrom); 

      // Calculating arrow edges. 
      var arrowSlope : Number = 30; 
      var arrowHeadLength : Number = 10; 
      var vector : Point = 
       new Point(-(pointTo.x - pointFrom.x), -(pointTo.y - pointFrom.y)); 

      // First edge of the head... 
      var edgeOneMatrix : Matrix = new Matrix(); 
      edgeOneMatrix.rotate(arrowSlope * Math.PI/180); 
      var edgeOneVector : Point = edgeOneMatrix.transformPoint(vector); 
      edgeOneVector.normalize(arrowHeadLength); 
      var edgeOne : Point = new Point(); 
      edgeOne.x = pointTo.x + edgeOneVector.x; 
      edgeOne.y = pointTo.y + edgeOneVector.y; 

      // And second edge of the head. 
      var edgeTwoMatrix : Matrix = new Matrix(); 
      edgeTwoMatrix.rotate((0 - arrowSlope) * Math.PI/180); 
      var edgeTwoVector : Point = edgeTwoMatrix.transformPoint(vector); 
      edgeTwoVector.normalize(arrowHeadLength); 
      var edgeTwo : Point = new Point(); 
      edgeTwo.x = pointTo.x + edgeTwoVector.x; 
      edgeTwo.y = pointTo.y + edgeTwoVector.y; 

      // Drawing the arrow. 
      var arrow : Shape = new Shape(); 
      with(arrow.graphics) { 
       lineStyle(2); 
       // Drawing the line. 
       moveTo(pointFrom.x, pointFrom.y); 
       lineTo(pointTo.x, pointTo.y); 

       // Drawing the arrow head. 
       lineTo(edgeOne.x, edgeOne.y); 
       moveTo(pointTo.x, pointTo.y); 
       lineTo(edgeTwo.x, edgeTwo.y); 
      } 
      return arrow; 
     } 

     /** 
     * Utility method to get a point on a square border at a certain angle. 
     */ 
     private function getSquareBorderPointAtAngle(square : Shape, angle : Number) : Point 
     { 
      // Calculating rays of inner and outer circles. 
      var minRay : Number = Math.SQRT2 * square.width/2; 
      var maxRay : Number = square.width/2; 

      // Calculating the weight of each rays depending on the angle. 
      var rayAtAngle : Number = ((maxRay - minRay) * Math.abs(Math.cos(angle * 2))) + minRay; 

      // We have our point. 
      var point : Point = new Point(); 
      point.x = rayAtAngle * Math.sin(angle) + square.x + (square.width/2); 
      point.y = rayAtAngle * Math.cos(angle) + square.y + (square.height/2); 
      return point; 
     } 

     /** 
     * Utility method to draw a square of a given size in a new shape. 
     */ 
     private function getSquareShape(edgeSize : Number, fillColor : Number) : Shape 
     { 
      // Draw the square. 
      var square : Shape = new Shape(); 
      with(square.graphics) { 
       lineStyle(1); 
       beginFill(fillColor); 
       drawRect(0, 0, edgeSize, edgeSize); 
       endFill(); 
      } 

      // Set a random position. 
      square.x = Math.random() * (stage.stageWidth - square.width); 
      square.y = Math.random() * (stage.stageHeight - square.height); 

      return square; 
     } 
    } 
} 

이 코드는 완전히 최적화되지 않았습니다. 아이디어는 어떻게 작동하는지 더 설명합니다. 기본적으로 두 개의 (무작위) 사각형을 정의하고 그 사이에 선을 그립니다. 직선을 추적하려면 첫 번째 정사각형의 중심에서 두 번째 정사각형의 중심까지의 각도를 계산하고, 올바른 방법으로 정사각형 경계 위의 점을 추출하는 특수 방법 (getSquareBorderPointAtAngle)을 사용합니다.

이 방법은이 스 니펫의 첫 번째 요점입니다. 우리는 단순한 원형 지오메트리를 사용하여 그것을 계산합니다. 점을 만드는 방법에 대한 약간의 복합성을 가지고 사각형 주위 또는 원 안에 일치하는 원 대신 일치시킵니다.

그런 다음 화살표 머리를 그립니다. 이를 위해 플래시 Matrix 클래스를 사용하고 있습니다. 처음부터 플래시를 계산하는 것보다 훨씬 쉽기 때문입니다.

여기까지 완료되었습니다.

+0

는 사람을 완전히 끝내이 감사합니다! 나는 조금 정신이 나서 아직 시도하지 않았지만 그렇게 할 것이다. 대단히 감사합니다. – artemb

4

저는 같은 것을 필요로하기 때문에 한 달 전에 여기에서 답을 읽고있었습니다. 그 사이에이 커넥터 그림을 찾아서 링크를 공유 할 수 있다고 생각했습니다.

이 예에서는 uicomponents간에 커넥터 선을 그려 커넥터가 드래그 될 때 줄을 업데이트합니다. 좋은 분!

alt text http://sammyjoeosborne.com/Images/connectorImage.jpg

http://sammyjoeosborne.com/Examples/Connector/ConnectorExample.html