iPhone-AR-Toolkit icon indicating copy to clipboard operation
iPhone-AR-Toolkit copied to clipboard

Detect Collisions and reposition callouts

Open markrickert opened this issue 12 years ago • 22 comments

The images overlap when there are points very close to each other. Check out how the yelp app handles this in "monocle mode"

IMG_4991

markrickert avatar Jan 10 '13 23:01 markrickert

I haven't checked out Yelp yet - but just an idea, what if we always had the closest to the centre at the foreground using z-indexing on the CALayer?

I have a feeling the altitude is a little broken too so will need to confirm this, and if so open an issue.

a1phanumeric avatar Jan 15 '13 00:01 a1phanumeric

I think the z-index would be a great idea - just to verify that the closest is in the front. Basically, if two objects are going to collide, they stack them on op of each other.

The data I'm using doesn't have altitude data associated with it, so i'm not sure I can test that.

markrickert avatar Jan 15 '13 20:01 markrickert

So getting back to this... I've got live data to test now. I think that because of line 510 on AugmentedRealityController.m sometimes locations that are further away get set in front of locations that are closer.

Here's an example. You can see that the 2.07mile marker is on top of the 1.19 mile marker.

photo

Ideally, I'd like to see there be a variation in the y-positioning of the markers based on distance. Here's a mockup i threw together:

Untitled-1

markrickert avatar Feb 27 '13 00:02 markrickert

Hey guys, it looks like Yelp! stacks the POIs on top of each other, but an app called Wikitude takes nearby POI's and bundles them together. The user taps the bundle it "expands out" (see screenshots)

IMG_0519 IMG_0518

What is elevation supposed to? I have created several coordinates and set them to different inclinations as shown below but I see no difference in the view. Am I doing something wrong?

tempCoordinate.inclination = M_PI/30;

Whatever gets implemented to help show bunched up points would be AWESOME guys, it's a great project!

POI - Point of interest in Lat and Long

jchri853 avatar Mar 06 '13 16:03 jchri853

Thanks for the input, Jonathan.

I actually have it implemented in my app as-is, but would love to see it get better. I haven't had a lot of time to hack on it myself.

markrickert avatar Mar 06 '13 16:03 markrickert

Is your implementation (I'm assuming what you have above in your post) available for download?

jchri853 avatar Mar 06 '13 16:03 jchri853

I've got some uncommitted changes to the arkit library (don't want rotation in my app). I'll try and throw it together and commit it to my fork.

Here's the project: https://github.com/markrickert/WSCrime but it's in RubyMotion. So you'll need that to compile it. You can also get it in the app store here: https://itunes.apple.com/us/app/winston-salem-crime-map/id472546582?mt=8

Email me through my contact form on my website - http://mohawkapps.com and i'll shoot you over a promo code... unless you want to give me $0.99 :)

markrickert avatar Mar 06 '13 16:03 markrickert

Hey,

I like the idea of stacking them together but that would cause problems with the second issue: elevation. I could either:

  • Include an option to either stack "close" POIs
  • Overlap and have elevation working?

Which do you reckon would work best?

Thanks for the input!

a1phanumeric avatar Mar 06 '13 17:03 a1phanumeric

@markrickert I just purchased your app, I am working on a virtual tours app of my college/wildlife reserve up here and your app really looks helpful to view the source on. Unfortunately I'm so far away that all the markers are bunched into one spot :P I'll send you an email shortly.

@a1phanumeric I think removing the overlap would be the biggest benefit to the application (I push to a new new after touching a marker) and not being able to see what I'm pressing is a little frustrating. Is there a way to get elevation working and if one marker can detect if another marker is on top of it (stack them together) ?

jchri853 avatar Mar 06 '13 17:03 jchri853

@jchri853 if you have rubymotion and can compile my application, you can artificially set your location so that they're not all bunched up in one direction (i no longer live in that city so I have to do that as well)

In AugmentedReailtyController.m change this method:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    [self setCenterLocation:newLocation];
    [[self delegate] didUpdateLocation:newLocation];    
}

to this:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    CLLocation *temporaryLocation = [[CLLocation alloc] initWithLatitude:36.0997 longitude:-80.2444];
    [self setCenterLocation:temporaryLocation];
    [[self delegate] didUpdateLocation:newLocation];
}

Then run rake clean && rake device (since the app can't simulate motion and rotation in the simulator) and you'll be artificially placed smack dab in the middle of Winston-salem and you should see the markers all around you.

markrickert avatar Mar 06 '13 17:03 markrickert

I'll take a swing at it (I have only been in the Objectice C/xCode world for about 7 weeks now) would using your xcode fork include all the changes to the AR view from your app?

Looks like I would have to buy Rubymotion

jchri853 avatar Mar 06 '13 17:03 jchri853

I'll update everything right now and I'll let you know when it's all updated.

Also, you'll need to purchase RubyMotion in order to compile my app since it's written in ruby and not Obj-C. http://www.rubymotion.com/

markrickert avatar Mar 06 '13 17:03 markrickert

Ok much appreciated, I'll wait on the RubyMotion

jchri853 avatar Mar 06 '13 17:03 jchri853

I've pushed up my changes here: https://github.com/markrickert/iPhone-AR-Toolkit/tree/wscrime-changes

These are just tweaks for my production implementation.

And good call on RubyMotion... you probably don't want to delve into that until you've got a bit more understanding about the CocoaTouch APIs and iOS applications in general.

markrickert avatar Mar 06 '13 17:03 markrickert

ok thanks!

jchri853 avatar Mar 06 '13 18:03 jchri853

@a1phanumeric Hey! Any luck on your end for fixing the overlay issue?

jchri853 avatar Apr 04 '13 20:04 jchri853

@a1phanumeric Did you get any luck to solve this overlay location issue ?

viral105 avatar Jul 31 '13 11:07 viral105

@jchri853 Did you get any luck to solve this overlay location issue ?

viral105 avatar Aug 02 '13 13:08 viral105

I found a small solution in - (void)updateLocations { (AugmentedRealityController.m) I wrote this code: if([ item distanceFromOrigin] <= (_radarRange*1000)/10){ scaleFactor = 1.0;

[markerView setFrame:CGRectMake(loc.x - width / 2.0, loc.y, width, height)]; [markerView setNeedsDisplay]; } else { scaleFactor = 0.5; [markerView setFrame:CGRectMake(loc.x - width / 100.0, loc.y-50, width, height)]; [markerView setNeedsDisplay];

        }

screenshot 2013 11 28 09 46 15

iLuca73 avatar Nov 28 '13 08:11 iLuca73

Hi, Is the issue been resolved ?

vivekMA avatar Jun 18 '14 09:06 vivekMA

I have solve the problem of the callout collision made some little bit changes in your code and the your problem will be solve .

  1. In AugmentedRealityViewController there is updateLocations method, go into if condition and

if (!([markerView superview])) { [[self displayView] insertSubview:markerView atIndex:1]; [self listSubviewsOfView:markerView]; // retrive the subviews from the markerview which is display on the camera screen... }

this condition is updatelocation method and i call the "listSubviewsOfView" method, that is used for retriving subview from superView.

  • (void)listSubviewsOfView:(UIView *)view {

    // Get the subviews of the view NSArray *subviews = [view subviews];
    // Return if there are no subviews if ([subviews count] == 0) return;

    for (UIView _subview in subviews) { if ([subview isKindOfClass:[UIImageView class]]) {
    UIImageView *myLabel = (UIImageView *)subview; myLabel.clipsToBounds = YES; if (myLabel.tag == 1) { numberOfImageView++; CGRect rect = myLabel.frame; rect.origin.y = 0+numberOfImageView_50; myLabel.frame = rect; }
    } // List the subviews of subview [self listSubviewsOfView:subview]; } }

there is variable numberOfImageView. declare in .h file int numberOfImageView;

and do one thing in else condition of the updateLocation Method , set the "numberOfImageView" to zero. else if ([markerView superview]) {

            [markerView removeFromSuperview];
            numberOfImageView =0;
        }

then compile and run your code problem will be solve..

vijayrathore99 avatar Dec 15 '14 05:12 vijayrathore99

Add in updateLocations of AugmentedRealityController.m :-

int totalDisplayed=0;

for (ARGeoCoordinate *item in [self coordinates]) {

    UIView *markerView = [item displayView];

    if ([self shouldDisplayCoordinate:item]) {

        CGPoint loc = [self pointForCoordinate:item];
        CGFloat scaleFactor = SCALE_FACTOR;

        if ([self scaleViewsBasedOnDistance]) 
            scaleFactor = scaleFactor - [self minimumScaleFactor]*([item radialDistance] / [self maximumScaleDistance]);

        float width  = [markerView bounds].size.width  * scaleFactor;
        float height = [markerView bounds].size.height * scaleFactor;


        int offset = totalDisplayed%2 ? totalDisplayed*25 : -totalDisplayed*25;  
        [markerView setFrame:CGRectMake(loc.x - width / 2.0, loc.y - (height / 2.0) + offset, width, height)];
        totalDisplayed ++;


        //[markerView setFrame:CGRectMake(loc.x - width / 2.0, loc.y, width, height)];
        [markerView setNeedsDisplay];
        if ([item distanceFromOrigin]>0) {
            float difference = [item distanceFromOrigin]-prevLoc;

            if ((difference>0 &&difference<200) || ( difference < 0 && difference>(-200))) {
                [markerView setFrame:CGRectMake(loc.x - width / 2.0, loc.y - (height / 2.0) + offset, width, height)];
                totalDisplayed ++;
            }
            prevLoc = [item distanceFromOrigin];
        }



        CATransform3D transform = CATransform3DIdentity;

        // Set the scale if it needs it. Scale the perspective transform if we have one.
        if ([self scaleViewsBasedOnDistance]) 
            transform = CATransform3DScale(transform, scaleFactor, scaleFactor, scaleFactor);

        if ([self rotateViewsBasedOnPerspective]) {
            transform.m34 = 1.0 / 300.0;

        }
        [[markerView layer] setTransform:transform];

        //if marker is not already set then insert it
        if (!([markerView superview])) {
            [[self displayView] insertSubview:markerView atIndex:1];
        }
    } 
    else {
        if ([markerView superview]){
            [markerView removeFromSuperview];
        }
    }

pushpank123 avatar Mar 21 '16 12:03 pushpank123