gjiazhe / PanoramaImageView

An imageView can auto scroll with device rotating.
MIT License
2.17k stars 245 forks source link

Support for devices with accelerometer +/- digital compass #3

Open sameerkhan2k1 opened 7 years ago

sameerkhan2k1 commented 7 years ago

First of all, Gr8 work!

I pulled the code to check this lib on my moto G3 phone and found that it does not work because my phone does not have a gyro sensor and this library currently support gyro alone. I feel it would be great if this library can be extended to support accelerometer based panoramic viewing.

gjiazhe commented 7 years ago

Sorry, I don't think the gyroscope sensor can be replaced by accelerometer sensor , do you have any solution to do this?

sameerkhan2k1 commented 7 years ago

Based on the roll (x-axis) and pitch (y-axis) using the accelerometer and magnetic field, one can gather the change of angles along each of these axes. I believe this data should be sufficient the rotate the images. Does it make sense to you?

gjiazhe commented 7 years ago

OK. I'll have a try with that. Thank you very much.

sameerkhan2k1 commented 7 years ago

I have pasted relevant code to gather reading from accelerometer and magnetic field.

private float[] gravity = new float[9];
private float[] outGravity = new float[9];

// Magnetic rotational data
private float accels[] = new float[3];
private float mags[] = new float[3];
private float values[] = new float[3];

// azimuth, pitch and roll
private double azimuth;
private double pitch, lastPitch;
private double roll, lastRoll;

@Override
protected void onPause() {
    super.onPause();
    mSensorManager.unregisterListener(this);
}

@Override
protected void onResume() {
    super.onResume();
    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SENSOR_DELAY_GAME);
    mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SENSOR_DELAY_GAME);
}

protected float[] lowPass(float[] input, float[] output) {
    if (output == null)
        return input;

    for ( int i=0; i<input.length; i++) {
        output[i] = output[i] + ALPHA * (input[i] - output[i]);
    }

    return output;
}

@Override
public void onSensorChanged(SensorEvent event) {
    switch (event.sensor.getType()) {
        case Sensor.TYPE_MAGNETIC_FIELD:
            mags = lowPass(event.values.clone(), mags);
            break;
        case Sensor.TYPE_ACCELEROMETER:
            accels = lowPass(event.values.clone(), accels);
            break;
    }

    if (mags != null && accels != null) {
        SensorManager.getRotationMatrix(gravity, null, accels, mags);
        SensorManager.remapCoordinateSystem(gravity, SensorManager.AXIS_X, SensorManager.AXIS_Z, outGravity);
        SensorManager.getOrientation(outGravity, values);

        azimuth = Math.toDegrees(values[0]);
        pitch = Math.toDegrees(values[1]);
        roll = Math.toDegrees(values[2]);

        double diffRoll = lastRoll - roll;
        double diffPitch = lastPitch - pitch;
        }
    }
}
sameerkhan2k1 commented 7 years ago

Have you been able to look into this feature?

gjiazhe commented 7 years ago

So sorry for late. I have been busy with my graduation thesis these months. I'll follow up this issue as soon as possible when I finish the thesis. So at least in the following month I have no time to look into this feature. And it's very welcome for you to make a pull request if possible!

codernavi18 commented 7 years ago

Implemented in this pull request