-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Does squaredDistance
really need to be squared?
#29
Comments
@chriseidhof I realized my earlier answer was me realizing things as I wrote them so I wrote down a better answer, as you aren't the first person to ask this:
The If the question is "How to use KDTree for CLLocation?"The answer is it depends : App about local points of interestE.g. an app that displays running paths on a local map of Brandenburg Example implementation could look like this
I just remembered I had to do the same for the spherical starmap here. Also, when asking for the nearest neighbor we have to be careful when showing points around the international date line or This way we're basically searching for the nearest point on the rolled out cylinder. This should be fine on a phone, as the screen is also flat, i.e. map data will be 2D-projected. App showing global points of interestIf your app is more like Google Earth, say you have a 3D globe where there are little To the literal question you asked: "Does squaredDistance really need to be squared?"The numerical-analysis mathematician in me automatically went with squaredDistance instead of euclidian distance (generally sqrt is a really slow operation compared to +,* of course).
Because of the hyperplane-intersection thing, it is important whether the distance is defined with More on manifolds https://en.wikipedia.org/wiki/Manifold .
|
Now, I actually thought about adding Do you have a good idea how I could bundle both of those solutions in the framework and leave the choice to the person importing? (I mean, I can't conform to the same protocol in two different ways). |
Interesting. Instead of a protocol, you could have the points in a protocol, but at initialization, pass in a distance function. You could then have two distance functions (one for A and one for B). |
Hm, my idea doesn't really work, because KDTree is an enum... and it wouldn't be good API design to have to pass in the function with the method. So we'd have to put the tree in a box (which might in itself be a good idea, as it might allow us to do copy-on-write). Another possibility is to use a wrapper struct, e.g.: struct LocalLocation: KDTreePoint {
let location: CLLocation
}
struct GlobalLocation: KDTreePoint {
let location: CLLocation
} |
In case anyone ever comes across this issue, I found that the "simplest" way of calculating the location wasn't really working for me, so I switched to this one: extension CLLocationCoordinate2D {
func squaredDistanceApproximation(to other: CLLocationCoordinate2D) -> Double {
let latMid = (latitude + other.latitude) / 2
let m_per_deg_lat: Double = 111132.954 - 559.822 * cos(2 * latMid) + 1.175 * cos(4.0 * latMid)
let m_per_deg_lon: Double = (Double.pi/180) * 6367449 * cos(latMid)
let deltaLat = fabs(latitude - other.latitude)
let deltaLon = fabs(longitude - other.longitude)
return pow(deltaLat * m_per_deg_lat,2) + pow(deltaLon * m_per_deg_lon, 2)
}
} I found it on StackOverflow. |
thank you @chriseidhof , next chance I get for this I'll write a proper example app for KDTree usage together with a MapKit view and add a CLLocation support to |
There’s no rush from my side :)
|
Another interesting thing: For my application, I was able to use MKMapPoint, as it's a 2D projection of CLLocationCoordinate2D . As my data set is very local and doesn't span any lat/lon boundaries, I can simply return the MKMapPoint.x and .y as the x and y for the k-d tree. |
Dunno if anyone is still interested in this topic, but anyway this piqued my curiosity. I am thinking the question is, what are the algebraic properties that must be satisfied by the space from which the data points are taken -- must it be a manifold, and if so what kind; are there implicit assumptions built into the code the way it is written now? what is the range of spaces which can be handled by the current implementation, and if it doesn't include some spaces of interest, what would it take to expand it? Anyway those are the kinds of questions that came to mind as I was reading this discussion. I found this article which seems to address some of the same topics: http://users.umiacs.umd.edu/~rama/Publications/Turaga_ICVGIP_2010.pdf |
From my current understanding of the code (I've not looked at it in detail) squaredDistance could also just be
distance
, right? And as a comment, we might say that it could also be squaredDistance?The reason I'm asking is because my KDTreePoint will be a CLLocation, which provides
distance(from:)
, but nothing similar to squared distance.The text was updated successfully, but these errors were encountered: