Convert point(x,y) within bounding box[(x1,y1),(x2,y2),(x3,y3),(x4,y4)] to account for heading - point

Need help converting a point (716, 493) within a bounding box to the perspective of a 0 degree heading.
Current heading: 307
point: 716, 493
x1: 711, y1: 554
x2: 659 ,y2: 519
x3: 708, y3: 479
x4: 758, y4: 512
Currently this point is accurate with a heading of 307 degrees but I need to move this point to be from a 0 degree heading perspective. Reason for conversion is I am overlaying this point on top of another bounding box with perspective of 0 degree heading. As you can imagine the point is off by whatever degree difference is between heading of current point and 0 degrees, but I'm not sure how to calculate what the point x,y should be.
Any help is appreciated!!
For all the non-geniuses like me I found a algorithm to rotate a point about an origin by a certain number of degrees:
function rotate(origin, point, angle){
var ox = origin[0];
var oy = origin[1];
var px = point[0];
var py = point[1];
var qx = ox + Math.cos(angle) * (px - ox) - Math.sin(angle) * (py - oy);
var qy = oy + Math.sin(angle) * (px - ox) + Math.cos(angle) * (py - oy);
return [qx,qy];
}
rotate([0,0],[716,493],-53 * Math.PI/ 180)
So I believe this is correct. angle needs to be in radians. So I wanted to rotate my point from 307 to 90 degrees so I took the difference of 360 - 307 = 53 then I negate the angle to move that many degrees clockwise.
Hope this helps someone who is a non-geniuses like me. And if this is wrong, well sorry my post was given a -1 so no one else would look at it and give ideas.

Related

Drawing a circle without using a function for it

So I was wondering how does a circle() function work, and how can I draw to circle without using it (wanted to do something related to it). Does anyone know this stuff?
A classic way of rasterizing a circle is using the Midpoint Circle Algorithm.
It works by tracking the pixels which are as close to the x2 + y2 = r2 isoline as possible. This can even be done with purely integer calculations, which is particularly suitable for low-computation power devices.
A circle is the set of points located at a constant distance from another point, called the center.
If you can draw lines defined by two points, you can draw the representation of a circle on a canvas, knowing its center, and its radius.
The approach is to determine a set of consecutive points located on the circumference, then join them with lines.
for instance, in python (which reads like pseudocode):
import math
def make_circle(center, radius, num_points=40):
"""returns a sequence of points on the circumference
"""
points = [center]
d_theta = 2 * math.pi / num_points
cx, cy = center
for idx in range(num_points + 1):
theta = idx * d_theta
points.append((cx + math.cos(theta) * radius, cy + math.sin(theta) * radius))
return points
And if you want to try it, here it is: circles codeskulptor.
You will see that for display purposes, 40 points on the circumference is enough to give an acceptable rendition.

Python 3 Tkinter canvas

I am trying to draw a clock that works. I am using a 600x600 form. I cant' figure out how to place the oval in the center of the form or how to add the minutes or the seconds tick marks inside the oval. I tried dash but couldn't get it to look right. Any suggestions. Thanks in advance.
This is what I have done so far:
from tkinter import *
canvas_width = 600
canvas_height = 600
master = Tk()
w = Canvas(master, width = canvas_width, height = canvas_height)
w.pack()
oval = w.create_oval(75,75,500,500)
minline = w.create_line(150,150,300,300)
mainloop()
The center of a drawn shape is the middle of the two points specified when it is drawn. Currently, the middle point of your shape (draw from 75, 75 to 500, 500) is 237.5, so, if you want the middle of it to be the middle of your page, and keep the 75, 75 coordinate, you would have to make the other one 525, 525 to completely mirror the first.
As for drawing the shape, you'll need some math in python, so I would first suggest doing an image as the background for the clock, so that less objects are drawn. But, if you must do it without other images, you must first import the math library.
import math
Now, for a mathematic principle: Any point on the circle of radius r can be expressed as the point (r*cosθ), (r*sinθ), where θ is the angle from the center to the point. The reason this is important is that you want each line on the side of the clock face to be pointing towards the center of the circle. To do that, we need the two points to draw the line on that together point towards the center, and fortunately for us this means that both points on the line are on different circles (our circle and one within it) but are at the same angle from the center.
Since we want 12 hour points around the circle, and 4 minute points between each of those (so 60 points in total), and 360 degrees in a circle (so 1 point for every 6 degrees), we will need a for loop that goes through that.
for angle in range(0, 360, 6):
Then we'll want 3 constants: One for the radius of the exterior circle (for the points to begin from), one for an interior circle (for the minute points to add at), and one for an even more interior circle (for the hour points to end at). We'll also want it to choose the more interior radius only every 30 degrees (because it appears every 5 points, and there are 6 degrees between them).
radius_out = 225
radius_in = 0 #temporary value
if (angle % 30) == 0: #the % symbol checks for remainder
radius_in = 210
else:
radius_in = 220
Now, for the conversion into radians (As math in python needs radians for sin and cos):
radians = (angle / 180) * math.pi
Next off, assigning the coordinates to variables so it's easier to read.
x_out = (radius_out * math.cos(radians)) + 300
y_out = (radius_out * math.sin(radians)) + 300
x_in = (radius_in * math.cos(radians)) + 300
y_in = (radius_in * math.sin(radians)) + 300
#the (+ 300) moves each point from a relative center of 0,0 to 300,300
And finally we assign it to a list so we can access it later if we need to. Make sure to define this list earlier outside of the for loop.
coords.append( w.create_line(x_out, y_out, x_in, y_in) )
This should give you your clock lines.
NOTE: Due to the way tkinter assigns x and y coordinates, this will draw lines from the 3 hour line clockwise back to it.
Hope this was helpful! If there is anything you don't understand, comment it below.

algorithm of calculating the slope between line relatively to center coordinate

Please help with the algorithm of calculating the slope
So we have a Cartesian coordinate system. X right at Y the top. There is a line which passes through the center of coordinates.
Needed to determine the angle relatively to the axis OX.
So here's what I'm doing
Certain functions transferred to the origin (top line) and end of line
Determine dx, dy
Hildren releases two parameters in atan2 (dy, dx)
Returns the result in radians.
But! I atan2 works only within 180 degrees. After 180 goes in another direction.
So the question: what is the correct algorithm for finding the angle? Do I need to take dy, dx values in magnitude? How to make the arctangent calculated for all 360 and more? I would be glad to hear specific algorithms, or pieces of code comments.
Thanx!
static inline CGFloat angleBetweenLinesInRadians2 (CGPoint line1Start, CGPoint line1End)
{
CGFloat dx = 0, dy = 0;
dx = line1End.x - line1Start.x; / / whether to do fabs (line1End.x - line1Start.x);
dy = line1End.y - line1Start.y;
CGFloat rads = atan2 (dy, dx); / / whether to do fabs (rads)
return rads;
}
atan2() is supposed to return a value in the interval [-pi,pi] (i.e. [-180, 180] ), and works with the signs of x and y to figure out the quadrant. (C++ ref)
So technically, you have 360 degrees.
A formula to calculate an angle from 0 to 360 degrees :
f(x,y)=180-90*(1+sign(x))* (1-sign(y^2))-45*(2+sign(x))*sign(y)
-180/pi()*sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))
x=x2-x1 and y=y2-y1 .

Ray Generation Inconsistency

I have written code that generates a ray from the "eye" of the camera to the viewing plane some distance away from the camera's eye:
R3Ray ConstructRayThroughPixel(...)
{
R3Point p;
double increments_x = (lr.X() - ul.X())/(double)width;
double increments_y = (ul.Y() - lr.Y())/(double)height;
p.SetX( ul.X() + ((double)i_pos+0.5)*increments_x );
p.SetY( lr.Y() + ((double)j_pos+0.5)*increments_y );
p.SetZ( lr.Z() );
R3Vector v = p-camera_pos;
R3Ray new_ray(camera_pos,v);
return new_ray;
}
ul is the upper left corner of the viewing plane and lr is the lower left corner of the viewing plane. They are defined as follows:
R3Point org = scene->camera.eye + scene->camera.towards * radius;
R3Vector dx = scene->camera.right * radius * tan(scene->camera.xfov);
R3Vector dy = scene->camera.up * radius * tan(scene->camera.yfov);
R3Point lr = org + dx - dy;
R3Point ul = org - dx + dy;
Here, org is the center of the viewing plane with radius being the distance between the viewing plane and the camera eye, dx and dy are the displacements in the x and y directions from the center of the viewing plane.
The ConstructRayThroughPixel(...) function works perfectly for a camera whose eye is at (0,0,0). However, when the camera is at some different position, not all needed rays are produced for the image.
Any suggestions what could be going wrong? Maybe something wrong with my equations?
Thanks for the help.
Here's a quibble that may have nothing to do with you problem:
When you do this:
R3Vector dx = scene->camera.right * radius * tan(scene->camera.xfov);
R3Vector dy = scene->camera.up * radius * tan(scene->camera.yfov);
I assume that the right and up vectors are normalized, right? In that case you want sin not tan. Of course, if the fov angles are small it won't make much difference.
The reason why my code wasn't working was because I was treating x,y,z values separately. This is wrong, since the camera can be facing in any direction and thus if it was facing down the x-axis, the x coordinates would be the same, producing increments of 0 (which is incorrect). Instead, what should be done is an interpolation of corner points (where points have x,y,z coordinates). Please see answer in related post: 3D coordinate of 2D point given camera and view plane

How do I find the lat/long that is x km east/west of a given lat/long?

I have two given lat and lon points. For example, lets assume I have two positions (point_1 and point_2) at coordinates (lat1, lon1) and (lat2, lon2).
I would like to calculate a third point, that is on the same latitude as that of point_2, but x km to the east or west of point_2. So the third point will have the same latitude as point_2, but a different longitude depending on distance x (in kilometers), in other words point_3 will be (lat2, lon?).
I am writing this in IDL, but any other language or formulas would be very welcome.
Thanks
You don't use point 1 anywhere, do you? Let's say our point is P = (lat, lon)
The first rule of problems like this: draw a picture! From a cross-section of the earth, you can see that the radius of the circle centered on the earth's axis, going through your two points, is R*cos(lat). (R is the earth's radius. I hope you don't need to consider the earth an ellipsoid here.) The length x therefore takes up an angle (in degrees) of 360*x/(2*pi*R*cos(lat)). The new point you want is then:
P' = ( lat, lon +- 180*x/(2Rcos(lat)) )
I'm assuming you're using -180 to 0 for west longitude, so you have +/- for east/west. You'll have to check if you need to wrap around. Pseudo-code:
if (lon < -180)
lon += 360
else if (long > 180)
lon -= 360
Just for fun: if you do care about the earth being ellipsoidal, the radius of the circle is (instead of R*cos(lat)):
1/sqrt(tan^2 lat / Rp^2 + 1 / Re^2)
where Rp is the polar radius and Re is the equatorial radius. If Rp = Re, this reduces to the original formula, since 1 + tan^2 lat = sec^2 lat
import math
R = 6378.1 #Radius of the Earth
brng = 1.57 #Bearing is 90 degrees converted to radians.
d = 15 #Distance in km
#lat2 52.20444 - the lat result I'm hoping for
#lon2 0.36056 - the long result I'm hoping for.
lat1 = math.radians(52.20472) #Current lat point converted to radians
lon1 = math.radians(0.14056) #Current long point converted to radians
lat2 = math.asin( math.sin(lat1)*math.cos(d/R) +
math.cos(lat1)*math.sin(d/R)*math.cos(brng))
lon2 = lon1 + math.atan2(math.sin(brng)*math.sin(d/R)*math.cos(lat1),
math.cos(d/R)-math.sin(lat1)*math.sin(lat2))
lat2 = math.degrees(lat2)
lon2 = math.degrees(lon2)
print(lat2)
print(lon2)

Resources