Search code examples
coordinateslinesparallelsactionscript-3

Draw 2 parallel lines between any 2 coordinates on the stage in AS3


I am developping a web application, basically its a simple version of Illustrator/Flash. So soccer trainers can make schemes.
I made different tools like in Photoshop (line tool, rectangle tool, ..). All of these work.

However now i need to develop a tool where the user can draw a double parallel line. I would like to be able to define the distance between those 2 lines in a variable. I need to draw 2 parallel lines between any 2 points on the stage. Like the line tool in Photoshop/Illustrator , but it draws 2 lines at once.


It should basically work like this
1) on mouse down:
create a new graphics object and register the X and Y where the user clicked. start to listen for Mouse Move.

2) on mouse move:
clear the graphics object, draw the double line from the original mouse position to the current mouse position. redraw on every mouse move.

3) on mouse up:
stop listening for events and add the double line to the stage.


This worked perfectly for drawing a single line, but I'm having troubles with 2 parallel lines. They don't stay parallel to each other or the rotation doesn't work properly.


Solution

  • You will need to plot the points this way:

    90 degrees (UP from the START point)        90 degrees (UP from the END point)
    |                                                                            |
    START- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - END
    |                                                                            |
    90 degrees (DOWN from the START point)    90 degrees (DOWN from the END point)
    

    Once you determine those 6 points (2 for the top-line, 2 for the mouse start and end, and 2 for the bottom-line), you can join the pair of points for the top-line and bottom-line together with a lineTo(...) command to give you this:

    ------------------------------------------------------------------------------
    
    START                                                                      END
    
    ------------------------------------------------------------------------------
    

    To know what is the current angle formed by your START and END point, you need the deltas (difference between two values) of your point's X and Y values.

    So X2 - X1 = DeltaX, and Y2 - Y1 = DeltaY.

    Then, put those deltas in Math.atan2(y:Number, x:Number):Number. The returned value is in radians I believe, so to work with degrees, you can do the conversion by multiplying the result with 180 / Math.PI.

    This won't be really necessary however, as we can resume the rest of the calculations in radians. It would be useful to store the above value (180/Math.PI) in a variable.

    If we continue with Radians, it is important to convert our 90 degrees to Radians.

    • 90 / radians gives us a number to offset from our START and END point to solve the top line.
    • -90 / radians gives us the number to offset from our START and END point to solve the bottom line.

    in other words...

    This is a whole solution that I quickly tested, I apologize if it doesn't work 100%:

    var startPoint:Point = new Point(10, 0); //Replace by start-mouse location
    var endPoint:Point = new Point(20, 0); //Replace by end-mouse location
    
    var mouseAngle:Number = Math.atan2( endPoint.y - startPoint.y, endPoint.x - startPoint.x );
    
    var angle:Number;
    var lineHalfGap:Number = 100 * .5; //Replace 100 by your seperation value
    var radians:Number = 180 / Math.PI;
    angle = 90 / radians + mouseAngle;
    var topOffsetX:Number = Math.cos( angle ) * lineHalfGap;
    var topOffsetY:Number = Math.sin( angle ) * lineHalfGap;
    angle = -90 / radians + mouseAngle;
    var bottomOffsetX:Number = Math.cos( angle ) * lineHalfGap;
    var bottomOffsetY:Number = Math.sin( angle ) * lineHalfGap;
    
    var topStart:Point = new Point(startPoint.x + topOffsetX, startPoint.y + topOffsetY);
    var topEnd:Point = new Point(endPoint.x + topOffsetX, endPoint.y + topOffsetY);
    
    var bottomStart:Point = new Point(startPoint.x + bottomOffsetX, startPoint.y + bottomOffsetY);
    var bottomEnd:Point = new Point(endPoint.x + bottomOffsetX, endPoint.y + bottomOffsetY);
    
    trace(topStart, topEnd, bottomStart, bottomEnd);
    

    Obviously there's a few variables you will have to replace / substitute for your own (like the mouse locations and the separation value for your line gap), but this should do the trick.

    A running example can be found here:

    http://pierrechamberlain.ca/blog/2012/08/math-101-parallel-lines-two-points/