How to find intersect between two polylines in android? - 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;
}

Related

How to get the angle from quartnenion value?

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

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

Click inside the Path in Openstreetmap

I have two overlays in my openstreetmap app, Itemized overlay and Path overlay together. I want to provide click inside the path inside the path overlay and custom marker
Not available with PathOverlay.
Use OSMBonusPack Polyline.
If you just want to open a bubble, use setInfoWindow.
If you want to do something else, inherit from Polyline class, override onSingleTapConfirmed, and use isCloseTo.
Finally I got answer for the Above question...
Add all path overlays into a single layer.
In on single tap check isPointOnLine(lox,loy,ltx,lty, x, y)
public boolean isPointOnLine(double lox, double loy, double ltx,
double lty, double x, double y) {
// determine if point is on line
Double dx = x - lox;
Double dy = y - loy;
Double tx = ltx - lox;
Double ty = lty - loy;
// normalise the line vector
Double t1 = new Double(1 / Math.sqrt(tx * tx + ty * ty));
tx *= t1;
ty *= t1;
// calculate inverse length of secondary vector
Double dl = new Double(1 / Math.sqrt(dx * dx + dy * dy));
// take dot product of normalised line vector, and rotated normalised
// secondary vector
Double dot = (dy * tx - dx * ty) * dl;
// Increase these values for less or more picky
if (dot < -0.2 || dot > 0.2)
return false;
// calculate distance along line segment by taking dot product of
// normalised
// line vector and un-normalised secondary vector
Double dis = tx * dx + ty * dy;
if (dis < 0 || dis > 1 / t1)
return false;
return true;
}

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

toPixels() returns the pixels of the tiles, instead of the screen

I have an Android application that showing maps using OSMDroid.
I want to get the projection pixels of a GeoPoint on the screen, not on the tiles.
Consider the following piece of code:
Projection projection = getProjection();
GeoPoint geoPoint1 = (GeoPoint)projection.fromPixels(0, 0);
Point pixelsPoint = new Point();
projection.toPixels(geoPoint1, pixelsPoint);
GeoPoint geoPoint2 = (GeoPoint)projection.fromPixels(pixelsPoint.x, pixelsPoint.y);
I would like geoPoint1 to be equal to geoPoint2. Instead, I get 2 totally different `GeoPoint'.
In my opininion, the problem is in this line:
projection.toPixels(geoPoint1, pixelsPoint);
The out variable pixelsPoint get filled with values much higher than the screen dimensions (I get 10,000+ for the x and y) and I suspect that this are the pixels on the tile, rather than the screen pixels.
How can I get from GeoPoint to screen pixels back and forth?
You need to compensate for the top left offset, these methods should work:
/**
*
* #param x view coord relative to left
* #param y view coord relative to top
* #param vw MapView
* #return GeoPoint
*/
private GeoPoint geoPointFromScreenCoords(int x, int y, MapView vw){
if (x < 0 || y < 0 || x > vw.getWidth() || y > vw.getHeight()){
return null; // coord out of bounds
}
// Get the top left GeoPoint
Projection projection = vw.getProjection();
GeoPoint geoPointTopLeft = (GeoPoint) projection.fromPixels(0, 0);
Point topLeftPoint = new Point();
// Get the top left Point (includes osmdroid offsets)
projection.toPixels(geoPointTopLeft, topLeftPoint);
// get the GeoPoint of any point on screen
GeoPoint rtnGeoPoint = (GeoPoint) projection.fromPixels(x, y);
return rtnGeoPoint;
}
/**
*
* #param gp GeoPoint
* #param vw Mapview
* #return a 'Point' in screen coords relative to top left
*/
private Point pointFromGeoPoint(GeoPoint gp, MapView vw){
Point rtnPoint = new Point();
Projection projection = vw.getProjection();
projection.toPixels(gp, rtnPoint);
// Get the top left GeoPoint
GeoPoint geoPointTopLeft = (GeoPoint) projection.fromPixels(0, 0);
Point topLeftPoint = new Point();
// Get the top left Point (includes osmdroid offsets)
projection.toPixels(geoPointTopLeft, topLeftPoint);
rtnPoint.x-= topLeftPoint.x; // remove offsets
rtnPoint.y-= topLeftPoint.y;
if (rtnPoint.x > vw.getWidth() || rtnPoint.y > vw.getHeight() ||
rtnPoint.x < 0 || rtnPoint.y < 0){
return null; // gp must be off the screen
}
return rtnPoint;
}

Categories

Resources