Calculate move by one pixel in the direction on specific point - python

I would like to move my image by one pixel in the direction on specific point. Right now I have:
My image cords:
position.x
position.y
Coordinates of the point where I want to move:
dest.x
dest.y
And the angle at which I must move to reach the designated place:
angle
How should you calculate for each step add / subtract 1 for x and y?

If you want to move only in increments of 1 pixel in x or y at a time, it sounds like the coordinates you want correspond with the pixels on a straight line from source to destination. A common algorithm for drawing a pixellated straight line is the Bresenham algorithm:
https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
So instead of drawing pixels, you could use the coordinates to position your image.

Assuming the angle is in radians, use trigonometry:
import math
x += math.cos(angle) * amount_to_move
y += math.sin(angle) * amount_to_move

Related

Need to know if a sphere intersects with cube using python code...?

I am developing a code in python to check whether a sphere having a center at (x, y, z) coordinates and with radius R, intersects the cube of dimension one, i.e., l = 1, b = 1, h = 1. As mentioned above, I want to know if the sphere intersects the cube at any point or direction, or proportion.
I have a list of sphere coordinates (x,y,z) that must be checked for the intersection. I had done some research on it but couldn't clear my doubts regarding how to approach this example.
I would love to know both the math and coding part of it. Can someone please help me solve it..??
Edit: Cube is axis aligned and placed at the origin.
To reveal a fact of intersection, you can calculate distance from cube to sphere center and compare it with sphere radius. 2D case is described here, it could be easily extended to 3D case.
Get cube center as (rcx, rcy, rcz) and find coordinate differences from cube center to sphere center
dx, dy, dz = x - rcx, y - rcy, z - rcz
Let SquaredDist = 0, and for every coordinate make:
t = dx + 0.5 # 0.5 is half-size of your cube
if t < 0:
SquaredDist += t * t
else:
t = dx - 0.5
if t > 0:
SquaredDist += t * t
finally compare SquaredDist with R*R
Some explanation to comment:
Look at the picture in linked answer. For rectangle ABCD we have center G and coordinate differences GK and GJ, they include half of width and half of height. Squared distance (EC here) is sum of squared distances to proper side lines (planes in 3D case). When the closest (to sphere center) point is cube corner, we take into account three planes, when closest point lies at the edge - we take into account two planes, when closest point lies at facet - we take into account only one plane, and when sphere center is inside - SquaredDist remains zero.

automated semi-circular path movement with pygame

I'm trying to create a traffic simulator using python (+ pygame and math libs).
I'm stuck at car movements, I've managed to create a fixed horizontal and vertical path using a list of coordinates, using nested for loops.
Now, since I'm in a crossroads I now have to make the 1/4 of a circle to make a left or right turn.
The car has to make a straight path for n pixels (and it's ok) then have to make the 1/4 following a circular path and then proceed towards a straight line again.
I have a list of coordinates, however, I don't know how to make it turn around the center of the circumference (which I know the coordinates of) while also turning the image relative to the center!
I'll give you an idea of the problem using an image
The red paths "1" are done, the problem is the blue tract "2", "O" coordinates are known, there are 4 "O" in total (one for each path).
I would suggest to use the equation of a circle which is (x – h)^2 + (y – k)^2 = r^2 where (h,k) are the coordinates of the cercle's center and r the radius.
The idea in your case could be to draw all discrete points (x,y) that verify this equation,
here is an example (for points where x and y are positive regarding the origin, if we follow your example):
import numpy as np
import matplotlib.pyplot as plt
center = (10,10)
radius = 5
th = 0.01
for x in np.arange(center[0],center[0]+radius+th, th):
for y in np.arange(center[1], center[1]+radius+th, th):
if abs((x-center[0])**2 + (y-center[1])**2 - radius**2) < th:
plt.scatter(x,y)
plt.show()
You can then control the number of points with the th, and even draw lines instead of just points to speed up the process

How to recalculate the coordinates of a point after scaling and rotation?

I have the coordinates of 6 points in an image
(170.01954650878906, 216.98866271972656)
(201.3812255859375, 109.42137145996094)
(115.70114135742188, 210.4272918701172)
(45.42426300048828, 97.89037322998047)
(167.0367889404297, 208.9329833984375)
(70.13690185546875, 140.90538024902344)
I have a point as center [89.2458, 121.0896]. I am trying to re-calculate the position of points in python using 4 rotation degree (from 0,90,-90,180) and 6 scaling factor (0.5,0.75,1,1.10,1.25,1.35,1.5).
My question is how can I rotate and scale the abovementioned points relative to the center point and get the new coordinates of those 6 points?
Your help is really appreciated.
Mathematics
A mathematical approach would be to represent this data as vectors from the center to the image-points, translate these vectors to the origin, apply the transformation and relocate them around the center point. Let's look at how this works in detail.
Representation as vectors
We can show these vectors in a grid, this will produce following image
This image provides a nice way to look at these points, so we can see our actions happening in a visual way. The center point is marked with a dot at the beginning of all the arrows, and the end of each arrow is the location of one of the points supplied in the question.
A vector can be seen as a list of the values of the coordinates of the point so
my_vector = [point[0], point[1]]
could be a representation for a vector in python, it just holds the coordinates of a point, so the format in the question could be used as is! Notice that I will use the position 0 for the x-coordinate and 1 for the y-coordinate throughout my answer.
I have only added this representation as a visual aid, we can look at any set of two points as being a vector, no calculation is needed, this is only a different way of looking at those points.
Translation to origin
The first calculations happen here. We need to translate all these vectors to the origin. We can very easily do this by subtracting the location of the center point from all the other points, for example (can be done in a simple loop):
point_origin_x = point[0] - center_point[0] # Xvalue point - Xvalue center
point_origin_y = point[1] - center_point[1] # Yvalue point - Yvalue center
The resulting points can now be rotated around the origin and scaled with respect to the origin. The new points (as vectors) look like this:
In this image, I deliberately left the scale untouched, so that it is clear that these are exactly the same vectors (arrows), in size and orientation, only shifted to be around (0, 0).
Why the origin
So why translate these points to the origin? Well, rotations and scaling actions are easy to do (mathematically) around the origin and not as easy around other points.
Also, from now on, I will only include the 1st, 2nd and 4th point in these images to save some space.
Scaling around the origin
A scaling operation is very easy around the origin. Just multiply the coordinates of the point with the factor of the scaling:
scaled_point_x = point[0] * scaling_factor
scaled_point_y = point[1] * scaling_factor
In a visual way, that looks like this (scaling all by 1.5):
Where the blue arrows are the original vectors and the red ones are the scaled vectors.
Rotating
Now for rotating. This is a little bit harder, because a rotation is most generally described by a matrix multiplication with this vector.
The matrix to multiply with is the following
(from wikipedia: Rotation Matrix)
So if V is the vector than we need to perform V_r = R(t) * V to get the rotated vector V_r. This rotation will always be counterclockwise! In order to rotate clockwise, we simply need to use R(-t).
Because only multiples of 90° are needed in the question, the matrix becomes a almost trivial. For a rotation of 90° counterclockwise, the matrix is:
Which is basically in code:
rotated_point_x = -point[1] # new x is negative of old y
rotated_point_y = point[0] # new y is old x
Again, this can be nicely shown in a visual way:
Where I have matched the colors of the vectors.
A rotation 90° clockwise will than be
rotated_counter_point_x = point[1] # x is old y
rotated_counter_point_y = -point[0] # y is negative of old x
A rotation of 180° will just be taking the negative coordinates or, you could just scale by a factor of -1, which is essentially the same.
As last point of these operations, might I add that you can scale and/or rotated as much as you want in a sequence to get the desired result.
Translating back to the center point
After the scaling actions and/or rotations the only thing left is te retranslate the vectors to the center point.
retranslated_point_x = new_point[0] + center_point_x
retranslated_point_y = new_point[1] + center_point_y
And all is done.
Just a recap
So to recap this long post:
Subtract the coordinates of the center point from the coordinates of the image-point
Scale by a factor with a simply multiplication of the coordinates
Use the idea of the matrix multiplication to think about the rotation (you can easily find these things on Google or Wikipedia).
Add the coordinates of the center point to the new coordinates of the image-point
I realize now that I could have just given this recap, but now there is at least some visual aid and a slight mathematical background in this post, which is also nice. I really believe that such problems should be looked at from a mathematical angle, the mathematical description can help a lot.

How do I draw a random dot in a circle in python?

So I have my circle drawn already, it has a radius of 140. Should I use r.randint(-140,140) to throw a random dot? and how do I make it seen in the circle(turtle graphic)?
You will need to verify that the point is actually inside your circle before you draw it, the point (-140,-140) isn't inside the circle for example but could be generated by (randint(-140,140), randint(-140,140)).
The common way of doing this is to loop until you get a result that fits your restrictions, in your case that its distance from (0,0) is less than the radius of the circle:
import math, random
def get_random_point(radius):
while True:
# Generate the random point
x = random.randint(-radius, radius)
y = random.randint(-radius, radius)
# Check that it is inside the circle
if math.sqrt(x ** 2 + y ** 2) < radius:
# Return it
return (x, y)
A non-looping variant:
import math, random, turtle
turtle.radians()
def draw_random_dot(radius):
# pick random direction
t = random.random() * 2 * math.pi
# ensure uniform distribution
r = 140 * math.sqrt(random.random())
# draw the dot
turtle.penup()
turtle.left(t)
turtle.forward(r)
turtle.dot()
turtle.backward(r)
turtle.right(t)
for i in xrange(1000): draw_random_dot(140)
It depends on where the beginning of the coordinate system is. If zeros start in the left upper conner of the picture, while loop is needed to make sure that dots are being placed within the circle's boundaries. If xy coordinates start in the center of the circle then the placement of the dots is limited by the circle's radius. I made a script for Cairo. It is not too too off topic. https://rockwoodguelph.wordpress.com/2015/06/12/circle/

python: elegant way of finding the GPS coordinates of a circle around a certain GPS location

I have a set of GPS coordinates in decimal notation, and I'm looking for a way to find the coordinates in a circle with variable radius around each location.
Here is an example of what I need. It is a circle with 1km radius around the coordinate 47,11.
What I need is the algorithm for finding the coordinates of the circle, so I can use it in my kml file using a polygon. Ideally for python.
see also Adding distance to a GPS coordinate for simple relations between lat/lon and short-range distances.
this works:
import math
# inputs
radius = 1000.0 # m - the following code is an approximation that stays reasonably accurate for distances < 100km
centerLat = 30.0 # latitude of circle center, decimal degrees
centerLon = -100.0 # Longitude of circle center, decimal degrees
# parameters
N = 10 # number of discrete sample points to be generated along the circle
# generate points
circlePoints = []
for k in xrange(N):
# compute
angle = math.pi*2*k/N
dx = radius*math.cos(angle)
dy = radius*math.sin(angle)
point = {}
point['lat']=centerLat + (180/math.pi)*(dy/6378137)
point['lon']=centerLon + (180/math.pi)*(dx/6378137)/math.cos(centerLat*math.pi/180)
# add to list
circlePoints.append(point)
print circlePoints
Use the formula for "Destination point given distance and bearing from start point" here:
http://www.movable-type.co.uk/scripts/latlong.html
with your centre point as start point, your radius as distance, and loop over a number of bearings from 0 degrees to 360 degrees. That will give you the points on a circle, and will work at the poles because it uses great circles everywhere.
It is a simple trigonometry problem.
Set your coordinate system XOY at your circle centre. Start from y = 0 and find your x value with x = r. Then just rotate your radius around origin by angle a (in radians). You can find the coordinates of your next point on the circle with Xi = r * cos(a), Yi = r * sin(a). Repeat the last 2 * Pi / a times.
That's all.
UPDATE
Taking the comment of #poolie into account, the problem can be solved in the following way (assuming the Earth being the right sphere). Consider a cross section of the Earth with its largest diameter D through our point (call it L). The diameter of 1 km length of our circle then becomes a chord (call it AB) of the Earth cross section circle. So, the length of the arc AB becomes (AB) = D * Theta, where Theta = 2 * sin(|AB| / 2). Further, it is easy to find all other dimensions.

Categories

Resources