a1phanumeric / iPhone-AR-Toolkit

An iOS (Objective-C) Augmented Reality kit for iPhone. With radar and other goodness! Active community!
http://edrackham.com
Other
81 stars 30 forks source link

Detect Collisions and reposition callouts #4

Open markrickert opened 11 years ago

markrickert commented 11 years ago

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

a1phanumeric commented 11 years ago

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.

markrickert commented 11 years ago

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 commented 11 years ago

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

jchri853 commented 11 years ago

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

markrickert commented 11 years ago

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.

jchri853 commented 11 years ago

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

markrickert commented 11 years ago

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 :)

a1phanumeric commented 11 years ago

Hey,

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

Which do you reckon would work best?

Thanks for the input!

jchri853 commented 11 years ago

@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) ?

markrickert commented 11 years ago

@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.

jchri853 commented 11 years ago

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

markrickert commented 11 years ago

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/

jchri853 commented 11 years ago

Ok much appreciated, I'll wait on the RubyMotion

markrickert commented 11 years ago

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.

jchri853 commented 11 years ago

ok thanks!

jchri853 commented 11 years ago

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

viral105 commented 11 years ago

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

viral105 commented 11 years ago

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

iLuca73 commented 10 years ago

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

vivekMA commented 10 years ago

Hi, Is the issue been resolved ?

vijayrathore99 commented 9 years ago

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.

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..

pushpank123 commented 8 years ago

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];
        }
    }