0
votes

I am working on an iOS camera based app, in which I have to capture a first point and then I need to draw the line to the current focus point to the first captured point. MagicPlan works this way.

Here is an image:

MagicPlan example

I have tried to fix a point for first point using accelerometer values and the tilted angle of the device. But, no luck so far. And how would i draw the line to the second point from the first point?

This is the code that i have tried so far:

    if (self.motionManager.deviceMotionAvailable)
    {
        [self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
         withHandler: ^(CMDeviceMotion *motion, NSError *error) {
             
             CATransform3D transform;
             
             transform = CATransform3DMakeRotation(motion.attitude.pitch, 1, 0, 0);
             
             transform = CATransform3DRotate(transform,motion.attitude.roll, 0, 1, 0);
             
             transform = CATransform3DRotate(transform,motion.attitude.yaw, 0, 0, 1);
             
             self.viewObject.layer.transform = transform;
             
         }];
    }
    
    
    if (self.motionManager.deviceMotionActive)
    {
        /**
         *  Pulling gravity values from deviceMotion sensor
         */
        CGFloat x = [self convertRadianToDegree:self.motionManager.deviceMotion.gravity.x];
        CGFloat y = [self convertRadianToDegree:self.motionManager.deviceMotion.gravity.y];
        CGFloat z = [self convertRadianToDegree:self.motionManager.deviceMotion.gravity.z];
        
        CGFloat r = sqrtf(x*x + y*y + z*z);
        
        /**
         *  Calculating device forward/backward title angle in degrees
         */
        CGFloat tiltForwardBackward = acosf(z/r) * 180.0f / M_PI - 90.0f;
        
        [self.lblTilForwardBackward setText:[@(tiltForwardBackward) stringValue]];
    }
1
Maybe you could clarify your question a bit. I can't follow what you are trying to do. Sounds like you want to draw a line between two points? This shows how to do that. stackoverflow.com/questions/6905941/…LawfulEvil
@LawfulEvil if you see the image, it's from MagicPlan app, which asks user to capture an image at one point and then when the user moves the device the squares are drawn automatically. see it in action here: youtu.be/0X-kmUhPC4Q?t=14Akshit Zaveri

1 Answers

1
votes

You have a lot of issues to resolve here. It isn't just a matter of adjusting for camera orientation as the height that the camera is being held at and position of the camera in the room are also changing. Even in MagicPlan, when the person turns around, the camera moves (rotates about the axis going through the person's head down to his feet).

There is quite a lot of algebra and rotation/translation matrix operations to work out. No one is going to do this for you. You'll have to figure it all out and derive it yourself (or look it up from old graphics text books).

I suggest doing something as straight forward and multi-step as possible (so you can debug each step along the way). Assume flat ground (indoor environment).

  1. Get camera position/orientation/focal length from the first snapshot.
  2. Figure out the touch point in real world Cartesian coordinates(start with video coordinates and translate via roll/pitch/yaw and ray traced projection to ground plane(using camera height).
  3. From the focal length you can figure out the field of view and depth to center of field of view and using camera orientation and click distance from center of screen determine xyz offset from some origin (your feet maybe).
  4. Determine and track camera position and orientation relative to that origin.
  5. On second snapshot (or motion awake), figure out (center or touched point) distance from origin and exact xyz (as above).
  6. Once you have those two points in xyz you can plot the line by taking the standard orthogonal projection onto the view plane. Clipping as needed in case original point is out of the FOV.