Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6087253
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T11:50:59+00:00 2026-05-23T11:50:59+00:00

I would like to allow the user to draw curves in such a way

  • 0

I would like to allow the user to draw curves in such a way that no line can cross another line or even itself. Drawing the curves is no problem, and I even found that I can create a path that is closed and still pretty line-like by tracing the nodes of the line forwards and back and then closing the path.

Unfortunately, iOS only provides a test for whether a point is contained in a closed path (containsPoint: and CGPathContainsPoint). Unfortunately, a user can pretty easily move their finger fast enough that the touch points land on both sides of an existing path without actually being contained by that path, so testing the touch points is pretty pointless.

I can’t find any “intersection” of paths method.

Any other thoughts on how to accomplish this task?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T11:51:00+00:00Added an answer on May 23, 2026 at 11:51 am

    Well, I did come up with a way to do this. It is imperfect, but I thought others might want to see the technique since this question was upvoted a few times. The technique I used draws all the items to be tested against into a bitmap context and then draws the new segment of the progressing line into another bitmap context. The data in those contexts is compared using bitwise operators and if any overlap is found, a hit is declared.

    The idea behind this technique is to test each segment of a newly drawn line against all the previously drawn lines and even against earlier pieces of the same line. In other words, this technique will detect when a line crosses another line and also when it crosses over itself.

    A sample app demonstrating the technique is available: LineSample.zip.

    The core of hit testing is done in my LineView object. Here are two key methods:

    - (CGContextRef)newBitmapContext {
    
        // creating b&w bitmaps to do hit testing
        // based on: http://robnapier.net/blog/clipping-cgrect-cgpath-531
        // see "Supported Pixel Formats" in Quartz 2D Programming Guide
        CGContextRef bitmapContext =
        CGBitmapContextCreate(NULL, // data automatically allocated
                              self.bounds.size.width,
                              self.bounds.size.height,
                              8, 
                              self.bounds.size.width,
                              NULL,
                              kCGImageAlphaOnly);
        CGContextSetShouldAntialias(bitmapContext, NO);
        // use CGBitmapContextGetData to get at this data
    
        return bitmapContext;
    }
    
    
    - (BOOL)line:(Line *)line canExtendToPoint:(CGPoint) newPoint {
    
        //  Lines are made up of segments that go from node to node. If we want to test for self-crossing, then we can't just test the whole in progress line against the completed line, we actually have to test each segment since one segment of the in progress line may cross another segment of the same line (think of a loop in the line). We also have to avoid checking the first point of the new segment against the last point of the previous segment (which is the same point). Luckily, a line cannot curve back on itself in just one segment (think about it, it takes at least two segments to reach yourself again). This means that we can both test progressive segments and avoid false hits by NOT drawing the last segment of the line into the test! So we will put everything up to the  last segment into the hitProgressLayer, we will put the new segment into the segmentLayer, and then we will test for overlap among those two and the hitTestLayer. Any point that is in all three layers will indicate a hit, otherwise we are OK.
    
        if (line.failed) {
            // shortcut in case a failed line is retested
            return NO;
        }
        BOOL ok = YES; // thinking positively
    
        // set up a context to hold the new segment and stroke it in
        CGContextRef segmentContext = [self newBitmapContext];
        CGContextSetLineWidth(segmentContext, 2); // bit thicker to facilitate hits
        CGPoint lastPoint = [[[line nodes] lastObject] point];
        CGContextMoveToPoint(segmentContext, lastPoint.x, lastPoint.y);
        CGContextAddLineToPoint(segmentContext, newPoint.x, newPoint.y);
        CGContextStrokePath(segmentContext);
    
        // now we actually test
        // based on code from benzado: http://stackoverflow.com/questions/6515885/how-to-do-comparisons-of-bitmaps-in-ios/6515999#6515999
        unsigned char *completedData = CGBitmapContextGetData(hitCompletedContext);
        unsigned char *progressData = CGBitmapContextGetData(hitProgressContext);
        unsigned char *segmentData = CGBitmapContextGetData(segmentContext);
    
        size_t bytesPerRow = CGBitmapContextGetBytesPerRow(segmentContext);
        size_t height = CGBitmapContextGetHeight(segmentContext);
        size_t len = bytesPerRow * height;
    
        for (int i = 0; i < len; i++) {
            if ((completedData[i] | progressData[i]) & segmentData[i]) { 
                ok = NO; 
                break; 
            }
        }
    
        CGContextRelease(segmentContext);
    
        if (ok) {
            // now that we know we are good to go, 
            // we will add the last segment onto the hitProgressLayer
            int numberOfSegments = [[line nodes] count] - 1;
            if (numberOfSegments > 0) {
                // but only if there is a segment there!
                CGPoint secondToLastPoint = [[[line nodes] objectAtIndex:numberOfSegments-1] point];
                CGContextSetLineWidth(hitProgressContext, 1); // but thinner
                CGContextMoveToPoint(hitProgressContext, secondToLastPoint.x, secondToLastPoint.y);
                CGContextAddLineToPoint(hitProgressContext, lastPoint.x, lastPoint.y);
                CGContextStrokePath(hitProgressContext);
            }
        } else {
            line.failed = YES;
            [linesFailed addObject:line];
        }
        return ok;
    }
    

    I’d love to hear suggestions or see improvements. For one thing, it would be a lot faster to only check the bounding rect of the new segment instead of the whole view.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I would like to create a new controller that will allow the admin user
I've got a TextView that I would like to allow the user to select
I've a user profile and would like allow the user update everything about himself(username,
I would like to allow the user to click within my UserControl and drag
I would like to allow a user to click on a JList and if
I'm creating a new WP theme and I would like to allow the user
I'd like to allow a user to add a shape (which would just be
I'd like to draw lines on an image. Basically allow the user to draw
I would like to allow a user to change his email address. A user
I would like to allow user to search for other users by typing a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.