How to get the angle from quartnenion value? - android

Using android phone, I am able to get quarternion value x,y,z from TYPE_ROTATION_VECTOR
However, I do not know how to get the angle.
Anyone have any idea on this? Thank you.

Taken from here
/**
* Returns the heading, attitude and bank of this quaternion as euler angles in the double array respectively
*
* #return An array of size 3 containing the euler angles for this quaternion
*/
public double[] toEulerAngles() {
double[] ret = new double[3];
ret[0] = Math.atan2(2 * points[1] * getW() - 2 * points[0] * points[2], 1 - 2 * (points[1] * points[1]) - 2
* (points[2] * points[2])); // atan2(2*qy*qw-2*qx*qz , 1 - 2*qy2 - 2*qz2)
ret[1] = Math.asin(2 * points[0] * points[1] + 2 * points[2] * getW()); // asin(2*qx*qy + 2*qz*qw)
ret[2] = Math.atan2(2 * points[0] * getW() - 2 * points[1] * points[2], 1 - 2 * (points[0] * points[0]) - 2
* (points[2] * points[2])); // atan2(2*qx*qw-2*qy*qz , 1 - 2*qx2 - 2*qz2)
return ret;
}

Related

How to find intersect between two polylines in android?

How to find intersect between two polylines in android?
I tried all below options
PolyUtil.isLocationOnPath();
RectF rectPathBounds=new RectF();
path.computeBounds(rectPathBounds,true);
if(rectPathBounds.contains((int) event.getX(), (int) event.getY())){
}
3.boolean res = path.op(path1, Path.Op.INTERSECT);
Please help me with the solutions. Thanks in advance
/**
* See if two line segments intersect. This uses the
* vector cross product approach described below:
* http://stackoverflow.com/a/565282/786339
*
* #param {Object} p point object with x and y coordinates
* representing the start of the 1st line.
* #param {Object} p2 point object with x and y coordinates
* representing the end of the 1st line.
* #param {Object} q point object with x and y coordinates
* representing the start of the 2nd line.
* #param {Object} q2 point object with x and y coordinates
* representing the end of the 2nd line.
*/
boolean doLineSegmentsIntersect(Point p,Point p2,Point q,Point q2) {
Point r = subtractPoints(p2, p);
Point s = subtractPoints(q2, q);
float uNumerator = crossProduct(subtractPoints(q, p), r);
float denominator = crossProduct(r, s);
if (denominator == 0) {
// lines are paralell
return false;
}
float u = uNumerator / denominator;
float t = crossProduct(subtractPoints(q, p), s) / denominator;
return res = (t >= 0) && (t <= 1) && (u > 0) && (u <= 1);
}
/**
* Calculate the cross product of the two points.
*
* #param {Object} point1 point object with x and y coordinates
* #param {Object} point2 point object with x and y coordinates
*
* #return the cross product result as a float
*/
float crossProduct(Point point1, Point point2) {
return point1.x * point2.y - point1.y * point2.x;
}
/**
* Subtract the second point from the first.
*
* #param {Object} point1 point object with x and y coordinates
* #param {Object} point2 point object with x and y coordinates
*
* #return the subtraction result as a point object
*/
Point subtractPoints(Point point1,Point point2) {
Point result = new Point();
result.x = point1.x - point2.x;
result.y = point1.y - point2.y;
return result;
}

Android OpenCV retrieve intersection point

I'm trying to modifiy the following OpenCV code to Java.
std::vector<cv::Vec4i> lines;
cv::HoughLinesP(bw,lines,1,CV_PI/180,70,30,10);
for (unsigned int i = 0;i<lines.size();i++)
{
cv::Vec4i v = lines[i];
lines[i][0] = 0;
lines[i][1] = ((float)v[1] - v[3])/(v[0] - v[2])* -v[0] + v[1];
lines[i][2] = src.cols;
lines[i][3] = ((float)v[1] - v[3])/(v[0] - v[2])*(src.cols - v[2]) + v[3];
}
std::vector<cv::Point2f> corners;
for (unsigned int i = 0;i<lines.size();i++)
{
for (unsigned int j=i+1;j<lines.size();j++)
{
cv::Point2f pt = computeIntersect(lines[i],lines[j]);
if (pt.x >= 0 && pt.y >=0)
{
corners.push_back(pt);
}
}
}
So you have two line segments (lines[i] and lines[j]) given by their end points and you are interested in estimating their intersection (the function computeIntersect()):
computeIntersect(lines[i], lines[j]);
The point where the segments intersect is given by solving two simple equations. You should read the description here for more details. And also here you have some good SO answer about the problem.
/**
* Computes the intersection between two lines. The calculated point is approximate,
* since integers are used. If you need a more precise result, use doubles
* everywhere.
* (c) 2007 Alexander Hristov. Use Freely (LGPL license). http://www.ahristov.com
*
* #param x1 Point 1 of Line 1
* #param y1 Point 1 of Line 1
* #param x2 Point 2 of Line 1
* #param y2 Point 2 of Line 1
* #param x3 Point 1 of Line 2
* #param y3 Point 1 of Line 2
* #param x4 Point 2 of Line 2
* #param y4 Point 2 of Line 2
* #return Point where the segments intersect, or null if they don't
*/
public Point intersection(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
int d = (x1-x2)*(y3-y4) - (y1-y2)*(x3-x4);
if (d == 0) return null;
int xi = ((x3-x4)*(x1*y2-y1*x2)-(x1-x2)*(x3*y4-y3*x4))/d;
int yi = ((y3-y4)*(x1*y2-y1*x2)-(y1-y2)*(x3*y4-y3*x4))/d;
return new Point(xi,yi);
}

Android Google maps Spatial Coordinates: From GCJ-02

I am provided a LatLng that belongs to Spatial Reference GCJ-02.
Of course it does not show up properly in google maps, since i beleive, correct me if i am wrong, google maps uses WGS-84.
Does the google map service v2 for android provide a way to display or transform GCJ-02 ?
Is my only option using geo tool? I do not want to bring in such huge library for just spatial transformation.
Thanks for all your help,
Kev
Around the time the question was asked, the only way to convert between GCJ-02 and WGS-84 was to use an interpolation method with coordinates based on regression from a data set of Google China and satellite imagery coordinates. There is an Objective-C library on GitHub at https://github.com/maxime/ChinaMapDeviation.
However, since the question was asked, the GCJ-02 encryption code was leaked and can be found in many places online, the most popular being the EvilTransform repo.
Further reading:
What causes the GPS shift in China?
Restrictions on geographic data in China
public static LatLng wgs_gcj_encrypts(double wgLat, double wgLon) {
LatLng point;
if (outOfChina(wgLat, wgLon)) {
Log.e("Baidu", "outOfChina");
point = new LatLng(wgLat,wgLon);
return point;
}
double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
double radLat = wgLat / 180.0 * pi;
double magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
double lat = wgLat + dLat;
double lon = wgLon + dLon;
point = new LatLng(lat,lon);
return point;
}
private static boolean outOfChina(double lat, double lon) {
if (lon < 72.004 || lon > 137.8347)
return true;
if (lat < 0.8293 || lat > 55.8271)
return true;
return false;
}
public static double transformLat(double x, double y) {
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
public static double transformLon(double x, double y) {
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}
Google maps will accept 4326 but if you really want to be correct - read this post
https://gis.stackexchange.com/questions/253/what-is-the-current-web-mercator-projection-code
You can use proj4 or store your data in PostGIS ( It can do the transform for you). I don't know of any library on the android client that could do this but perhaps this could the trick for you:
http://www.jhlabs.com/java/maps/proj/

Animation Along a path with Auto Rotation based on the path in android

I have been trying to animate an image of a fly which moves in a path like the following image(which i have added for a clear idea) in android version 2.2
Well,this can be done in a very simple manner in the iphone as they have a property forsetting this auto rotation after the path is drawn using
animation.rotationMode = kCAAnimationRotateAuto;
which i believe would rotate the object based on the path`
I am able to animate ma fly through this path using the nineoldandroid library using the methods
path.moveTo(float x, float y);
path.lineTo(float x, float y);
path.curveTo(float c0X, float c0Y, float c1X, float c1Y, float x, float y);
Such that the curves are drawn through cubic B�zier curve.
Now what i have been trying is to implement something that would allow my fly to rotate itself along the path and i just cant seem to reach anywhere.
Please Help Me out with some ideas!!! :( :(
You have to download the demo and the lib of nineoldandroids and these 4 java files if you want to use my solution
That was easy, I modified the evaluator in the demo of nineoldandroids.
It's too much to post here:
Just to get the idea:
I extend the PathPoint with the field angle.
Then write all calculated Points in a stack (a simple float[][])
After the first calculation the angle can be calculated by the atan and the last 2 points in the stack.
If you don't want to use a stack you can modify the timeparam and look forward to where the next point will be drawn and calculate the angle out of these.
Just think about:
Do you first watch where you are walking to and then walk or do you just walk and then chose the angle for the destination. It's not neccessary since we have display densities that high and calculating the angle for each pixel.
Here's the PathEvaluator
public class PathEvaluatorAngle implements TypeEvaluator<PathPointAngle> {
private static final int POINT_COUNT = 5000;
private float[][] stack = new float[POINT_COUNT][2];
private int stackC = 0;
#Override
public PathPointAngle evaluate(float t, PathPointAngle startValue, PathPointAngle endValue) {
float x, y;
if (endValue.mOperation == PathPointAngle.CURVE) {
float oneMinusT = 1 - t;
x = oneMinusT * oneMinusT * oneMinusT * startValue.mX +
3 * oneMinusT * oneMinusT * t * endValue.mControl0X +
3 * oneMinusT * t * t * endValue.mControl1X +
t * t * t * endValue.mX;
y = oneMinusT * oneMinusT * oneMinusT * startValue.mY +
3 * oneMinusT * oneMinusT * t * endValue.mControl0Y +
3 * oneMinusT * t * t * endValue.mControl1Y +
t * t * t * endValue.mY;
} else if (endValue.mOperation == PathPointAngle.LINE) {
x = startValue.mX + t * (endValue.mX - startValue.mX);
y = startValue.mY + t * (endValue.mY - startValue.mY);
} else {
x = endValue.mX;
y = endValue.mY;
}
stack[stackC][0] = x;
stack[stackC][1] = y;
double angle;
if (stackC == 0){
angle = 0;
} else if (stackC >= POINT_COUNT){
throw new IllegalStateException("set the stack POINT_COUNT higher!");
} else {
angle = Math.atan(
(stack[stackC][1] - stack[stackC-1][1]) /
(stack[stackC][0] - stack[stackC-1][0])
) * 180d/Math.PI;
}
stackC++;
return PathPointAngle.moveTo(x, y, angle);
}
}
Please check the below link.Hope it will help.
https://github.com/JakeWharton/NineOldAndroids

OpenGL Normal Matrix

I've been trying to create simple diffuse lighting shader for Android using OpenGL ES 2.0 and getting knowledge from OpenGL 4.0 Shading language cookbook but it doesn't tell much about normal matrix and I am pretty sure the problem comes from it because the "model" I've been using is working perfectly in WebGL where I can use that nice glMatrix lib that I can't find for Java.
I am not sure how can I get normal matrix from model view matrix but I read its just transpose of inverted 3x3 piece of modelview matrix, too bad Android Matrix class only lets you work with 4x4 matrices(right?) so I've been splitting the matrix up in the shader which is probably where I go wrong.
So what I do is simply this:
float[] nMatrix = new float[4 * 4];
Matrix.invertM(nMatrix, 0, mvMatrix, 0);
Matrix.transposeM(nMatrix, 0, nMatrix, 0);
glUniformMatrix4fv(shader.getUniformPointer("nMatrix"), 1, false, nMatrix, 0);
and then at my vertex shader I do this:
tNorm = normalize(mat3(nMatrix) * vNormal).xyz;
and the rest of the code is basically from the book and the results are below
As you can see some sides of the cube are compeltely dark, and I am sure I got all the normals even thought I don't know any Android GL debugger, but if you know one, feel free to tell me about it.
So the question is, how can I properly get the normal matrix from my modelview matrix?
I don't where you could find a Matrix library in Java to help you with this.
But, as long as your modelView matrix does not contain non-uniform scales, you can safely use your modelView matrix instead of the normalMatrix.
This could help you get started and make sure that your problem is not hidden elsewhere.
This might be useful
Port of some useful mat3 functions of glm library
package com.CosmicCreations;
public class Mat3x3 {
public static float determinant(float []m){
return
+ m[0] * (m[4] * m[8] - m[7] * m[5])
- m[3] * (m[1] * m[8] - m[7] * m[2])
+ m[6] * (m[1] * m[5] - m[4] * m[2]);
}
public static void Mat3(float []m4, float[]m){
m[0]=m4[0]; m[1]=m4[1]; m[2]=m4[2];
m[3]=m4[4]; m[4]=m4[5]; m[5]=m4[6];
m[6]=m4[8]; m[7]=m4[9]; m[8]=m4[10];
}
/*
Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
Inverse[1][0] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]);
Inverse[2][0] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]);
Inverse[0][1] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]);
Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]);
Inverse[2][1] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]);
Inverse[0][2] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
Inverse[1][2] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]);
Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]);
Inverse /= Determinant;
*/
public static void inverse(float []m, float[] Inverse, int offset){
float Determinant = Mat3x3.determinant(m);
Inverse[offset+0] = + (m[4] * m[8] - m[7] * m[5])/ Determinant;
Inverse[offset+3] = - (m[3] * m[8] - m[6] * m[5])/ Determinant;
Inverse[offset+6] = + (m[3] * m[7] - m[6] * m[4])/ Determinant;
Inverse[offset+1] = - (m[1] * m[8] - m[7] * m[2])/ Determinant;
Inverse[offset+4] = + (m[0] * m[8] - m[6] * m[2])/ Determinant;
Inverse[offset+7] = - (m[0] * m[7] - m[6] * m[1])/ Determinant;
Inverse[offset+2] = + (m[1] * m[5] - m[4] * m[2])/ Determinant;
Inverse[offset+5] = - (m[0] * m[5] - m[3] * m[2])/ Determinant;
Inverse[offset+8] = + (m[0] * m[4] - m[3] * m[1])/ Determinant;
}
public static void transpose(float []m, int offset, float[]result){
result[0] = m[offset+0];
result[1] = m[offset+3];
result[2] = m[offset+6];
result[3] = m[offset+1];
result[4] = m[offset+4];
result[5] = m[offset+7];
result[6] = m[offset+2];
result[7] = m[offset+5];
result[8] = m[offset+8];
}
}
It should be used like this -
// Invert + transpose of mvmatrix
float []temp = new float[18];
Mat3x3.Mat3(mMVMatrix, temp);
Mat3x3.inverse(temp, temp, 9);
Mat3x3.transpose(temp, 9, normalMatrix);

Categories

Resources