Question

I am using SKShapeNodes to dynamically draw lines by updating the path property as the user touches the screen. Once the line is complete, I would like to append a new fixed length perpendicular line to the end of the path.

I have looked into CGAffineTransform to rotate the new line based on the end point of the path, but so far haven't had any luck. Any tips or insight would be much appreciated.

Some of my current code for reference looks like:

        - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        UITouch* touch = [touches anyObject];
        CGPoint positionInScene = [touch locationInNode:self];

        //add a line to the new coordinates the user moved to
        CGPathAddLineToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);
    }


-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//create local copy of path
CGPathRef myPath_ = pathToDraw;

CGPoint myPoint = CGPathGetCurrentPoint(pathToDraw);

//create rectangle to append to end of line        
CGRect newRect = CGRectMake(myPoint.x, myPoint.y, 25, 3);
CGPathRef newPath = CGPathCreateWithRect(newRect, NULL);

//add new line to the end of the path
CGPathAddPath(newPath, NULL, myPath_);

//set shape node path to drawn path        
lineNode.path = myPath_;
}
Was it helpful?

Solution

To get the perpendicular, you can take the vector pointing in the direction of the last line segment, then swap x and y, and invert one of them. Something like this:

CGPoint v = { currentPoint.x - lastPoint.x, currentPoint.y - lastPoint.y };
CGPoint perp;
if (v.x == 0)
{
    perp.x = -v.y;
    perp.y = v.x;
}
else
{
    perp.x = v.y;
    perp.y = -v.x;
}

Now you can draw a line in the direction of perp, starting at the current point, like this:

CGPathMoveToPoint (somePath, currentPoint);
CGPathAddLineToPoint (somePath, NULL, currentPoint.x + perp.x * length, currentPoint.y + perp.y * length);

where length is the length of the line segment you want to draw.

And don't forget to set lastPoint to currentPoint so it's correct the next time around:

lastPoint = currentPoint;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top