Sorting and comparing arrays in Go - sorting

I am a beginner Go student and I've been given the following assignment that needs to be built in Go:
-Read in a data file that contains all 83 counties of Michigan and the coordinates (in decimal) for each county seat.
-Set beginning coordinates to the college I attend.
-Prompt user for a direction (n,s,e,w) and the program then finds the closest county seat in that specified direction. The found county seat then becomes the new starting point and the program starts over with the direction prompt.
-the program needs to show an error if the user hits water or is about to leave the state.
I am able to do most of this without issue, but here is where I'm hitting a brick wall:
My plan is to use two arrays; one for latitude and one for longitude. I need to sort each array so that the numbers are in order from the eastern most county seat to the western most county seat (for latitude and the same for longtitude). My thinking is that if the user enters that they want to go west, the program will take the latitude coordinate of the starting point, determine where in the array it is supposed to be positioned then the program selects the closest coordinate in the numbers to the right of starting coordinate. The program should then take the determined coordinate and reference the main map of coordinates, find the matching complete set of coordinates then set the starting point to the new coordinates. I'm using float64s for the coordinate data types.
So to break it down: the data file reads in the coordinates of {1, 1.2} {2,1.3} {3, 2.4} {4, 5.4} {5, 6.6}; the starting point is (1,2) and the user wants to go west. So the latitude array holds {1.2, 1.3, 2.4, 5.4, 6.6} and the program needs to take the 2 from the starting, determine that it belongs between the 1.3 and 2.4, the determine that the 2.4 is the closest coordinate to the starting point. Then it takes the 2.4 and compares it to the data file coordinates to match the {3, 2.4}. The starting point is now {3, 2.4}. Then the program starts over from the user choosing a direction.
I apologize for the novel but I wanted to make sure I was as clear (as mud, I know LOL) as possible. How do I code the sort and comparisons? If there is an easier way to complete this assignment, I would be incredibly grateful for any help. Please keep in mind, I've only been working with Go for about a month and a half. Please be gentle with complicated code. LOL Thank you!

From a design perspective, consider creating a type that encapsulates the information about each county seat (e.g. a struct with the city/town name, latitude, and longitude) since they are logically related.
The code example below shows how you could sort these objects by latitude or longitude using sort.Slice(...), making it easier to find which one is closest in the specified direction.
Hope it helps!
package main
import "sort"
type CountySeat struct {
Name string
Lat, Lng float64
}
func main() {
// Pretend we've read these from the data file.
countySeats := []CountySeat{
CountySeat{"Alpha", 3.0, 1.0},
CountySeat{"Bravo", 2.0, 2.0},
CountySeat{"Charlie", 1.0, 3.0},
}
// Sorting by latitude makes it easy to find N/S proximity.
sort.Slice(countySeats, func(i, j int) bool {
return countySeats[i].Lat < countySeats[j].Lat;
})
// Now countySeats are ordered by increasing latitude...
// Sorting by longitude makes it easy to find E/W proximity.
sort.Slice(countySeats, func(i, j int) bool {
return countySeats[i].Lng < countySeats[j].Lng;
})
// Now countySeats are ordered by increasing longitude...
}

Related

How can you iterate linearly through a 3D grid?

Assume we have a 3D grid that spans some 3D space. This grid is made out of cubes, the cubes need not have integer length, they can have any possible floating point length.
Our goal is, given a point and a direction, to check linearly each cube in our path once and exactly once.
So if this was just a regular 3D array and the direction is say in the X direction, starting at position (1,2,0) the algorithm would be:
for(i in number of cubes)
{
grid[1+i][2][0]
}
But of course the origin and the direction are arbitrary and floating point numbers, so it's not as easy as iterating through only one dimension of a 3D array. And the fact the side lengths of the cubes are also arbitrary floats makes it slightly harder as well.
Assume that your cube side lengths are s = (sx, sy, sz), your ray direction is d = (dx, dy, dz), and your starting point is p = (px, py, pz). Then, the ray that you want to traverse is r(t) = p + t * d, where t is an arbitrary positive number.
Let's focus on a single dimension. If you are currently at the lower boundary of a cube, then the step length dt that you need to make on your ray in order to get to the upper boundary of the cube is: dt = s / d. And we can calculate this step length for each of the three dimensions, i.e. dt is also a 3D vector.
Now, the idea is as follows: Find the cell where the ray's starting point lies in and find the parameter values t where the first intersection with the grid occurs per dimension. Then, you can incrementally find the parameter values where you switch from one cube to the next for each dimension. Sort the changes by the respective t value and just iterate.
Some more details:
cell = floor(p - gridLowerBound) / s <-- the / is component-wise division
I will only cover the case where the direction is positive. There are some minor changes if you go in the negative direction but I am sure that you can do these.
Find the first intersections per dimension (nextIntersection is a 3D vector):
nextIntersection = ((cell + (1, 1, 1)) * s - p) / d
And calculate the step length:
dt = s / d
Now, just iterate:
if(nextIntersection.x < nextIntersection.y && nextIntersection.x < nextIntersection.z)
cell.x++
nextIntersection.x += dt.x
else if(nextIntersection.y < nextIntersection.z)
cell.y++
nextIntersection.y += dt.y
else
cell.z++
nextIntersection.z += dt.z
end if
if cell is outside of grid
terminate
I have omitted the case where two or three cells are changed at the same time. The above code will only change one at a time. If you need this, feel free to adapt the code accordingly.
Well if you are working with floats, you can make the equation for the line in direction specifiedd. Which is parameterized by t. Because in between any two floats there is a finite number of points, you can simply check each of these points which cube they are in easily cause you have point (x,y,z) whose components should be in, a respective interval defining a cube.
The issue gets a little bit harder if you consider intervals that are, dense.
The key here is even with floats this is a discrete problem of searching. The fact that the equation of a line between any two points is a discrete set of points means you merely need to check them all to the cube intervals. What's better is there is a symmetry (a line) allowing you to enumerate each point easily with arithmetic expression, one after another for checking.
Also perhaps consider integer case first as it is same but slightly simpler in determining the discrete points as it is a line in Z_2^8?

Third person view camera with marmalade SDK

Help me please to get camera following target point. I can't do it for 2 days already for the new prototype project in my company. Currently i have:
void Camera::followTargetPoint(CIwVec3 target, int32 distance, int32 height)
{
CIwVec3 viewSpaceLocation = (CIwVec3)IwGxGetModelViewMatrix().TransformVec(target);
IwTrace(SCOOTER, ("viewSpaceLocation: x: %d, y: %d, z: %d", viewSpaceLocation.x, viewSpaceLocation.y, viewSpaceLocation.z));
// set the viewspace origin to the camera location in viewspace
//IwGxSetViewSpaceOrg(&viewSpaceLocation);
CIwVec3 pos = CIwVec3(viewSpaceLocation.x, viewMatrix.t.y, viewSpaceLocation.z);
viewMatrix.SetTrans(pos);
//viewMatrix.LookAt(CIwVec3(0,0,-100), target, CIwVec3(0,-100,0));
IwGxSetViewMatrix(&viewMatrix);
}
this method called in my renderer like:
p->Render();
cam->followTargetPoint(p->getModelMatrix().GetTrans(), 3, 100);
What i need is a third person view camera that is located at a distance and height specified by followTargetPoint method. I can only get a first person view with this code cuz when i trying to subtract a distance from z coordinate of target vector i get a flickering model and i know the reason but the question i how to get rid of it?
You need to know which direction your point is travelling in, in order to be able to follow it. Unless you can make assumptions about this, e.g. is it a top-down 2d game?
Anyway, given a direction, your camera position in world space would be something like:
CIwVec3 camPos = ( target - ( targetDirection * distance ) );
camPos.z += height; // assuming Z is up
You then need to build a matrix using this position, but you'll also need 3 axes. The forward axis is:
( target - camPos ).Normalized();
Then you can use some cross products assuming a rough up vector of 0,0,1, to construct the other 2 axes. You should be able to figure out/google for how to build that matrix given a point and a forward vector. I can't just spoon-feed you the whole thing ;)
Then you can set the inverse of your newly constructed matrix as your new view matrix:
viewMatrix = viewMatrix.Inverse();
IwGxSetViewMatrix(&viewMatrix);
Sorry I'm not familar with the IwGx API so I probably typed some function names incorrectly.

Algorithm to calculate the distances between many geo points

I have a matrix having around 1000 geospatial points(Longitude, Latitude) and i am trying to find the points that are in 1KM range.
NOTE: "The points are dynamic, Imagine 1000 vehicles are moving, so i have to re-calculate all distances every few seconds"
I did some searches and read about Graph algorithms like (Floyd–Warshall) to solve this, and I ended up with many keywords, and i am kinda lost now. I am considering the performance and since the search radius is short, I will not consider the curvature of the earth.
Basically, It appears that i have to calculate the distance between every point to every other point then sort the distances starting from every point in the matrix and get the points that are in its range. So if I have 1000 co-ordinates, I have to perfom this process (1000^2-1000) times and I do not beleive this is the optimum solution. Thank You.
If you make a modell with a grid of 1km spacing:
0 1 2 3
___|____|____|____
0 | | |
c| b|a | d
___|____|____|____
1 | | |
| |f |
___|e___|____|____
2 | |g |
let's assume your starting point is a.
If your grid is of 1km size, points in 1km reach have to be in the same cell or one of the 8 neighbours (Points b, d, e, f).
Every other cell can be ignored (c,g).
While d is nearly of the same distance to a as c, c can be dropped early, because there are 2 barriers to cross, while a and d lie on opposite areas of their border, and are therefore nearly 2 km away from each other.
For early dropping of element, you can exclude, it is enough to check the x- or y-part of the coordinate. Since a belongs to (0,2), if x is 0 or smaller, or > 3, the point is already out of range.
After filtering only few candidates, you may use exhaustive search.
In your case, you should be looking at the GeoHash which allows you to quickly query the coordinates within a given distance.
FYI, MongoDB uses geohash internally and it's performing excellently.
Try with an R-Tree. The R-Tree supports the operation to find all the points closest to a given point that are not further away than a given radius. The execution time is optimal and I think it's O(number_of_points_in_the_result).
You could compute geocodes of 1km range around each of those 1000 coordinates and check, whether some points are in that range. May be it's not optimum, but you will save yourself some sorting.
If you want to lookup the matrix for each point vs. each point then you already got the right formula (1000^2-1000). There isn't any shortcut for this calculation. However when you know where to start the search and you want look for points within a 1KM radius you can use a grid or spatial algorithm to speed up the lookup. Most likely it's uses a divide and conquer algorithm and the cheapest of it is a geohash or a z curve. You can also try a kd-tree. Maybe this is even simpler. But if your points are in euklidian space then there is this planar method describe here: http://en.wikipedia.org/wiki/Closest_pair_of_points_problem.
Edit: When I say 1000^2-1000 then I mean the size of the grid but it's actually 1000^(1000 − 1) / 2 pairs of points so a lot less math.
I have something sort of similar on a web page I worked on, I think. The user clicks a location on the map and enters a radius, and a function returns all the locations within a database within the given radius. Do you mean you are trying to find the points that are within 1km of one of the points in the radius? Or are you trying to find the points that are within 1km of each other? I think you should do something like this.
radius = given radius
x1 = latitude of given point;
y1 = longitude of given point;
x2 = null;
y2 = null;
x = null;
y = null;
dist = null;
for ( i=0; i<locationArray.length; i++ ) {
x2 = locationArray[i].latitude;
y2 = locationArray[i].longitude;
x = x1 - x2;
y = y1 - y2;
dist = sqrt(x^2 + y^2);
if (dist <= radius)
these are your points
}
If you are trying to calculate all of the points that are within 1km of another point, you could add an outer loop giving the information of x1 and y1, which would then make the inner loop test the distance between the given point and every other point giving every point in your matrix as input. The calculations shouldn't take too long, since it is so basic.
I had the same problem but in a web service development
In my case to avoid the calculation time problem i used a simple divide & conquer solution : The idea was start the calculation of the distance between the new point and the others in every new data insertion, so that my application access directly the distance between those tow points that had been already calculated and put in my database

Sort a set of 3-D points in clockwise/counter-clockwise order

In 3-D space I have an unordered set of, say, 6 points; something like this:
(A)*
(C)*
(E)*
(F)*
(B)*
(D)*
The points form a 3-D contour but they are unordered. For unordered I mean that they are stored in an
unorderedList = [A - B - C - D - E - F]
I just want to reorganize this list starting from an arbitrary location (let's say point A) and traversing the points clockwise or counter-clockwise. Something like this:
orderedList = [A - E - B - D - F - C]
or
orderedList = [A - C - F - D - B - E]
I'm trying to implement an algorithm as simple as possible, since the set of points in mention corresponds to a N-ring neighborhood of each vertex on a mesh of ~420000 points, and I have to do this for each point on the mesh.
Some time ago there was a similar discussion regarding points in 2-D, but for now it's not clear for me how to go from this approach to my 3-D scenario.
The notion of "clockwise" or "counterclockwise" is not well-defined without an axis and orientation! (proof: What if you looked at those points from the other side of your monitor screen, or flipped them, for example!)
You must define an axis and orientation, and specify it as an additional input. Ways to specify it include:
a line (1x=2y=3z), using the right-hand rule
a (unit) vector (A_x, A_y, A_z), using the right-hand rule; this is the preferred way to do so
In order to determine the orientation, you have to look deeper at your problem: You must define a "up" and "down" size of the mesh. Then for each set of points, you must take the centroid (or another "inside" point) and construct a unit vector pointing "up" which is normal to the surface. (One way to do this would be to find the least-squares-fit plane, then find the two perpendicular vectors through that point, picking the one in the "up" direction.)
You will need to use any of the above suggestions to determine your axis. This will allow you to reformulate your problem as follows:
Inputs:
the set of points {P_i}
an axis, which we shall call "the z-axis" and treat as a unit vector centered on the centroid (or somewhere "inside") of the points
an orientation (e.g. counterclockwise) chosen by one of the above methods
Setup:
For all points, pick two mutually-orthogonal unit vectors to the axis, which we shall call "the y-axis" and "the x-axis". (Just rotate the z-axis unit-vector 90 degrees in two directions, http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations )
Algorithm:
For each point P, project P onto the x-axis and y-axis (using the dot product), then use http://en.wikipedia.org/wiki/Atan2
Once you have the angles, you can just sort them.
I can't attest for the efficiency of this code, but it works, and you can optimize parts of it as needed, I'm just not good at it.
Code is in C#, using system collection classes, and linq.
Vector3 is a class with floats x, y, z, and static vector math functions.
Node is a class with Vector3 variable called pos
//Sort nodes with positions in 3d space.
//Assuming the points form a convex shape.
//Assuming points are on a single plain (or close to it).
public List<Node> sortVerticies( Vector3 normal, List<Node> nodes ) {
Vector3 first = nodes[0].pos;
//Sort by distance from random point to get 2 adjacent points.
List<Node> temp = nodes.OrderBy(n => Vector3.Distance(n.pos, first ) ).ToList();
//Create a vector from the 2 adjacent points,
//this will be used to sort all points, except the first, by the angle to this vector.
//Since the shape is convex, angle will not exceed 180 degrees, resulting in a proper sort.
Vector3 refrenceVec = (temp[1].pos - first);
//Sort by angle to reference, but we are still missing the first one.
List<Node> results = temp.Skip(1).OrderBy(n => Vector3.Angle(refrenceVec,n.pos - first)).ToList();
//insert the first one, at index 0.
results.Insert(0,nodes[0]);
//Now that it is sorted, we check if we got the direction right, if we didn't we reverse the list.
//We compare the given normal and the cross product of the first 3 point.
//If the magnitude of the sum of the normal and cross product is less than Sqrt(2) then then there is more than 90 between them.
if ( (Vector3.Cross( results[1].pos-results[0].pos, results[2].pos - results[0].pos ).normalized + normal.normalized).magnitude < 1.414f ) {
results.Reverse();
}
return results;
}

Geographic grid search algorithm

Many of the location based services provide APIs for finding places/venues/spots around a given latitude longitude pair. I'm looking into how I can search for these places across an entire city.
I can build a grid for a city by getting its bounds from the Google Maps Geocoder and then incrementing the lat/longs to lay down points to form the grid. I've prototyped this grid (click the Fill Grid button to see all of the points) to visualize this idea.
// gather a collection of lat/long pairs that represents a grid of the city
var latIncrement = .04;
var lngIncrement = .04;
var newLat = nw.lat();
while(newLat >= sw.lat()) {
var newLng = nw.lng();
while(newLng <= ne.lng()) {
// western and northern border as well as grid infill
addMarker(new google.maps.LatLng(newLat, newLng));
newLng += lngIncrement;
}
// eastern border
addMarker(new google.maps.LatLng(newLat, ne.lng()));
newLat -= latIncrement;
}
// southern border
var newLng = sw.lng();
while(newLng <= se.lng()) {
addMarker(new google.maps.LatLng(sw.lat(), newLng));
newLng += lngIncrement;
}
addMarker(se);
I can then take all of these points and run searches for them against the LBS APIs.
My question is, are there more scientific ways/algorithms to establish this grid? I'd like to learn more about them. I'm just arbitrarily incrementing the lat/lngs until I reach the border of the grid. The density of places is going to vary wildly by city and area of a city, so sometimes the increment will be too small, and sometimes too large. I'm looking for ideas about how to tune this a little better?
A perhaps more efficient/clean way would be to find the bounding rectangle of the city, which is the rectangle with each edge being the extreme cardinal points between the city border points, if you can find them, and then filling them in iteratively. But that is basically what you are already doing, anyway.
As for place density, do you have a specific API that you are going to be using this with? If you know the "reach" of the your API's points when detecting places, you ever only have to have grid points as close as their radius.
That being said, have you looked into seeing perhaps if the API directly supports searching for places within a border? That might be your best and cleanest bet.
After reading your comment, here is a possibly inefficient way that I'm going to think over and refine in the future, but it might help you get started.
Place a point in the center of your city, and observe all locations detected. Find the convex hull of your locations, and place a new point on each location on the convex hull. Then, add to your list of locations all locations that fall within reach of these newly added points.
Then, find the convex hull of those, and repeat the same process.
This might actually reduce your amount of points for sparsely populated cities. For dense ones, it might be less than optimal, but it might get you started on a working track.
While I was facing same problem. I came up with a solution, where you will go do grid search in a top down recursive way. This will work if that API supports bounding box search. Initially assume your city as a square. Now fetch data/places using API in that square (bounding box query). Now if number of returned places are more than some threshold, than split the city square into 4 equal squares and repeat the process for each square. Don't split if number of returned places are less. This will prevent grid searching into non business areas (squares) like forests,rivers etc. Here is the prototype python code for that:
Here fetch is function which fetch results from API based on bounding box with sw as southwest latitude,logitude tuple and ne as northeast latitude,logitude tuple
allresults = []
def grid_search(sw,ne):
global results
results = fetch(sw,ne)
if len(results) <= 10:
return
allresults.append(results)
swlat,swlon = sw
nelat,nelon = ne
grid_search( (swlat + delta, swlon), (nelat, sw + delta) )
grid_search( (swlat + delta, swlon + delta), ne )
grid_search( sw, (swlat + delta, swlon + delta) )
grid_search( (swlat,swlon + delta), (swlat + delta, nelon) )

Resources