Calculate pixels between two points on a image - android

Turns out I am not explaining what I want to do very well so I am going to re-write the whole question again and add graphics to assist in the explanation.
I am designing an app for android/iPhone. I have designed one algorithm for it already, but am stuck on the next one. What I am aiming to do is place two horizontal lines on an image (any image, just a picture taken by the iPhone/android) and then calculate what pixel the lines lye on, to then calculate the number of pixels between them.
I.e.
Take this image:
http://i.stack.imgur.com/41vS1.png
Then place two horizontal lines anywhere on the image, like so:
http://i.stack.imgur.com/ne4tV.png
What I want to calculate is the value of y, or how many vertical pixels are between the two lines. To do this I must know what pixel the two lines lye on.
Assuming that the horizontal lines are both only 1 pixel in height what would I use to work out what pixel in the image the line lies on. I.e. what is the value of the y-intercept(y=mx+c), or c, on each of the horizontal lines.
To explain what I mean further, lets assume that an image is a graph. Each pixel equals a value of 1, so for an image with a resolution of 1920x2560 the maximum value of the y-axis would be 1920 and the maximum of the x-axis would be 2560. How would I design an algorithm to calculate what the y-intercept of both lines are?

Distance between two points (Pythagora):
dx = x1 - x2;
dy = y1 - y2;
dist = sqrt (dx*dx + dy*dy);
Distance between two horizontal lines:
d = y1 - y2;
If your lines are defined as y1 = k1x + n1 and y2 = k2x + n2, then (they're horizontal, k1 and k2 are 0) the distance between them is n2 - n1.
EDIT: ok, after you edited your question it makes a bit more sense now. But still: since you (or user) is adding the lines, your code always knows where they lie. Their end coordinates would be:
line1: {(0,y1):(picture.width,y1)}
line2: {(0,y2):(picture.width,y2)}
distance: |y2-y1|
Since they're both horizontal they ofcourse never cross.
You should just keep a reference to y1 and y2 (from the line-placing code) in an appropriate space. Since your question is for Android and iOS the answer is: in that part of code that would correspond to model in MVC.

Related

Speed and distance not same on every device

I have created an Android game using a canvas, but when testing, I have found that the speed and distance of the movements such as flying up or falling down are set right on a phone with a resolution of 1920x1080 (401 ppi). But when I tested on a smaller phone with a resolution of 480 x 854 (196 ppi), I found that the movement of my sprites are a lot quicker which is affecting the gameplay. E.g. The main character sprite jumps a lot higher than I want it to.
Is there any way of keeping the speed and distance the same across all device sizes and types?
Here is some code on how I have implemented the movement:
A sprite class.
//class variables
private int GRAVITY_LIMIT = -30;
public int gravity = 0;
//gravity
if(gravity>GRAVITY_LIMIT){
gravity= gravity-2;
}
//fall
y= y-gravity;
Drawing the sprite
canvas.drawBitmap(bmp1, x, y, null);
When onTouch is triggered (Jumping)
bird.gravity=30;
You should base your movement around world coordinates. For example, set your world to be 10meters x 10meters, so that when you jump, you jump 1m. You then need to map that world to screen pixels.
float worldHeight = 10f;
float worldToPixels = screenHeight/worldHeight;
y = bird.y * worldToPixels;
So, on a 500px height screen, you would jump 50px and on a 1000px height screen you would jump 100px.
Gravity and other forces need to be based on the world as well for it to work on all devices.
Lastly, if you're trying to make a game for multiple devices, it would be better to use a library like libGDX. There are lots of helpful classes like ViewPorts to make this easier.
I have found another solution.
This one works well.
y= y-(gravity * game.getResources().getDisplayMetrics().density);

Calculate angle of touched point and rotate it on a fixed image or canvas or bitmap image in Android

Ohh.. damm Math !! once again stuck. It seems to be easy but i think its not that easy,
Problem Statement: I want to rotate the 3 fixed points which lies on a fixed circle.
1.when 1 point is selected remaining 2 points should be static mode and only selected point should move/rotate on circumference of circle.
2.And all 3 points are connected via 3 lines as shown in images..when we select a point and rotate it,connected lines also increase and decrease..
I already tried to solve this problem finding angle at each instant after touch.but its not quite working as per my need..
something like this
I hope the following explanation enable you to put the steps into your coding language.
Presumption is that the vertex to be moved has already selected and so the calculation of (xcnd,ycnd) as defined below is used to set the selected vertex of the triangle.
Let the constraining circle have centre at (cx,cy) and radius r.
Let the coordinates of where the screen is touched be (xtch,ytch)
Let the coordinates of where the screen is touched relative to the centre be (xrel,yrel)
then xrel = xtch - cx and yrel = ytch - cy
Let the coordinates of the point on the constraining circle when the screen is touched at (xtch,ytch) be (xcnd,ycnd).
xcndrel = xcnd - cx, and ycndrel = ycnd - cy give the coordinates on the constraining circle relative to its centre,
Note that
xrel and xcndrel will have the same signs (ie both positive or both negative)
and yrel and ycndrel will also have the same signs.
the function abs(x) = x if x>=0 and -x if x<0 should be available in whatever language you are using
the function sign(x) may or may not be available, sign(x) =1 if x>0 and -1 if x<0 and undefined for x=0
If not available then sign(x)=x/abs(x)
Check if xrel=0
if xrel=0 xcndrel=0, ycndrel=r*sign(yrel)
Otherwise work in first quadrant ie where x>0 and y>0 using abs(xrel) and abs(yrel)
find angle where screen is touched relative to centre of circle using
theta=arctan(abs(yrel)/abs(xrel))
find the coordinates (xcndrel, ycndrel) by using theta in the first quadrant and then placing in the correct quadrant using the signs of xrel and yrel
xcndrel = sign(xrel)*r*COS(theta)
ycndrel = sign(yrel)*r*SIN(theta)
Screen coordinates can now be found
xcnd = xcndrel +cx
ycnd = ycndrel + cy

Android - Parabolic motion

I have a moving object in surface view it stat moving from fixed location.
I need set to it to be move like parabolic way ..my object drawn like using x and y so I do
not know using that thread how to calculate the X and y plz help?
The basic formula is:
y=x^2 + m
(m being the x offset)
(the 2 can be an even number higher that 2, but use 2 for now)
Your starting location has the coordinates y0, x0
So you first location is:
y = x0^2 + y0
For the next step calculate your x value like this
x = x0+(n*stepsize)
x0 is you initial x value (see above).
stepsize is the could of pixels offset to each step (simply use 1 for now)
n is the current step inside your drawing loop, like this: for(int n=0;n<100;n++)
then calculate your y value with this x value
y = x^2 + y0
Major Edit:
So i thought of another way to do what you're trying to do which is much simpler:
First you need to define your start (x0|y0) and end (x1|y1) coordinates.
Then use separate formulas to calculate the new position during the animation.
Calculate the distances
x0x1 = x1 - x0
y0y1 = y1 - y0
Define how many animation steps you want (let's say 20)
Devide the distances by this value and in each animation step add that step distance to the last coordinate.
Now to make the whole thing a parabola you'll have to split the distances not evently but logarithmical, at least at the start of the motion. But please try the former before attempting this.
This is a more numerical approach - i hope it helps.

Need help for algorithm to calculate position from current position like this (geometry 2D)

See image below:
illustration http://img28.imageshack.us/img28/5286/pic1we.png
Assume it's on android device screen. Dot #1 is the current position. I want to get the (x,y) position of Dot #2 following the linear blue line (let's say the range between dot #2 and dot #1 is 50dp). The black box is the source point of the blue line.
What is the term for this? Translation?
Is there anyone know the algorithm?
I developed android application using AndEngine, if you know there is built-in function for that, please let me know. Same too for android openGL ES library.
Note: I'm not looking for a way to move object using MoveModifier.
Thx in advance.
Authman's answer is good, but doesn't include how to get a specific distance away. If you're looking for p2 along the line, IMO it's easier to think about this in vectors. First you find the vector along the blue line, which is similar to the process that Authman describes above. If the black box has position v0 = (x0, y0) and the first dot has position v1 = (x1, y1), then your "direction vector" is going to be v1 - v0 = (x1 - x0, y1 - y0). This is a vector that points along the blue line. Once you have that, you normalize it so that the length is 1, and then multiply it by your desired distance, in your case 50. If you want to do it component-wise, here's some quick pseudocode:
find_v2(x0, y0, x1, y1):
direction_x = x1 - x0
direction_y = y1 - y0
norm = sqrt(direction_x^2 + direction_y^2)
direction_x *= 50 / norm
direction_y *= 50 / norm
x2 = x1 + direction_x
y2 = y1 + direction_y
Hope that helps! I'm not sure how comfortable you are with vector math, but if you're doing graphics stuff, it can be really, really useful for problems like this; I'd recommend checking out some of the Khan Academy Linear Algebra courses.
The term you are looking for is extrapolation.
If the black dot is dot '0', then you first calculate your line equation's slope:
m = ( (d0.y-d1.y) / (d0.x-d1.x) )
Then you can extrapolate along that line, either positively (away from point 0) or negatively (towards it, until you get to it, and then eventually again away from in continuing in the line of motion).
dot2.x = d0.x + m*percentage
dot2.y = d0.y + m*percentage
Where percentage is how close you are to dot 1. Thus 1 (eg 100%) would put you on dot 1 exactly. percentage=0 would put you on dot 0 exactly. >1, would put you closer to dot 2. <1 would move you past dot 0, etc.
--
Slight correction there:
dot2.y = d0.x + m*percentage
dot2.x = (dot2.y - dot0.y) / m
The slope as i set it up is only useful for calculating the y coordinate of dot2. Since you already have the equation of the line, you can solve for dot2's x-coord directly using it.

Calculate angle of moving ball after collision with angled or sloped wall that is a 2D line segment

If you have a "ball" inside a 2D polygon, made up of say, 4 line segments that act as bounding walls, how do you calculate the angle of the ball after the collision with the irregularly sloped wall?
I know how to make the ball bounce if the wall is horizontal, vertical, or at a 45 degree angle. I also have my code setup to detect a collision with the wall.
I've read about dot products and normals, but I cannot figure out how to implement these in Java / Android. I'm completely stumped and feel like I've looked up everything 10 pages deep in Google 10 times now. I'm burned out trying to figure this out, I hope someone can help.
Apologies in advance: I don't know the correct Android types. I'm assuming you have a vector type with properties 'x' and 'y'.
If the wall were horizontal and the current velocity were 'vector' then it'd be as easy as:
vector.y = -vector.y;
And you'd leave the x component alone. So you need to do something analogous, but more general.
You do that by substituting the idea of the line normal (a vector perpendicular to the line) for hard coding for the y axis (which is perpendicular to the horizontal).
Since the normal is orthogonal to the line, it can be found by rotating the line by 90 degrees. In 2d, the vector (a, b) can be rotated by 90 degrees by converting it to (-b, a). Hence if you have a line from (x1, y1) to (x2, y2) then you can get the normal with:
vectorAlongLine.x = x2 - x1;
vectorAlongLine.y = y2 - y1;
normal.x = -vectorAlongLine.y;
normal.y = vectorAlongLine.x;
You don't actually care how long the original line was (and it'll affect computations later when you don't want it to), so you want to make the normal be of length 1 irrespective of its current length. You can do that by dividing it by its current length. So, e.g.
lengthOfNormal = Math.sqrt(normal.x*normal.x + normal.y*normal.y);
normal.x /= lengthOfNormal;
normal.y /= lengthOfNormal;
Using the Pythagorean theorem there to get the length.
With the horizontal line, flipping on the y axis was the same as (i) working out what the extent of the vector extends along the y axis; and (ii) subtracting that amount twice — once to get the velocity to be 0 in that direction, again to make it the negative version of the original. That is, it's the same as:
distanceAlongNormal = vector.y;
vector.y -= 2.0 * distanceAlongNormal;
The dot product is used in the general case is to work how far the vector extends along the normal. So it does the same as taking vector.y does for the horizontal line. This is where you possibly have to take a bit of a leap of faith. It's a property of the dot product and you can persuade yourself by inspecting a right-angled triangle. But for now, if you had a horizontal line, you'd have ended up with the normal (0, 1). Since the dot product would be:
vector.x * normal.x + vector.y * normal.y
You'd compute:
distanceAlongNormal = vector.x * 0.0 + vector.y * 1.0;
Which is obviously the same thing as just taking the y component.
Having worked out the distance along the normal, you actually want to then subtract that amount times the normal times two. The only additional step here is multiplying by the normal to get a 2d quantity to subtract. That's because you're looking to subtract in the order of the normal. So complete code, based on a normal computed earlier, is:
distanceAlongNormal = vector.x * normal.x + vector.y * normal.y;
vector.x -= 2.0 * distanceAlongNormal * normal.x;
vector.y -= 2.0 * distanceAlongNormal * normal.y;
If you hadn't made normal of length 1, then you'd need to divide by the length here, since the dot product would scale the distanceAlongNormal value by that amount.
This might come in handy for you
http://www.tonypa.pri.ee/vectors/tut07.html

Categories

Resources