it-swarm.com.ru

Определить, находится ли точка внутри ограничительной рамки

Как бы вы определили, находится ли данная точка внутри ограничительной рамки?

Моя точка зрения 48,847172, 2,386597.

Ограничительная рамка:

    "48.7998602295",
    "48.8198640442",
    "2.46138595581",
    "2.48138619423"
11
viniciusmo

Делай как обычно:

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) - ее координаты.

25
Mario Rossi

Это решение также учитывает случай, в котором пользовательский интерфейс отправляет прямоугольник, который пересекает долготу 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
}
9
kumetix

Если вы используете листовку, вы можете создать новую 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))
5
psychicsaint

Есть довольно полезные служебные методы для 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);
2
deekay

Это должно быть быстрее.

function doesPointCollide(p,box) {
    return !(p.x < box.left || p.x > box.right || p.y > box.bottom || p.y < box.top)
}

Если точка находится вне какого-либо из измерений, мы знаем, что она не находится в ограничительной рамке, иначе она находится в ограничительной рамке, поэтому мы можем быстрее игнорировать опущенные случаи.

0
nikk wong

Используйте эту функцию для c плюс плюс, чтобы проверить, находится ли точка внутри прямоугольника

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;

}
0
Juggernogger93

Этот ответ идентичен ответу Kumetix выше ; однако, что касается меня, я не понимал, что там происходит, так как это было немного сжато. Вот тот же ответ с подробным объяснением. Также обратите внимание, что ответ на Kotlin в отличие от JavaScript, как было запрошено в оригинальном сообщении, но он достаточно читабелен, так что преобразование на ваш язык должно быть тривиальным. 

Сначала определите классы 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
}
0
Deniz