Sprawdzanie, czy punkt leży wewnątrz prostokąta, czy nie

84

Chcę sprawdzić, czy punkt znajduje się wewnątrz prostokąta, czy nie. Prostokąt może być zorientowany w dowolny sposób i nie musi być wyrównany do osi.

Jedną z metod, o których mogłem wymyślić, było obrócenie prostokąta i współrzędnych punktu w celu wyrównania osi prostokąta, a następnie po prostu przetestowanie współrzędnych punktu, czy leżą one w granicach prostokąta, czy nie.

Powyższa metoda wymaga rotacji, a więc operacji zmiennoprzecinkowych. Czy istnieje inny skuteczny sposób na zrobienie tego?

avd
źródło
Możesz szybko sprawdzić, czy punkt znajduje się w prostopadłej ramce ograniczającej obróconego prostokąta, a jeśli nie, to szybko się nie powiedzie. (Tak, to tylko połowa odpowiedzi (hmmm, są trzy prostopadłe prostokąty, które mogą być utworzone przez punkty narożne ... i jest już późno (geometria koncepcyjna jest pierwsza)).
msw
Ale najpierw muszę się obrócić, prawda?
śr
1
Dopóki nie powiesz nam, jak zdefiniowany jest twój prostokąt, odpowiedzi nie będą miały praktycznej wartości. Podczas pracy ze współrzędnymi całkowitymi metoda używana do reprezentowania kształtu ma kluczowe znaczenie przy wyborze algorytmu.
AnT

Odpowiedzi:

81

Jak jest reprezentowany prostokąt? Trzy punkty? Cztery punkty? Punkt, boki i kąt? Dwa punkty i bok? Coś innego? Nie wiedząc o tym, wszelkie próby odpowiedzi na twoje pytanie będą miały wyłącznie czysto akademicką wartość.

W każdym razie dla dowolnego wypukłego wielokąta (w tym prostokąta) test jest bardzo prosty: sprawdź każdą krawędź wielokąta, zakładając, że każda krawędź jest zorientowana w kierunku przeciwnym do ruchu wskazówek zegara i sprawdź, czy punkt leży po lewej stronie krawędzi (po lewej półpłaszczyzna ręczna). Jeśli wszystkie krawędzie przejdą test - punkt jest wewnątrz. Jeśli przynajmniej jeden zawodzi - punkt jest na zewnątrz.

Aby sprawdzić, czy punkt (xp, yp)leży po lewej stronie krawędzi (x1, y1) - (x2, y2), wystarczy obliczyć

D = (x2 - x1) * (yp - y1) - (xp - x1) * (y2 - y1)

Jeśli D > 0punkt znajduje się po lewej stronie. Jeśli D < 0punkt znajduje się po prawej stronie. Jeśli D = 0punkt jest na linii.


Poprzednia wersja tej odpowiedzi opisywała pozornie inną wersję testu lewej strony (patrz poniżej). Ale można łatwo wykazać, że oblicza tę samą wartość.

... Aby sprawdzić, czy punkt (xp, yp)leży po lewej stronie krawędzi (x1, y1) - (x2, y2), musisz zbudować równanie prostej dla prostej zawierającej krawędź. Równanie jest następujące

A * x + B * y + C = 0

gdzie

A = -(y2 - y1)
B = x2 - x1
C = -(A * x1 + B * y1)

Teraz wszystko, co musisz zrobić, to obliczyć

D = A * xp + B * yp + C

Jeśli D > 0punkt znajduje się po lewej stronie. Jeśli D < 0punkt znajduje się po prawej stronie. Jeśli D = 0punkt jest na linii.

Jednak ten test znowu działa dla każdego wypukłego wielokąta, co oznacza, że ​​może być zbyt ogólny dla prostokąta. Prostokąt może pozwolić na prostszy test ... Na przykład w prostokącie (lub w jakimkolwiek innym równoległoboku) wartości Ai Bmają tę samą wielkość, ale różne znaki dla przeciwnych (tj. Równoległych) krawędzi, które można wykorzystać do uproszczenia testu .

Mrówka
źródło
Dotyczy to tylko zestawu współrzędnych matematycznych. Na ekranie komputera i GPS kierunki osi są różne i nie możesz być pewien, że masz prawidłowy zestaw nierówności. Albo możesz być pewien, że nie. Moja odpowiedź jest lepsza :-).
Gangnus,
AndreyT @Gangnus, szybka precyzja, wystarczy sprawdzić, czy znak równania jest taki sam dla wszystkich punktów wypukłego kształtu w stosunku do P, dzięki temu nie martwisz się o układy współrzędnych lub kierunek, w którym znajduje się twój wypukły kształt zdefiniowane;))
Jason Rogers
2
Jest kilka rozszerzeń, które pozwalają przyspieszyć działanie. 1. Ponieważ dwa przeciwległe boki prostokąta są równoległe, ich współczynniki A, B mogą być takie same. 2. Ponieważ pozostałe dwa boki są do nich prostopadłe, ich współczynniki A'i B'mogą być podane przez A'=Bi B'=-A. 3. Nie ma sensu obliczać A xp + B ypobu krawędzi, więc połącz je w jeden test. Wtedy twój test na bycie w prostokącie staje się (v_min < A xp + B yp < v_max) && ( w_min < B xp - A yp < w_max ).
Michael Anderson
@MichaelAnderson A co to jest v_min, etc?
Anonimowy
v_minjest minimalną wartością A x + B ydla wszystkich wartości we wnętrzu prostokąta (która jest wartością minimalną podczas oceny w rogach). v_maxjest odpowiednim maksimum. Te w_?wartości są takie same, ale za Bx - A y.
Michael Anderson,
43

Zakładając, że prostokąt jest reprezentowany przez trzy punkty A, B, C, przy czym AB i BC są prostopadłe, wystarczy sprawdzić rzuty punktu zapytania M na AB i BC:

0 <= dot(AB,AM) <= dot(AB,AB) &&
0 <= dot(BC,BM) <= dot(BC,BC)

ABJest to wektor AB, o współrzędnych (BX-Ax, Ay, W) i dot(U,V)jest iloczyn skalarny wektorów U i V: Ux*Vx+Uy*Vy.

Aktualizuj . Zilustrujmy to na przykładzie: A (5,0) B (0,2) C (1,5) i D (6,3). Ze współrzędnych punktu otrzymujemy AB = (- 5,2), BC = (1,3), kropka (AB, AB) = 29, kropka (BC, BC) = 10.

Dla punktu zapytania M (4,2) mamy AM = (- 1,2), BM = (4,0), kropka (AB, AM) = 9, kropka (BC, BM) = 4. M znajduje się wewnątrz prostokąta.

Dla punktu zapytania P (6,1) mamy AP = (1,1), BP = (6, -1), kropka (AB, AP) = - 3, kropka (BC, BP) = 3. P nie znajduje się wewnątrz prostokąta, ponieważ jego rzut na bok AB nie znajduje się wewnątrz odcinka AB.

Eric Bainville
źródło
1
0,2 - 10,2 - 10,10 - 2,10 nie jest prostokątem.
Eric Bainville
2
Proszę nakreślić punkty i rozważyć weryfikację poprawności pierwszego komentarza.
Eric Bainville
3
To najlepsza odpowiedź!
Tahlil
1
Podoba mi się, że ta odpowiedź jest zwięzła, utrzymuje liczbę operacji mniej więcej na tak niskim poziomie, jak inne dobre odpowiedzi, ale ma również tę zaletę, że jest bardzo intuicyjna i wizualizowana.
Anonimowy
22

Pożyczyłem z odpowiedzi Erica Bainville'a:

0 <= dot(AB,AM) <= dot(AB,AB) && 0 <= dot(BC,BM) <= dot(BC,BC)

Co w javascript wygląda tak:

function pointInRectangle(m, r) {
    var AB = vector(r.A, r.B);
    var AM = vector(r.A, m);
    var BC = vector(r.B, r.C);
    var BM = vector(r.B, m);
    var dotABAM = dot(AB, AM);
    var dotABAB = dot(AB, AB);
    var dotBCBM = dot(BC, BM);
    var dotBCBC = dot(BC, BC);
    return 0 <= dotABAM && dotABAM <= dotABAB && 0 <= dotBCBM && dotBCBM <= dotBCBC;
}

function vector(p1, p2) {
    return {
            x: (p2.x - p1.x),
            y: (p2.y - p1.y)
    };
}

function dot(u, v) {
    return u.x * v.x + u.y * v.y; 
}

na przykład:

var r = {
    A: {x: 50, y: 0},
    B: {x: 0, y: 20},
    C: {x: 10, y: 50},
    D: {x: 60, y: 30}
};

var m = {x: 40, y: 20};

następnie:

pointInRectangle(m, r); // returns true.

Oto kod do narysowania wyniku jako testu wizualnego :) http://codepen.io/mattburns/pen/jrrprN

wprowadź opis obrazu tutaj

matowe oparzenia
źródło
Cześć @matt burns Użyłem twojej metody i umieściłem ją w moim projekcie testowym: jsfiddle.net/caymanbruce/06wjp2sk/6 Ale nie mogłem sprawić, żeby zadziałała. Nie mam pojęcia, dlaczego nadal testuje punkt w oryginalnym prostokącie bez obrotu. Używam mouseoverzdarzenia w moim projekcie, więc za każdym razem, gdy mysz znajdzie się nad punktem, który ma znajdować się wewnątrz prostokąta, wyświetli czarną kropkę wokół myszy, a poza prostokątem nie powinien nic wyświetlać. Potrzebuję pomocy, aby to zadziałało, ale jestem tak zdezorientowany.
newguy
mouseoverpowinno być mousemove, po prostu literówka.
newguy
Odniesienie
Zmart,
W zasadzie twoja metoda jest poprawna, ale twój prostokąt nie jest prostokątem w twoim przykładzie. Zrobiłem twoją ulepszoną wersję tutaj, gdzie trzymam się oryginalnej formuły i schematu nazewnictwa, i gdzie dane wejściowe są w rzeczywistości prawdziwym prostokątem.
JohannesB
15
# Pseudo code
# Corners in ax,ay,bx,by,dx,dy
# Point in x, y

bax = bx - ax
bay = by - ay
dax = dx - ax
day = dy - ay

if ((x - ax) * bax + (y - ay) * bay < 0.0) return false
if ((x - bx) * bax + (y - by) * bay > 0.0) return false
if ((x - ax) * dax + (y - ay) * day < 0.0) return false
if ((x - dx) * dax + (y - dy) * day > 0.0) return false

return true
Jonas Elfström
źródło
Przeczytaj to jako: „jeśli połączymy punkt z trzema wierzchołkami prostokąta, wówczas kąty między tymi segmentami i bokami powinny być ostre”
P Shved
3
Problem z takimi podejściami polega na tym, że działają one w teorii, ale paractice mogą napotkać problemy. OP nie powiedział, w jaki sposób reprezentowany jest prostokąt. Odpowiedź ta zakłada, że jest ona reprezentowana przez trzech punktach - a, bi d. Podczas gdy trzy punkty są poprawnym sposobem przedstawienia dowolnego prostokąta w teorii, w praktyce niemożliwe jest wykonanie dokładnego pomiaru we współrzędnych pośrednich w ogólnym przypadku. W ogólnym przypadku otrzymamy równoległobok, który jest bardzo zbliżony do prostokąta, ale nadal nie jest prostokątem.
AnT
3
To znaczy kąty w tym kształcie nie będą dokładnie 90 stopni. W takiej sytuacji należy być bardzo ostrożnym przy wykonywaniu testów kątowych. Znowu zależy to od tego, jak PO definiuje „wnętrze” dla nieprecyzyjnie przedstawionego „prostokąta”. I jeszcze raz, jak reprezentowany jest prostokąt.
AnT
Daj +1 obu swoim komentarzom. Tylko @avd może nam powiedzieć, czy to wystarczy.
Jonas Elfström
U mnie działa idealnie ... Używając dość często trygonometrii i geometrii, miło jest nie wymyślać wzoru na rozwiązanie typowego problemu. Dzięki.
2
12

Zdaję sobie sprawę, że to stary wątek, ale dla każdego, kto jest zainteresowany spojrzeniem na to z czysto matematycznej perspektywy, jest doskonały wątek na temat wymiany stosów matematycznych, tutaj:

/math/190111/how-to-check-if-a-point-is-inside-a-rectangle

Edycja: Zainspirowany tym wątkiem, opracowałem prostą metodę wektorową, aby szybko określić, gdzie leży twój punkt.

Załóżmy, że masz prostokąt z punktami w punktach p1 = (x1, y1), p2 = (x2, y2), p3 = (x3, y3) i p4 = (x4, y4), zgodnie z ruchem wskazówek zegara. Jeśli punkt p = (x, y) leży wewnątrz prostokąta, to iloczyn skalarny (p - p1). (P2 - p1) będzie leżeć między 0 a | p2 - p1 | ^ 2, a (p - p1). (p4 - p1) będzie leżeć między 0 a | p4 - p1 | ^ 2. Jest to równoważne z rzutem wektora p - p1 wzdłuż długości i szerokości prostokąta, z punktem początkowym p1.

Może to mieć więcej sensu, jeśli pokażę równoważny kod:

p21 = (x2 - x1, y2 - y1)
p41 = (x4 - x1, y4 - y1)

p21magnitude_squared = p21[0]^2 + p21[1]^2
p41magnitude_squared = p41[0]^2 + p41[1]^2

for x, y in list_of_points_to_test:

    p = (x - x1, y - y1)

    if 0 <= p[0] * p21[0] + p[1] * p21[1] <= p21magnitude_squared:
        if 0 <= p[0] * p41[0] + p[1] * p41[1]) <= p41magnitude_squared:
            return "Inside"
        else:
            return "Outside"
    else:
        return "Outside"

I to wszystko. Będzie również działać w przypadku równoległoboków.

Matt Thompson
źródło
Czy możesz podsumować dotychczasową dyskusję? W przeciwnym razie prawdopodobnie powinien to być komentarz, a nie odpowiedź. Z nieco większym przedstawicielem będziesz mógł publikować komentarze .
Nathan Tuggy
7
bool pointInRectangle(Point A, Point B, Point C, Point D, Point m ) {
    Point AB = vect2d(A, B);  float C1 = -1 * (AB.y*A.x + AB.x*A.y); float  D1 = (AB.y*m.x + AB.x*m.y) + C1;
    Point AD = vect2d(A, D);  float C2 = -1 * (AD.y*A.x + AD.x*A.y); float D2 = (AD.y*m.x + AD.x*m.y) + C2;
    Point BC = vect2d(B, C);  float C3 = -1 * (BC.y*B.x + BC.x*B.y); float D3 = (BC.y*m.x + BC.x*m.y) + C3;
    Point CD = vect2d(C, D);  float C4 = -1 * (CD.y*C.x + CD.x*C.y); float D4 = (CD.y*m.x + CD.x*m.y) + C4;
    return     0 >= D1 && 0 >= D4 && 0 <= D2 && 0 >= D3;}





Point vect2d(Point p1, Point p2) {
    Point temp;
    temp.x = (p2.x - p1.x);
    temp.y = -1 * (p2.y - p1.y);
    return temp;}

Punkty wewnątrz wielokąta

Właśnie zaimplementowałem odpowiedź AnT za pomocą c ++. Użyłem tego kodu, aby sprawdzić, czy koordynacja piksela (X, Y) leży wewnątrz kształtu, czy nie.

Alghyaline
źródło
Pewne wyjaśnienie tego, co tutaj robisz, byłoby naprawdę pomocne.
Brad
Chciałem tylko podziekować. Przekonwertowałem to, co musiałeś pracować dla Unity Shader i zmniejszyłem to o 3 punkty zamiast 4. Działało dobrze! Twoje zdrowie.
Dustin Jensen
U mnie zadziałało, oto implementacja w C #, którą zrobiłem dla Unity DOTS: gist.github.com/rgoupil/04b59be8ddb56c992f25e1489c61b310
JamesDev
6

Jeśli nie możesz rozwiązać problemu dla prostokąta, spróbuj podzielić problem na łatwiejsze. Podziel prostokąt na 2 trójkąty i sprawdź, czy punkt znajduje się wewnątrz któregokolwiek z nich, tak jak wyjaśniono tutaj

Zasadniczo przechodzisz między krawędziami na każdych dwóch parach linii z punktu. Następnie za pomocą iloczynu poprzecznego sprawdź, czy punkt znajduje się między dwiema liniami za pomocą iloczynu poprzecznego. Jeśli jest zweryfikowany dla wszystkich 3 punktów, to punkt znajduje się wewnątrz trójkąta. Zaletą tej metody jest to, że nie tworzy ona żadnych błędów punktów zmiennoprzecinkowych, które zdarzają się, gdy sprawdzasz kąty.

Cristian T
źródło
To jest poprawny, ale strasznie nieskuteczny algorytm.
Gangnus,
4

Jeśli punkt znajduje się wewnątrz prostokąta. W samolocie. Dla współrzędnych matematycznych lub geodezji (GPS)

  • Niech prostokąt będzie wyznaczony przez wierzchołki A, B, C, D. Punkt to P. Współrzędne są prostokątne: x, y.
  • Pozwala przedłużyć boki prostokąta. Mamy więc 4 proste l AB , l BC , l CD , l DA lub, w skrócie, l 1 , l 2 , l 3 , l 4 .
  • Zrób równanie dla każdego l i . Rodzaj równania:

    f i (P) = 0.

P to punkt. W przypadku punktów należących do l i równanie jest prawdziwe.

  • Potrzebujemy funkcji po lewej stronie równań. Są to f 1 , f 2 , f 3 , f 4 .
  • Zauważ, że dla każdego punktu z jednej strony l i funkcja f i jest większa niż 0, dla punktów z drugiej strony f i jest mniejsza niż 0.
  • Tak więc, jeśli sprawdzamy, czy P jest w prostokącie, potrzebujemy tylko, aby p znajdował się po właściwych stronach wszystkich czterech linii. Musimy więc sprawdzić cztery funkcje pod kątem ich znaków.
  • Ale która strona linii jest właściwa, do której należy prostokąt? Jest to bok, w którym leżą wierzchołki prostokąta nie należące do linii. Do sprawdzenia możemy wybrać dowolny z dwóch nienależących wierzchołków.
  • Więc musimy to sprawdzić:

    f AB (P) f AB (C)> = 0

    f BC (P) f BC (D)> = 0

    f CD (P) f CD (A)> = 0

    f DA (P) f DA (B)> = 0

Nierówności nie są ścisłe, bo jeśli punkt znajduje się na granicy, to również należy do prostokąta. Jeśli nie potrzebujesz punktów na granicy, możesz zmienić nierówności na ścisłe. Ale podczas pracy w operacjach zmiennoprzecinkowych wybór nie ma znaczenia.

  • Na przykład w prostokącie wszystkie cztery nierówności są prawdziwe. Zauważ, że działa to również dla każdego wypukłego wielokąta, różni się tylko liczba linii / równań.
  • Pozostaje tylko otrzymać równanie dla prostej przechodzącej przez dwa punkty. Jest to dobrze znane równanie liniowe. Napiszmy to dla prostej AB i punktu P:

    f AB (P) ≡ (x A -x B ) (y P -y B ) - (y A -y B ) (x P -x B )

Sprawdzanie można uprościć - przejdźmy wzdłuż prostokąta zgodnie z ruchem wskazówek zegara - A, B, C, D, A. Wtedy wszystkie poprawne strony będą po prawej stronie linii. Nie musimy więc porównywać ze stroną, na której znajduje się inny wierzchołek. I musimy sprawdzić zestaw krótszych nierówności:

f AB (P)> = 0

f BC (P)> = 0

f CD (P)> = 0

f DA (P)> = 0

Ale jest to poprawne dla normalnego, matematycznego (ze szkolnej matematyki) zestawu współrzędnych, gdzie X jest po prawej stronie, a Y do góry. A dla współrzędnych geodezji , które są używane w GPS, gdzie X jest na górze, a Y na prawo, musimy odwrócić równania:

f AB (P) <= 0

f BC (P) <= 0

f CD (P) <= 0

f DA (P) <= 0

Jeśli nie masz pewności co do kierunków osi, zachowaj ostrożność przy tej uproszczonej kontroli - sprawdź jeden punkt ze znanym położeniem, jeśli wybrałeś prawidłowe nierówności.

Gangnus
źródło
"gdzie X jest na górze, a Y na prawo, musimy odwrócić równania:" To zależy od tego, jak określisz "zgodnie z ruchem wskazówek zegara". Jeśli weźmiesz pod uwagę współrzędne matematyczne, zgodnie z ruchem wskazówek zegara stanie się automatycznie przeciwnie do ruchu wskazówek zegara i nadal możesz używać pierwszego tego samego zestawu nierówności. Innymi słowy, możesz się dobrze obejść bez tego bałaganu, jeśli weźmiesz pod uwagę współrzędne matematyczne we wszystkich aspektach. Odwrócenie lub zamiana współrzędnych nie będzie miało wpływu na ten predykat.
Palo
@Palo Matematyka sama w sobie nie ma orientacji. Tak. Ale algorytm ma kilka punktów i znacznie lepiej byłoby mieć zrozumiałe i rozsądne (w prawdziwym życiu) wyniki w dowolnym miejscu, aby móc je przetestować. Bez tego do końca drugiego zdania trudno jest sprawdzić, czy poprawnie rozwiązujesz nierówności, używając wyobraźni kosmicznej.
Gangnus,
0

Najprostszym sposobem, o którym pomyślałem, było po prostu rzutowanie punktu na oś prostokąta. Pozwól mi wyjaśnić:

Jeśli możesz uzyskać wektor od środka prostokąta do górnej lub dolnej krawędzi i lewej lub prawej krawędzi. Masz również wektor od środka prostokąta do punktu, możesz rzutować ten punkt na wektory szerokości i wysokości.

P = wektor punktowy, H = wektor wysokości, W = wektor szerokości

Uzyskaj wektor jednostkowy W ', H', dzieląc wektory przez ich wielkość

proj_P, H = P - (P.H ') H' proj_P, W = P - (P.W ') W'

Chyba że się mylę, co nie wydaje mi się ... (Popraw mnie, jeśli się mylę), ale jeśli wielkość rzutu twojego punktu na wektorze wysokości jest mniejsza niż wielkość wektora wysokości (który jest połowa wysokości prostokąta) i wielkość rzutu twojego punktu na wektor szerokości wynosi, wtedy masz punkt wewnątrz prostokąta.

Jeśli masz uniwersalny układ współrzędnych, być może będziesz musiał obliczyć wektory wysokości / szerokości / punktów za pomocą odejmowania wektorów. Projekcje wektorowe są niesamowite! Zapamietaj to.

Mateusz
źródło
0

W dalszej części odpowiedzi. musimy użyć rozwiązania /math/190111/how-to-check-if-a-point-is-inside-a-rectangle/190373#190373 , aby działało

Poniżej nie działa
0 <= kropka (AB, AM) <= kropka (AB, AB) && 0 <= kropka (BC, BM) <= kropka (BC, BC)

Poniżej działa
0 <= kropka (AB, AM) <= kropka (AB, AB) && 0 <= kropka (AM, AC) <= kropka (AC, AC)

sprawdzasz, wklejając poniżej w konsoli javascript // rozwiązanie Javascript dla tego samego

            var screenWidth = 320;
            var screenHeight = 568;
            var appHeaderWidth = 320;
            var AppHeaderHeight = 65;
            var regionWidth = 200;
            var regionHeight = 200;

            this.topLeftBoundary = {
                A: {x: 0, y: AppHeaderHeight},
                B: {x: regionWidth, y: AppHeaderHeight},
                C: {x: 0, y: regionHeight + AppHeaderHeight},
                D: {x: regionWidth, y: regionHeight + AppHeaderHeight}
            }

            this.topRightBoundary = {
                A: {x: screenWidth, y: AppHeaderHeight},
                B: {x: screenWidth - regionWidth, y: AppHeaderHeight},
                C: {x: screenWidth, y: regionHeight + AppHeaderHeight},
                D: {x: screenWidth - regionWidth, y: regionHeight + AppHeaderHeight}
            }

            this.bottomRightBoundary = {
                A: {x: screenWidth, y: screenHeight},
                B: {x: screenWidth - regionWidth, y: screenHeight},
                C: {x: screenWidth, y: screenHeight - regionHeight},
                D: {x: screenWidth - regionWidth, y: screenHeight - regionHeight}
            }

            this.bottomLeftBoundary = {
                A: {x: 0, y: screenHeight},
                B: {x: regionWidth, y: screenHeight},
                C: {x: 0, y: screenHeight - regionHeight},
                D: {x: regionWidth, y: screenHeight - regionHeight}
            }
            console.log(this.topLeftBoundary);
            console.log(this.topRightBoundary);
            console.log(this.bottomRightBoundary);
            console.log(this.bottomLeftBoundary);

            checkIfTapFallsInBoundary = function (region, point) {
                console.log("region " + JSON.stringify(region));
                console.log("point" + JSON.stringify(point));

                var r = region;
                var m = point;

                function vector(p1, p2) {
                    return {
                        x: (p2.x - p1.x),
                        y: (p2.y - p1.y)
                    };
                }

                function dot(u, v) {
                    console.log("DOT " + (u.x * v.x + u.y * v.y));
                    return u.x * v.x + u.y * v.y;
                }

                function pointInRectangle(m, r) {
                    var AB = vector(r.A, r.B);
                    var AM = vector(r.A, m);
                    var AC = vector(r.A, r.C);
                    var BC = vector(r.B, r.C);
                    var BM = vector(r.B, m);

                    console.log("AB " + JSON.stringify(AB));
                    console.log("AM " + JSON.stringify(AM));
                    console.log("AM " + JSON.stringify(AC));
                    console.log("BC " + JSON.stringify(BC));
                    console.log("BM " + JSON.stringify(BM));

                    var dotABAM = dot(AB, AM);
                    var dotABAB = dot(AB, AB);
                    var dotBCBM = dot(BC, BM);
                    var dotBCBC = dot(BC, BC);
                    var dotAMAC = dot(AM, AC);
                    var dotACAC = dot(AC, AC);

                    console.log("ABAM " + JSON.stringify(dotABAM));
                    console.log("ABAB " + JSON.stringify(dotABAB));
                    console.log("BCBM " + JSON.stringify(dotBCBM));
                    console.log("BCBC " + JSON.stringify(dotBCBC));
                    console.log("AMAC " + JSON.stringify(dotAMAC));
                    console.log("ACAC" + JSON.stringify(dotACAC));

                    var check = ((0 <= dotABAM && dotABAM <= dotABAB) && (0 <= dotBCBM && dotBCBM <= dotBCBC));
                    console.log(" first check" + check);
                    var check = ((0 <= dotABAM && dotABAM <= dotABAB) && (0 <= dotAMAC && dotAMAC <= dotACAC));
                    console.log("second check" + check);
                    return check;
                }

                return pointInRectangle(m, r);
            }

        //var point = {x: 136, y: 342};

            checkIfTapFallsInBoundary(topLeftBoundary, {x: 136, y: 342});
            checkIfTapFallsInBoundary(topRightBoundary, {x: 136, y: 274});
            checkIfTapFallsInBoundary(bottomRightBoundary, {x: 141, y: 475});
            checkIfTapFallsInBoundary(bottomRightBoundary, {x: 131, y: 272});
            checkIfTapFallsInBoundary(bottomLeftBoundary, {x: 131, y: 272});
codeninja
źródło