5

I am having a thinking and searching problem here and can't find the good direction to look at... I am looking to develop an algorithm to move in a 360 image (sphere like) by using the device motion.

So if the user point the device in front of him he get the determined origin point of the image. As he moves the device around him the panoramic image moves according to it.

Any idea or source I can look into ?

Thanks and good luck to everyone with Swift :)

TanguyAladenise
  • 108
  • 1
  • 6
  • 360 or sphere, how is the structure of the image? A sphere means 3-dimensional i.e. sky and ground are integrated. 360 degrees indicates a cylinder like when you take a panorama photo with your iPhone – Kay Jun 03 '14 at 15:05
  • You're right to point that out. I do talk only about 360 panoramic and moving only around the x axis. I may go further afterwards but for a matter of doing this step by step I would like to get this first. – TanguyAladenise Jun 03 '14 at 15:21
  • I did start getting some results by storing a reference attitude and getting new roll based on previous with [currentAttitude multiplyByInverseOfAttitude: self.referenceAttitude]; This makes me move around the panoramic indefinitely. Those this sounds good to you ? I know need to handle the infinite image into an infinite scrollview I guess. Plus this behaviour doesn't handle the fact that the user points to the ground. If he rotates right or left no matter in which direction he is pointing at, the panoramic moves... I need to fix this also. – TanguyAladenise Jun 03 '14 at 15:47

2 Answers2

2

Thanks to Kay I could be on the right track to achieved this effect.

I am making this answer just to provide more details for those looking for the same thing.

First you need to create a CMMotionManager object.

Then use startDeviceMotionUpdatesToQueue to handle motion events.

[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
    [self processMotion];
}];

In processMotion you just need to get the attitude based on the previous one:

// Get attitude difference with previous one
CMAttitude *currentAttitude = self.motionManager.deviceMotion.attitude;
[currentAttitude multiplyByInverseOfAttitude:self.referenceAttitude];

Thanks to this you know the new angle made by the user since the last update. Then where you handle your view you convert the new Euler angle into the amount of pixels you need to move your image. Just be careful Euler angle varies between -180, 180 and are given in rad by Apple. This could be handy:

#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))

So in my case I just calculate the new x offset because I am just moving on the x axis.

Hope this helps.

TanguyAladenise
  • 108
  • 1
  • 6
  • 1
    I see that its an old answer, can you provide more details about how you managed to achieve it. What are you using as referenceAttitude? – dev296 Oct 26 '16 at 14:02
1

I see two easy ways to implement this without to much math hassle:

  1. Use Euler Angles i.e. the roll property of CMAttitude. Define a mapping between the width of the image and the measured angle and take care of the singularity at 180° / -180°. Drawback of this approach:
    • Possible danger of Gimbal Lock when users start to move their devices in a chaotic way.
    • The same applies to extensibility regarding a full 3D view.
  2. Use the magnetic field from CMDeviceMotion which is robust against Gimbal Lock. The magnetometer is a little bit slower than accelerometer / gyro, but I think the CoreMotion's fusion algorithm will provide a reasonable estimation so that this won't be the point. Drawbacks here:
    • Magnetic field is not always available or tends to be slighlty imprecise.
    • Extending it to 3D view might be a hassle.

Both approaches should be pretty easy to implement and thus I would start with one of them. If you then want to have a more sophisticated solution, you will need to dive a little bit deeper into the maths. In this case a ppossible solution can be to use the current device normal (s. for example Finding normal vector to iOS device), project it onto the earth suface plane and take the angles' delta for the cylindric panorama.

The sphere projection is even easier in this case as you can use the nomal vector directly.

Kay
  • 12,918
  • 4
  • 55
  • 77
  • Thank you for your answer. I think I understand things you explained. I am going to investigate and tell you when I get things working. – TanguyAladenise Jun 03 '14 at 16:37