Getting the position of an (real) object - python

The story: Lets say I have a robot with a distance (ultrasound?) sensor. The robot can calculate the distance from any object in front of it but it cannot know the coordinates of the object. So the robot moves a little bit to get a diffrent view angle and calculates the distance from that view knowing how far it is from the first view.
How do I get the coordinates or some kind of position of a real life object in Python 3.4 with the following input.
Distance from object at view A.
Distance from object at view B.
Distance between view A and B.
A and B are always on the same X coordinate.
Input example:
a = 3.5 #Distance from object at point A (in cm)
b = 7 # Disatance from object at point B (in cm)
c = 5 # Distance between A and B (in cm)
The output should be some coordinates or something that I can use to find out the position of an object.
How would I calculate where the object is? I know there is some kind of an algorithm but I don't know what it's called or how it works.
I guess this is more a math question than a programming question but I want to implement this programmatically.
Anyways the input doesn't need to be exactly this. I guess you would also need an angle or something similar so if extre input is needed just use it in the anwser.
Thanks!
(I am on Win 10, 64bit, Python 3.4)
If you know how to do this or some algorithm name but you don't know Python, please point it out or give an example of how to do it with math, and I will try to implement it in Python.

Draw the triangle ABC with coordinates (0,0), (b,0), (cx,cy) (fix the origin at A for want of anywhere better to put it -- you can always shift your coordinates later).
Then you know the quantities AC^2 = cx^2 + cy^2, BC^2 = (cx-b)^2 + cy^2. These equations you can solve for cx = (AC^2 - BC^2 + b^2)/2b and cy = +/- sqrt(AC^2 - cx^2).
Note that you don't provide enough information to deduce the sign of cy (which "side" of the x-axis your object is).
This is straightforward to code in Python.

The object is in two circumferences, one with center in position 1 of the robot (known) and radius a (= distance from position 1 to object) and another with center in position 2 and radius b (= distance from position 2 to object). Then it is a matter of finding the intersection of these two circumferences. Since the circumferences will intersect in two points you still have to determine in which one of these points the object is. Therefore you will need some additional information to decide this, but I'm sure with this little help you will get started.

Are you using an ultrasonic sensor?
A = (-c/2, 0)
B = (+c/2, 0)
C = (tx, ty), ty >= 0
then
AC^2 = (tx+c/2)^2 + ty^2 = a^2
BC^2 = (tx-c/2)^2 + ty^2 = b^2
Since the answer is uniquely determined, it is only solved after.

Related

Finding crossing numbers: Drawing a bipartite graph using Python turtle

At first I must say I am from Mathematics background and I have a very little knowledge about programming in Python. I am working on drawing complete bipartite graph with minimum number of crossings. For example: K(4,4) the complete bipartite graph with 8 vertices (grouped in 4 - 4) given in the following diagram.
The graph has crossing number = 4. I would like to draw graphs like this with higher number of vertices for example K(9,9), complete bipartite graph with 18 vertices. I have searched for different coding and theories. I found that Python has turtle package that can help me in this matter. I have planned to use an algorithm: I will start the turtle's journey from one vertex and stop on other vertex, in between the journey I will collect the coordinates of the path where it traveled and then repeat the process under the condition that It must not coincide with any other edge, if this happens then take the path which has minimum number of intersections.
Currently I am working on turtle and its commands. Any idea on how solve this problem, any recommendations on using more suitable software (paid or open source), help on algorithm, recommendations on books or research papers is highly appreciated.
I have made this diagram using yED (freely available) but for higher number of vertices manual work is very laborious.
Thanks in advance!
Sorry I'm not exactly answering the question re turtle graphics. Since you are a mathematician, don't you use LaTeX? If so, here's a little program to get you started:
from string import Template
DOC = Template("""
\\documentclass{article}
\\usepackage{tikz}
\\begin{document}
\\begin{tikzpicture}
$drawing\\end{tikzpicture}
\\end{document}
""")
class GraphDrawing(object):
def __init__(self, node_count: int):
self.node_count = node_count;
def Coord(self, i: int):
c = self.node_count
offset = 1 - c if c % 2 == 0 else - c
return offset + 2 * i
def Draw(self):
r = ''
for i in range(self.node_count):
for j in range(self.node_count):
r += f'\\draw ({self.Coord(i)},0) -- (0,{self.Coord(j)});\n'
for i in range(self.node_count):
r += f'\\filldraw ({self.Coord(i)},0) circle (3pt);\n'
r += f'\\filldraw (0,{self.Coord(i)}) circle (3pt);\n'
print(DOC.substitute({'drawing' : r}))
GraphDrawing(8).Draw()
Run through pdflatex, this produces:
If you really need turtle graphics, it should be pretty straightforward to replace the string construction in this program with turtle moves.
As http://garden.irmacs.sfu.ca/op/the_crossing_number_of_the_complete_bipartite_graph says, it is believed that the diagram you provided is always optimal. Put the one set on a vertical axis and the other on the horizontal, split close to evenly top/bottom, left/right. Then connect by straight lines. It is highly unlikely that you will find better than that.
You can see https://mathworld.wolfram.com/ZarankiewiczsConjecture.html for more, including various small n cases where it has been confirmed.

Beginner - Find in which "district" a point is located

I use a NumPy library in Python and I have an exercise as follows:
Let's admit a map (a false one) with both x and y axes going from 0 to 1, representing 1 Km² of territory. Each point is an individual and it is placed on this map using normalized coordinates.
There is also a frontier separating the map into two "districts". This is not a straight one, and it must pass through A/B/C/D points, which are :
A = (0., 0.3711257)
B = (0.496042,0.62673)
C = (0.781478,0.510147)
D = (1.,0.73035714)
One part of the exercice is to know in which district any new point is located.
Obviously, I cannot just make a condition to compare the coordinates of an individual with A-B-C-D, but I don't know what I can do.
I'll be glad for any suggestions.

Fast great circle for multiple points - Python geopy

Is it possible to speed up the great_circle(pos1, pos2).miles from geopy if using it for multiple thousand points?
I want to create something like a distance matrix and at the moment my machine needs 5 seconds for 250,000 calculations.
Actually pos1 is always the same if it helps.
Another "restriction" in my case is that I only want all points pos2 which have a distance less than a constant x.
(The exact distance doesn't matter in my case)
Is there a fast method? Do I need to use a faster function than great_circle which is less accurate or is it possible to speed it up without losing accuracy?
Update
In my case the question is whether a point is inside a circle.
Therefore it is easily possible to first get whether a point is inside a square.
start = geopy.Point(mid_point_lat, mid_point_lon)
d = geopy.distance.VincentyDistance(miles=radius)
p_north_lat = d.destination(point=start, bearing=0).latitude
# check whether the given point lat is > p_north_lat
# and so on for east, south and west

Find third coordinate of (right) triangle given 2 coordinates and ray to third

I start explaining my problem from very far, so you could suggest completely different approaches and understand custom objects and functions.
Over years I have recorded many bicycle GPS tracks (.gpx). I decided to merge these (mostly overlapping) tracks into a large graph and merge/remove most of track points. So far, I have managed to simplify tracks (feature in gpxpy module, that removes about 90% of track-points, while preserving positions of corners) and load them into my current program.
Current Python 3 program consists of loading gpx tracks and optimising graph with four scans. Here's planned steps in my program:
Import points from gpx (working)
Join points located close to each other (working)
Merge edges under small angles (Problem is with this step)
Remove points on straights (angle between both edges is over 170 degrees). Looks like it is working.
Clean-up by resetting unique indexing of points (working)
Final checking of all edges in graph.
In my program I started counting steps with 0, because first one is simply opening and parsing file. Stackoverflow doesn't let me to start ordering from 0.
To store graph, I have a dictionary punktid (points in estonian), where punkt (point) object is stored at key uid/ui (unique ID). Unique ID is also stored in point itself too. Weight attribute is used in 2-nd and 3-rd step to find average of points while taking into account earlier merges.
class punkt:
def __init__(self,lo,la,idd,edge=set(),ele=0, wei=1):
self.lng=lo #Longtitude
self.lat=la #Latitude
self.uid=idd #Unique ID
self.edges=edge #Set of neighbour nodes
self.att=ele #Elevation
self.weight=wei #Used to get weighted average
>>> punktid
{1: <__main__.punkt object at 0x0000006E9A9F7FD0>,
2: <__main__.punkt object at 0x0000006E9AADC470>, 3: ...}
>>> punktid[1].__dict__
{'weight': 90, 'uid': 9000, 'att': 21.09333333333333, 'lat': 59.41757, 'lng': 24.73907, 'edges': {1613, 1218, 1530}}
As you can see, there is a minor bug in clean-up, where uid was not updated. I have fixed it by now, but I left it in, so you could see scale of graph. Largest index in punktid was 1699/11787.
Getting to core problem
Let's say I have 3 points: A, B and C (i, lyhem(2) and lyhem(0) respectively in following code slice). A has common edge with B and C, but B and C might not have common edge. C is closer to A than B. To reduce size of graph, I want to move C closer to edge AB (while respecting weights of B and C) and redirect AB through C.
Solution I came up with is to find temporary point D on AB, which is closest to C. Then find weighted average between D and C, save it as E and redirect all C edges and AB to that. Simplified figure - note, that E=(C+D)/2 is not completely accurate. I cannot add more than two links, but I have additional 2 images illustrating my problem.
Biggest problem was finding coordinates of D. I found possible solution on Mathematica site, but it contains ± sign, because when finding coordinate there are two possible coordinates. But I have line, where point is located on. Anyway, I don't know how to implement it correctly and my code has become quite messy:
# 2-nd run: Merge edges under small angles
for i in set(punktid.keys()):
try:
naabrid1=frozenset(punktid[i].edges) # naabrid / neighbours
for e in naabrid1:
t=set(naabrid1)
t.remove(e)
for u in t:
try:
a=nurk_3(punktid[i], punktid[e], punktid[u]) #Returns angle EIU in degrees. 0<=a<=180
if a<10:
de=((punktid[i].lat-punktid[e].lat)**2+
((punktid[i].lng-punktid[u].lng))*2 **2) #distance i-e
du=((punktid[i].lat-punktid[u].lat)**2+
((punktid[i].lng-punktid[u].lng)*2) **2) #distance i-u
b=radians(a)
if du<de:
lyhem=[u,du,e] # lühem in English is shorter
else: # but currently it should be lähem/closer
lyhem=[e,de,u]
if sin(b)*lyhem[1]<r:
lr=abs(sin(b)*lyhem[1])
ml=tan(nurk_coor(punktid[i],punktid[lyhem[0]])) #Lühema tõus / Slope of closer (C)
mp=tan(nurk_coor(punktid[i],punktid[lyhem[2]])) #Pikema / ...farer / B
mr=-1/ml #Ristsirge / ...BD
p1=(punktid[i].lng+lyhem[1]*(1/(1+ml**2)**0.5), punktid[i].lat+lyhem[1]*(ml/(1+ml**2)**0.5))
p2=(punktid[i].lng-lyhem[1]*(1/(1+ml**2)**0.5), punktid[i].lat-lyhem[1]*(ml/(1+ml**2)**0.5))
d1=((punktid[lyhem[0]].lat-p1[1])**2+
((punktid[lyhem[0]].lng-p1[0])*2)**2)**0.5 #distance i-e
d2=((punktid[lyhem[0]].lat-p2[1])**2+
((punktid[lyhem[0]].lng-p2[0])*2)**2)**0.5 #distance i-u
if d1<d2: # I experimented with one idea,
x=p1[0]#but it made things worse.
y=p1[1]#Originally I simply used p1 coordinates
else:
x=p2[0]
y=p2[1]
lo=punktid[lyhem[2]].weight*p2[0] # Finding weighted average
la=punktid[lyhem[2]].weight*p2[1]
la+=punktid[lyhem[0]].weight*punktid[lyhem[0]].lat
lo+=punktid[lyhem[0]].weight*punktid[lyhem[0]].lng
kaal=punktid[lyhem[2]].weight+punktid[lyhem[0]].weight #kaal = weight
c=(la/kaal,lo/kaal)
punktid[ui]=punkt(c[1],c[0], ui,punktid[lyhem[0]].edges, punktid[lyhem[0]].att,kaal)
punktid[i].edges.remove(lyhem[2])
punktid[lyhem[2]].edges.remove(i)
try:
for n in punktid[ui].edges: #In all neighbours
try: #Remove link to old point
punktid[n].edges.remove(lyhem[0])
except KeyError:
pass #If it doesn't link to current
punktid[n].edges.add(ui) #And add new point
if log:
printf(punktid[n].edges,'naabri '+str(n)+' edges')
except KeyError: #If neighbour itself has been removed
pass #(in same merge), Ignore
punktid[ui].edges.add(lyhem[2])
punktid[lyhem[2]].edges.add(ui)
punktid.pop(lyhem[0])
ui+=1
except KeyError: # u has been removed
pass
except KeyError: # i has been removed
pass
This is a code segment and it is likely to not run after copy-pasting because of missing variables/functions. New point is being calculated on lines 22 to 43, in 3rd if-statement from beginning if sin(b)*lyhem[1]<r to punktid[ui]=... After that is redirecting old edges to new node.
Stating question clearly: How to find point on ray (AB), if two coordinates of line segment (AC) and angles at these points are known (angle ACB should be 90 degrees)? How to implement it in Python 3.5?
PS. (Meta) If somebody needs full source, how could I provide it (uploading single text file without registration)? Pastebin or pasting (spamming) it here? If I upload it to other site, how to provide link, if newbie users are limited to two?

Computing the circumference, area, and ratio of circumference to area of a circle

Studying for a CS test and basically I have to follow instructions that are similar to this.
Write a program, that is a file containing a main function followed by
a call to the main, and name the program ratio.py. The basic structure
of the program should look like this:
def main():
...
return
main() where the ellipsis indicates where you should place the code that performs following computations:
-you should prompt the user for an integer value corresponding to the
radius of a circle. Do this with code similar to:
radius = int(input("circle radius? "))
compute the circumference of the circle using the formula c = 2 πr where r is the radius and c is the circumference. Use the value of
3.14159 for π
compute the area of the circle using the formula c = πr2
print the ratio of the circumference to the area (the ratio of a to b is a divided by b)
Here is what I have written so far. I got the circumference and the area but how do I get it to make a ratio between the two and print the ratio.
def main():
radius = int(input("circle radius? "))
pi = 3.14159
r = radius
c = 2*pi*r
print(2*pi*r)
a = pi*r*r
print(pi*r*r)
ratio = c / a
return(ratio)
print("the ratio of the circumference to the area is",ratio)
main()
The ultimate goal is to get something like this:
$ python3 ratio.py
circle radius? 2
the ratio of the circumference to the area is ????
where ???? is replaced by the actual ratio.
You are extremely close to solving this. Here are a couple ideas to help you finish it:
import statements should generally go at the top of the file, not inside a function. They will work in the function, but it is poor form. This was probably not taught in class, but you get used to seeing particular patterns as you read other people's code.
As a matter of style, Python generally uses capital letters for names of constants, so PI=3.14159 is more common than pi=3.14159. This is minor and works either way. It is a good style to adhere to, since it will help make your code match others' code.
You need to calculate the area using the equation given to you: a = PI*r*r (NOTE - the original question incorrectly uses 'c' for the area. 'c' is the circumference.)
You need to return c/a, which is the ratio that was requested.
You probably need to print out the return value for testing. You can do that by storing the value returned by main() in a variable and then printing it.
Here is how to return a value from your main() function:
def main():
...
return c/a
ratio = main()
print(ratio)
# or...
print("The ratio is:", ratio)
it's odd that you do c = (2*math.pi*r) when you have pi declared as a variable above two lines. Doing math.pi goes to python's math library and digs up a more accurate version of pi. For all intents and purposes, you are just completely not using that pi variable.
see http://docs.python.org/2/library/math.html for more information.
Furthermore, you do the same computation twice.
c = 2*math.pi*r
return(2*math.pi*r)
c just ends up being garbage collected (which is to say, the computer does the computation then INTO THE TRASH IT GOES) and never being used. It would be better to simply return c
For scoping issues, which I'm sure you wouldn't really know about as a beginner, put import math above your main function, unindented.
just for future reference though, SO tends to be for isolated problems that you have spotted in code; not for a full code review. A more acceptable question would be along the lines of "my function is returning an unexpected value", not "my function is not working"

Categories