特定のポイントが境界ボックス内にあるかどうかをどのように判断しますか?
私のポイントは48.847172、2.386597です。
バウンディングボックス:
"48.7998602295",
"48.8198640442",
"2.46138595581",
"2.48138619423"
いつものようにしてください:
if( bb.ix <= p.x && p.x <= bb.ax && bb.iy <= p.y && p.y <= bb.ay ) {
// Point is in bounding box
}
bb
は境界ボックス、(ix,iy)
はその左上の座標であり、(ax,ay)
その右下の座標。 p
はポイントであり、(x,y)
その座標。
このソリューションは、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
}
リーフレットを使用している場合は、新しい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))
CGRectとCGPointには非常に便利なユーティリティメソッドがあります(座標を格納するためにCGFloatを使用していることを気にしていないと仮定し、値を確認しているので、:-)は使用しません)。
あなたはそれをそのようにすることができます:
// Create bounding box
CGRect area = CGRectMake(x, y, width, height);
// Define point
CGPoint point = CGPointMake(pX, pY);
/Check
BOOL isInside = CGRectContainsPoint(area, point);
この関数を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;
}
この答えは 上記のKumetixの答え と同じです。でも、結構凝縮していたので、一生、何が起こっているのかわからなかった。詳細な説明のある同じ回答です。また、回答はリクエストされた元の投稿のJavaScriptではなくKotlinにありますが、十分に読みやすいため、言語への変換は簡単です。
最初に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)
これはかどうかを決定する関数です
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
}
これはもっと速いはずです。
function doesPointCollide(p,box) {
return !(p.x < box.left || p.x > box.right || p.y > box.bottom || p.y < box.top)
}
ポイントが境界ボックス内にないことがわかっている寸法の外にある場合は、境界ボックス内にあるため、否定されたケースをより迅速に無視できます。