Check if a point is near a rectangle border - android

I have 4 points making a rectangle. I would like to know if another point in the view is near the border of that rectangle. It is not if the point is IN the rectangle or OUTSIDE of the rectangle. The idea is to know if the point is near (for example 25 pixels) from the rectangle.
What I am making is a rectangle to let the user re-size a view. If the user clicks outside of the rectangle then the changes are saved. All this is easy, but I also want to save changes when the user clicks inside the rectangle.
In this example I would like to detect if the user touches in the gray or pink area, and not in the black area (where probably is touching on the blue dots or around them)

Here is some pseudo code to solve the problem:
float distance = 25.0f; // constant distance
if ( ( point.x < rect.left && point.x > rect.left - distance ) ||
( point.x > rect.right && point.x < rect.right + distance ) ||
( point.y < rect.bottom && point.y > rect.bottom - distance ) ||
( point.y > rect.top && point.y < rect.top + distance ) ) {
// point is in black area
}
else {
// point is in pink/grey area
}
Just define distance to be the size around the rectangle to exclude, and make sure that both the point and rectangle coordinates are in the same coordinate system.

Related

Moving an object along a path ontouch

I have a stroke circle path and a little fill circle path and i want to move the little circle along the stroke circle path with touch, the little circle should not be outside the stroke circle. How can i do this ? Please help me
Your touch might be slighty outside of your circle path. To provide object position at the circle, you can make the next:
find position of touch against circle center
dx = touch.x - center.x
dy = touch.y - center.y
find distance from the center
dist = sqrt(dx*dx +dy*dy)
make new position at the same disraction form center but at circle radius distance
newx = center.x + radius * dx / dist
newy = center.y + radius * dy / dist

Android libgdx bouncy screen bounds

I need to set phone's bounds as a wall where elements inside can bounce. The physic should be correct. Here an example :
I know that Interpolation allow bounce but I don't know how to create the physics
Check for the collisions with the walls. I'm assuming you're rendering Bitmaps, so the origin of the square we'll say is the top left corner. In that case:
if (x + width >= SCREEN_WIDTH || x <= 0) vx *= -1;
if (y + height >= SCREEN_HEIGHT || y <= 0) vy *= -1;
Where vx and vy are the x and y velocities.

Draw a dot always at a fixed point on screen, even when the Canvas is zoomed in or out? - Android

I now draw a dot on the canvas, which may be zoomed in or out.
As far as I know, the drawing function, canvas.drawCircle() takes in the coordinates in canvas coordinate system. Furthermore, the co-ordinates remain unchanged when the canvas is zoomed.
E.g. previously you draw a dot at (50, 50) in the canvas coordinate system, and then you zoom in the canvas, the dot's coordinates in the canvas still remain (50, 50). But obviously, the dot has been moved w.r.t. the screen.
When the canvas is zoomed, the dot should be kept at the same position on the screen. *i.e. After the dot moves w.r.t. to the screen, I want to move it back to its original position w.r.t. the screen.*
My onDraw() function is as follows:
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvasWidth = canvas.getWidth();
canvasHeight = canvas.getHeight();
canvas.save();
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
mImage.draw(canvas); // draw the map as the background
Paint PointStyle = new Paint();
PointStyle.setColor(Color.BLUE);
PointStyle.setStyle(Paint.Style.FILL_AND_STROKE);
PointStyle.setStrokeWidth(2);
canvas.drawCircle(Constant.INITIAL_X, Constant.INITIAL_Y, 3, PointStyle);
canvas.restore();
}
I tried the following method to move the dot back on screen after the scaling.
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor(); // accumulate the scale factors
// Don't let the object get too small or too large.
mScaleFactor = Math.max(1f, Math.min(mScaleFactor, 10.0f)); // 1 ~ 10
float pinToCornerOnScreenXDistance = 0;
float pinToCornerOnScreenYDistance = 0;
float canvasToScreenDiffRatioX = 0;
float canvasToScreenDiffRatioY = 0;
float pinOnCanvasX = 0;
float pinOnCanvasY = 0;
// pin's location on the screen --> S:(336, 578)
pinToCornerOnScreenXDistance = 336 - canvasLeftTopCornerOnScreenX;
pinToCornerOnScreenYDistance = 578 - canvasLeftTopCornerOnScreenY;
Log.d("Screen Diff", "X: " + pinToCornerOnScreenXDistance + " Y: " + pinToCornerOnScreenYDistance);
canvasToScreenDiffRatioX = canvasWidth * mScaleFactor / 720; // screen of HTC One X --> 720*1280
canvasToScreenDiffRatioY = canvasHeight * mScaleFactor / 1280;
Log.d("Ratio", canvasToScreenDiffRatioX + " " + canvasToScreenDiffRatioY);
pinOnCanvasX = 0 + pinToCornerOnScreenXDistance * canvasToScreenDiffRatioX; // canvas left top corner is the origin (0, 0)
pinOnCanvasY = 0 + pinToCornerOnScreenYDistance * canvasToScreenDiffRatioY;
Log.d("Pin on Canvas", "X: " + pinOnCanvasX + " Y: " + pinOnCanvasY);
Constant.setInitialX(pinOnCanvasX);
Constant.setInitialY(pinOnCanvasY);
historyXSeries.set(0, Constant.INITIAL_X);
historyYSeries.set(0, Constant.INITIAL_Y);
invalidate();
return true;
}
}
The idea is based on the fact that I notice when I zoom in or out the canvas, its left top corner never moves. That is, the canvas' let top corner is the zooming center.
Then I successfully keep updating the zooming center's co-ordinates when the canvas is moved. So in this way, no matter I move the canvas or zoom it, I always have the zooming center's coordinates in my canvasLeftTopCornerOnScreenX and canvasLeftTopCornerOnScreenY.
Then I try to utilize the distance between the never-moved-during-scaling zooming center and the desired position where I hope to place my dot, (336, 578) here. I calculate it as pinToCornerOnScreenDistance.
As its name suggests, it is the on-screen distance. I have to scale it into canvas distance so that I can draw the dot, since the drawing function is based on the canvas coordinate system instead of the screen coordinate system. Currently, the code is device-specific, i.e. it is only for HTC One X, which has a 1280*720 screen, for now. So I do the scaling as follows:
canvasToScreenDiffRatioX = canvasWidth * mScaleFactor / 720;
canvasToScreenDiffRatioY = canvasHeight * mScaleFactor / 1280;
Then, finally I calculate the new on-canvas coordinates of on-screen point (336, 578) and then draw the dot there.
But the result is not correct. When I zoom the canvas, the dot I draw fails to remain at (336, 578) on screen.
Can anybody tell me where goes wrong?
Or propose another way of doing this?
Any comment or Answer will be greatly appreciated!
Is your app using full-screen? Otherwise, it is not 1280 for the height. But I don't think that is your problem.
Based on my understanding, I will change the code to
pinOnCanvasX = 336 / mScaleFactor;
pinOnCanvasY = 578 / mScaleFactor;
which I assume when mScaleFactor == 1, the pin that on Canvas are the same on screen
Try this one,
I think this can be useful for your issue,
pinOnCanvasX = (336 * mScaleFactor) + trans_x;
pinOnCanvasY = (578 * mScaleFactor) + trans_y;
here, trans_x and trans_y is translation of canvas on x and y axis. here in your case should be mPosX, mPosY but not sure what these points means for.
The way I would like to share you is scale and translate your starting
point of the circle as much as canvas does. That means if your canvas
scale and translate with some value then apply the same for
your starting point too.
hope this will solve your problem.

Draw perpendicular line to given line on canvas android

I drawn line passing through points - (x1,y1) , (x2,y2)
Now i want to draw another line perpendicular to this line with same length.
Please guide me for this ..
Think of your line as a vector from (x1,y1) to (x2,y2). Then we get the x and y components of this vector according to
vX = x2-x1
vY = y2-y1
The vector of equal size to this but perpendicular to it in the plane has x and y components
vXP = -(y2-y1)
vYP = x2-x1
you can verify these 2 vectors are perpendicular by taking the scalar product of the 2 vectors which will be zero. Now you have your vector of equal length and perpendicular to your first vector, you simply need to decide the start point of your line. We will call that (a,b). Then using your start point, the end point of your line is given by
(a - (y2-y1), b + (x2-x1))
or if you want it to point in the reverse direction (still perpendicular) it will be
(a + (y2-y1), b - (x2-x1))
Well, it's simple maths :
int dx = x2 - x1;
int dy = y2 - y1;
int ox,oy; // Origin of new line
//...
drawLine( ox, oy, ox+dy, oy-dx) // This line will be perpendicular to original one
All you have to do is to choose the origin.
For example, if you want that the lines cuts at their center, let :
ox = x1 + (dx - dy) / 2;
oy = y1 + (dx + dy) / 2;

Calculating radius for off screen map locations

Question:
How can I taken into account the rectangular shape of the screen to ensure that circles are drawn exactly to the padded boundary?
The following works for a 'round' area, but not a rectangular one...
dx = abs(center.x - place.x);
dy = abs(center.y - place.y);
dh = Math.sqrt((dx * dx) + (dy * dy));
radius = dh - padding;
Halo Design:
If the problem doesn't seem apparent, the following image represents the current approach which i'm using. Depending on where the place is effects how far it protrudes into the screen space.
I think this should work. Not tested.
dx = abs(placeLocationPixels.x - ourLocationPixels.x)
dy = abs(placeLocationPixels.y - ourLocationPixels.y)
ox = dx - ((screenSize.x / 2) - padding);
oy = dy - ((screenSize.y / 2) - padding);
if (ox < 0) ox = 0;
if (oy < 0) oy = 0;
radius = sqrt((ox*ox) + (oy*oy));
edit: this is not in any particular language.
I'm not sure but maybe you can calculate the convex hull, and then circumscribe it into a rectangle, then you will have the scale of your map to ensure that every circle is shown on the screen.
here: you can find information about the convex hull: http://en.wikipedia.org/wiki/Convex_hull

Categories

Resources