Finding the location where a photosphere was taken - math

I have a room with four corners (c1, c2, c3, c4), for each of which I have coordinates.
A user takes a photosphere - a 360-degree image - in this room. (We do not have the coordinates of the photosphere's location.) They then identify the room corners by clicking on the image. This gives us four angles (a1, a2, a3, a4).
From this data, I would like to find the most likely location where the photosphere was taken, as xy coordinates. What's the best way to do this?
(Disclaimer: I'm a halfway competent programmer but not a great mathematician, so please excuse me if I need to follow up on any particular points of understanding. Thank you!)
Edit 1: I've been trying to get #meowgoesthedog's really helpful solution working. Here it is (in Ruby, but it'd be pretty much the same in any other language) with some sample data:
c1 = [70.38017162671083, 573.9210230366474]
c2 = [62.14926043346433, 573.9210230601221]
c3 = [62.170859502652874, 566.273256963365]
c4 = [70.41870117287603, 566.2827951694268]
a1 = 0.7162475014121918
a2 = 3.076344266497204
a3 = 4.964159781307695
a4 = 5.859686474799228
a = Math.sin(a1) +Math.sin(a2)
b =-Math.cos(a1) -Math.cos(a2)
c = Math.sin(a3) +Math.sin(a4)
d =-Math.cos(a3) -Math.cos(a4)
e = Math.sin(a1)*c1[0] + Math.sin(a2)*c2[0] - Math.cos(a1)*c1[1] - Math.cos(a2)*c2[1]
f = Math.sin(a3)*c3[0] + Math.sin(a4)*c4[0] - Math.cos(a3)*c3[1] - Math.cos(a4)*c4[1]
x = (d*e - b*f) / (a*d - b*c)
y = (a*f - c*e) / (a*d - b*c)
However, the results aren't what I'd expect: in this case, x is 77.29614012577807 and y is 551.2264007863547. Both of these are outside the bounding box of the room (roughly x 62-70, y 566-574) where the camera is placed.
Calculating the angle from x,y to the corners c1 c2 c3 c4, which should result in (roughly) a1 a2 a3 a4, comes up with very different results:
puts Math.atan2(c1[1]-y, c1[0]-x)
> 1.8665964276063274
Is there anything obvious you can see that I'm doing wrong? Thank you again!

Related

Intersection point of a vector or its extension with surrounding rectangle [duplicate]

This question already has answers here:
intersection between a line and square
(2 answers)
Closed 4 months ago.
I would like to find the intersection point of a vector or its extension with the surrounding rectangle, that is, in the image (1) and (2), given (x1, y1), (x2, y2), (a1, a2), (b1, b2), we would like to obtain the point (c1, c2).
I have found the article Find collision point between vector and fencing rectangle but, since the positive y-axis is downward in python/windows, I could not manage the equations and parameters to acheive the correct result. The two following links are also related.
intersection between a line and square
Get intersection point of rectangle and line.
But they do not include the extension of the vector/line segment.
How should the equations change to obtain the correct result?
A point on the ray is given by the coordinates (a1 + t (b1 - a1), a2 + t (b2 - a2)).
The intersections are obtained by solving the four equations
a1 + t (b1 - a1) = x1
a1 + t (b1 - a1) = x2
a2 + t (b2 - a2) = y1
a2 + t (b2 - a2) = y2
for t and taking the smallest positive solution. If some of the coefficients of t is zero, just ignore the corresponding equation.
The orientations of the axis play no role.

Shortest keyboard distance typing

Can anyone help me with this problem?
We have a grid of MxN characters from some specific aplhabet, S={A,B,C,D} for example.
The cursor is positioned on (1,1) position, and we can move cursor using the arrow keys, up, down, left, right, and press enter to select the character ( just like selecting nick in old games ). What is minimum cost of operations where they are weighted same, (e.g. move right is equally costly as selecting the char) given some input string from aplhabet S? There can also be multiple occurences of the same character in the matrix.
Example:
alphabet S={A,B,C,D}
matrix :
ABDC
CADB
ABAA
and input string ADCABDA.
My incomplete solution would be:
Construct directed grid graph and find shortest path from 1,1 to end character, with inbetween characters similar to towns in TSP, and from optimal subpaths construct optimal final path using dynamic programming. Problem is that you could end with many possible end characters, and I totally have no idea how to construct longer optimal path from smaller optimal subpaths.
You should construct a graph with nodes something like this:
A1 A1 A1
A2 D1 C1 A2 B1 D1 A2
Start A3 D2 C2 A3 B2 D2 A3 End
A4 A4 B3 A4
A5 A5 A5
where there are edges connecting each node in a column to each node in the next column. Start is (1,1) and End is wherever. The edge weights are the "taxicab" distances between each pair of keys.
Now it's a fairly straightforward dynamic programming problem. You can start at either end; it's probably conceptually simpler to start at Start. Keep track of the minimum cost so far to reach each node.
You could use 3D dynamic programming, where each state is (x, y, l) - (x, y) representing current position and l representing what letter you are at.
To explain further. You start at position (0, 0, 0). First letter is "A". You can try all A's and we know that distance will be Manhattan distance (http://en.wikipedia.org/wiki/Taxicab_geometry). Solution for (0, 0, 0) would be minimum of all possibilities.
At each step repeat the above process. Note that importance of memorising each step. In the below sample code memo acts as function, you would use array in reality.
Here is sample pseudo-code:
f(x, y, l):
if memo(x, y, l) != -1:
return memo(x, y, l) # Check if already calculated.
if l == length(word):
return memo(x, y, l) = 0 # Ending condition.
memo(x, y, l) = inf
next_letter = word[l]
for each (x2, y2) in grid that contains next_letter:
distance = |x2 - x| + |y2 - y|
next_calc = f(x2, y2, l+1)
memo(x, y, l) = min(memo(x, y, l), distance + next_calc)
return memo(x, y, l)
Set all memo to -1, so we know that no states are calculated.
Solution is f(0, 0, 0).
Let me know which steps I need to clarify further.

Straight line intersection for a general form

Although there are some posts regarding intersection of two straight lines in vector & standard forms, I am interested in computing the intersection for the general equations of two straight lines to avoid the problem of vertical line.
I have a total least square fitting straight line like the following form:
a(x - x_bar) + b(y - y_bar) = 0 (which goes through the mid point (x_bar,y_bar)).
This equation can be written in the general form like Ax+By+C = 0.
My question is that if I try to find the intersection of two of these lines (say, A1x+B1y+C1=0 & A2x+B2y+C2=0), should I simply solve these equations for x & y by substitution? Also, will that cover the problem of vertical line?
You might have done this at school under simultaneous equations. Take A2 time the first and A1 times the second giving A1 A2 x B1 A2 y + C1 A2 = 0 and A2 A1 x + B2 A1 y + C2 A1 = 0. Subtract these two gives (B1 A2 - B2 A1) y + (C1 - C2) =0 you can then solve for y, once you have found that x is easy to find.

joining two Bézier curves smoothly (C2 continuous)

(Follow-up of this question.)
Given a sequence of cubic Bézier curves, how can I modify them minimally to make them join in a C2-continuous way?
Input:
curve P with control points P0, P1, P2, P3
curve Q with control points Q0, Q1, Q2, Q3
if it helps, you can assume that they are already C1 continuous.
Constraints:
C0 continuity: P3 = Q0
C1 continuity: P2 - P3 = Q0 - Q1
C2 continuity: P1 - 2*P2 + P3 = Q0 - 2*Q1 + Q2
modified curves as close as possible to original curves P and Q
Getting the modified curves as close as possible to the originals can have multiple interpretations, but one could consider that keeping endpoints and tangents far from the joining points constant could fit. So the points P0, P1, P3 = Q0, Q2, Q3 are constant.
We can change the origin such that P3 = Q0 = 0, enforcing C2 continuity can then be expressed as:
P1 - 2*P2 = 2*Q1 + Q2
One can expressP2=a*e^i*r and Q1=b*e^i*r in complex representations (keeping the same angle enforces C2 continuity. Compute
(P1 - Q2)/2 = c*e^i*s
Enforcing C2 continuity should be choosing r=s, and finding a combination of a and b such that a+b =c. There are infinitely many solutions, but one might use heuristics such as changing a if it is the smallest (thus producing less sensible changes).
If that's not producing sufficiently small variations, try a two-step optimisation: first change P1 and Q2 to get s closer to r, then apply the steps above.

Determine whether two sectors of a given circle intersect?

Anybody know how to determine whether two sectors of the same circle intersect?
Let's say I have a sector A, expressed by starting and ending angles A1 and A2, and a sector B, expressed by starting angle B1 and ending angle B2. All angles ranges from 0..2*PI radians (or 0..360 degrees).
How to determine whether angle A intersects with angle B?
I've tried a variation of the two rectangle intersection problem like the following:
if(a1 <= b2 && a2 >= b1) {
// the sectors intersect
} else {
// the sectores doesn't intersect
}
This method is fine as long as no sectors crosses the 0 degrees point. But if any one sector crosses it, the calculation becomes incorrect.
The underlying problem is in creating a directional (heading-based) augmented reality application. Sector A is the object whereas Sector B is the viewport. The angles are obtained as follow:
A0 = bearing of the object
A1 = A0 - objectWidthInRadians
A2 = A0 + objectWidthInRadians
B0 = heading of the user (device)
B1 = B0 - viewportWidthInRadians
B2 = B0 + viewportWidthInRadians
Thanks in advance.
What you really care about is whether the shortest difference in bearings is smaller than the collision range:
// absolute difference in bearings gives the path staying within the 0..2*pi range
float oneWay = abs(A0 - B0);
// .. but this may not be the shortest, so try the other way around too
float otherWay = 2 * pi - oneWay;
if ( min(oneWay, otherWay) < (objectWidthInRadians + viewPortWidthInRadians) )
{
// object is visible...
}
Note that your width definition is a bit odd (seems to be really the half-angle), and the calculations shown for A1 etc do not actually clip into the stated [0..2*pi] range...

Resources