ios 确定点是否在边界框内
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18295825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Determine if point is within bounding box
提问by viniciusmo
How would you determine if a given point is within the bounding box?
您如何确定给定点是否在边界框内?
My point is 48.847172 , 2.386597.
我的观点是 48.847172 , 2.386597。
Boundingbox:
边界框:
"48.7998602295",
"48.8198640442",
"2.46138595581",
"2.48138619423"
回答by Mario Rossi
Do just as usual:
照常做:
if( bb.ix <= p.x && p.x <= bb.ax && bb.iy <= p.y && p.y <= bb.ay ) {
// Point is in bounding box
}
bb
is the bounding box, (ix,iy)
are its top-left coordinates, and (ax,ay)
its bottom-right coordinates. p
is the point and (x,y)
its coordinates.
bb
是边界框,(ix,iy)
是它的左上角坐标和(ax,ay)
右下角坐标。 p
是点(x,y)
及其坐标。
回答by kumetix
This solution also takes in consideration a case in which the UI sends a box which crosses longitude 180/-180 (maps views on low zoom level where you can see the whole world, allow infinite cyclic horizontal scrolling, so it is possible for example that a box's bottomLeft.lng=170 while topRight.lng=-170(=190) and by that including a range of 20 degrees.
此解决方案还考虑了 UI 发送一个跨越 180/-180 经度的框的情况(以低缩放级别映射视图,您可以看到整个世界,允许无限循环水平滚动,因此可能例如一个盒子的 bottomLeft.lng=170 而 topRight.lng=-170(=190) 并且包括 20 度的范围。
def inBoundingBox(bl/*bottom left*/: Coordinates, tr/*top right*/: Coordinates, p: Coordinates): Boolean = {
// in case longitude 180 is inside the box
val isLongInRange =
if (tr.long < bl.long) {
p.long >= bl.long || p.long <= tr.long
} else
p.long >= bl.long && p.long <= tr.long
p.lat >= bl.lat && p.lat <= tr.lat && isLongInRange
}
回答by psychicsaint
If you are using leaflet, you can create a new LatLngBounds
and use its contains()
operation:
如果您使用的是传单,则可以创建一个新的LatLngBounds
并使用其contains()
操作:
var bounds = new L.LatLngBounds(
new L.LatLng(gc.bbox['_northEast'].lat, gc.bbox['_northEast'].lng),
new L.LatLng(gc.bbox['_southWest'].lat, gc.bbox['_southWest'].lng));
return bounds.contains(new L.LatLng(pos.latitude, pos.longitude))
回答by deekay
There are quite nice utility methods for CGRect and CGPoint (assuming you don't mind fact that they are using CGFloat for storing coordinates - and looking at your values, you don't :-) ).
CGRect 和 CGPoint 有非常好的实用方法(假设您不介意他们使用 CGFloat 来存储坐标的事实 - 并且查看您的值,您不会:-))。
You can do it like that:
你可以这样做:
// Create bounding box
CGRect area = CGRectMake(x, y, width, height);
// Define point
CGPoint point = CGPointMake(pX, pY);
/Check
BOOL isInside = CGRectContainsPoint(area, point);
回答by Juggernogger93
Use this function for c plus plus to check if a point exits inside a rectangle
将此函数用于 c plus plus 以检查点是否存在于矩形内
struct Box{
Vec2 corner1;
Vec2 corner2;
Vec2 corner3;
Vec2 corner4;
};
bool boxContainsPoint(Vec2 point, Box box){
//Calculate distances from corner to corner
float abL = box.corner1.getDistance(box.corner2);////////////////////
float bcL = box.corner2.getDistance(box.corner3);////////////////////
float cdL = box.corner3.getDistance(box.corner4);////////////////////
float daL = box.corner4.getDistance(box.corner1);////////////////////
//Calculate corner touch distance//////////////////////////////////
float apL = box.corner1.getDistance(point);/////////////////////////
float bpL = box.corner2.getDistance(point);/////////////////////////
float cpL = box.corner3.getDistance(point);/////////////////////////
float dpL = box.corner4.getDistance(point);/////////////////////////
//Here we calculate the touch area
//Heron's Formula
///////////////////////////////////////////////////////////////////
float area1 = (abL + apL + bpL) / 2;///////////////////////////////
float area2 = (bcL + bpL + cpL) / 2;///////////////////////////////
float area3 = (cdL + cpL + dpL) / 2;///////////////////////////////
float area4 = (daL + dpL + apL) / 2;///////////////////////////////
float a1 = sqrtf(area1 * (area1 - abL)*(area1 - apL)*(area1 - bpL));
float a2 = sqrtf(area2 * (area2 - bcL)*(area2 - bpL)*(area2 - cpL));
float a3 = sqrtf(area3 * (area3 - cdL)*(area3 - cpL)*(area3 - dpL));
float a4 = sqrtf(area4 * (area4 - daL)*(area4 - dpL)*(area4 - apL));
//Calculate the rectangle area
float A = roundf(abL*bcL);
//Check to see if the point contains the polygon rect
if(A ==roundf(a1 + a2 + a3 + a4)) return true;
return false;
}
回答by deniz
This answer is identical to kumetix's answer above; however, for the life of me, I didn't understand what was happening in there since it was condensed quite a bit. Here is the same answer with detailed explanation. Also please note that the answer is in Kotlin as opposed to JavaScript as the original post requested but it is sufficiently readable so that converting to your language should be trivial.
这个答案与上面 kumetix 的答案相同;然而,对于我的生活,我不明白那里发生了什么,因为它被浓缩了很多。这是相同的答案,并带有详细说明。另请注意,答案是在 Kotlin 中而不是在原始帖子请求的 JavaScript 中,但它具有足够的可读性,因此转换为您的语言应该是微不足道的。
First define Coordinate and BoundingBox classes:
首先定义 Coordinate 和 BoundingBox 类:
data class Coordinate2D (val latitude: Double, val longitude: Double)
data class BoundingBox (val north: Double, val east: Double, val south: Double, val west: Double)
Here is the function that determines whether
这是确定是否的函数
fun isPointInBoundingBox(point: Coordinate2D, boundingBox: BoundingBox): Boolean {
//initially assume the point is not in our bounding box of interest
var isPointEastOfWestLine = false
var isPointWestOfEastLine = false
var isPointSouthOfNorthLine = false
var isPointNorthOfSouthLine = false
if (boundingBox.east < boundingBox.west) {
//east longitude will always have a higher value if the bounding box is not
//crossing the dateline, i.e. longitude 180 is inside the box
//so we are crossing the dateline, let's see what's happening with the point
if (point.longitude >= boundingBox.west) {
//imagine a bounding box where westernmost longitude is +170 and easternmost longitude is -170
//if the point in question has a latitude of +171 as in the case expressed in the if
//statement, then we can conclude that point lies east of the west line
isPointEastOfWestLine = true
//we can also infer that the point must lie west of east line because the point's longitude is positive
//therefore, the point's position must be to the west of the easternmost longitude of the bounding box
isPointWestOfEastLine = true
}
if (point.longitude <= boundingBox.east) {
//imagine a bounding box where westernmost longitude is +170 and easternmost longitude is -170
//if the point in question has a latitude of -171 as in the case expressed in the if
//statement, then we can conclude that point lies west of the east line
isPointWestOfEastLine = true
//we can also infer that the point must lie east of the west line because the point's longitude is negative
//therefore, the point's position must be to the east of the westernmost longitude of the bounding box
isPointEastOfWestLine = true
}
} else {
//in the else case, bounding box does not cross the dateline, so comparisons are more straightforward
//longitudes range from -180 to +180; therefore, western side of a bounding box will always
//have lower value than eastern side
if (point.longitude >= boundingBox.west) {
//in this case, point's longitude has a higher value than the west side of the bounding box
//we can conclude that point lies to the east of the west line of the bounding box
isPointEastOfWestLine = true
}
if (point.longitude <= boundingBox.east) {
//in this case, point's longitude has a lower value than the east side of the bounding box
//we can conclude that point lies to the east of the west line of the bounding box
isPointWestOfEastLine = true
}
}
//comparing latitudes are little bit easier. latitude values range from -90 to +90 where
//-90 is the southern pole and +90 is the northern pole. The more north you go, higher the values.
if (point.latitude >= boundingBox.south) {
//point's latitude is higher, therefore, point must lie to the north of the south line
isPointNorthOfSouthLine = true
}
if (point.latitude <= boundingBox.north) {
//point's latitude is higher, therefore, point must lie to the north of the south line
isPointSouthOfNorthLine = true
}
return isPointEastOfWestLine &&
isPointWestOfEastLine &&
isPointNorthOfSouthLine &&
isPointSouthOfNorthLine
}
回答by nikk wong
This should be faster.
这应该更快。
function doesPointCollide(p,box) {
return !(p.x < box.left || p.x > box.right || p.y > box.bottom || p.y < box.top)
}
If the point is outside any of the dimensions we know that it's not in the bounding box, else it is in the bounding box, so we can ignore negated cases more quickly.
如果点在任何维度之外,我们知道它不在边界框中,否则它在边界框中,因此我们可以更快地忽略否定情况。