Tìm xem một điểm có nằm bên trong hình chữ nhật hay không


82

Tôi muốn tìm xem một điểm có nằm bên trong hình chữ nhật hay không. Hình chữ nhật có thể được định hướng theo bất kỳ cách nào và không cần phải căn chỉnh trục.

Một phương pháp tôi có thể nghĩ ra là xoay hình chữ nhật và tọa độ điểm để làm cho trục hình chữ nhật được căn chỉnh và sau đó chỉ cần kiểm tra tọa độ của điểm xem chúng có nằm trong trục của hình chữ nhật hay không.

Phương pháp trên yêu cầu các phép toán quay và do đó dấu phẩy động. Có cách nào hiệu quả khác để làm điều này không?


Bạn có thể thực hiện kiểm tra nhanh để xem liệu điểm có nằm trong hộp giới hạn trực giao của hình chữ nhật được xoay hay không và sẽ nhanh chóng thất bại nếu không. (Vâng, đó chỉ là một nửa câu trả lời (hmmm, có ba hộp trực giao có thể được tạo thành bởi các điểm góc ... và đã muộn (hình học khái niệm là hình học đầu tiên))).
msw

Nhưng tôi phải xoay trước đúng không?
AVD

1
Nếu bạn không cho chúng tôi biết hình chữ nhật của bạn được xác định như thế nào, sẽ không có nhiều giá trị thực tế trong các câu trả lời. Khi bạn đang làm việc với tọa độ số nguyên, phương pháp được sử dụng để biểu diễn hình dạng có tầm quan trọng quan trọng khi lựa chọn thuật toán.
AnT

Câu trả lời:


80

Hình chữ nhật được biểu diễn như thế nào? Ba điểm? Bốn điểm? Điểm, cạnh và góc? Hai điểm và một bên? Thứ gì khác? Nếu không biết điều đó, bất kỳ nỗ lực nào để trả lời câu hỏi của bạn sẽ chỉ có giá trị học thuật thuần túy.

Trong mọi trường hợp, đối với bất kỳ đa giác lồi nào (bao gồm cả hình chữ nhật), việc kiểm tra rất đơn giản: kiểm tra từng cạnh của đa giác, giả sử mỗi cạnh được định hướng theo hướng ngược chiều kim đồng hồ và kiểm tra xem điểm có nằm bên trái không cạnh (ở bên trái không -nửa mặt phẳng). Nếu tất cả các cạnh đều vượt qua bài kiểm tra - điểm nằm bên trong. Nếu ít nhất một lỗi - điểm nằm ngoài.

Để kiểm tra xem điểm có (xp, yp)nằm ở phía bên trái của cạnh hay không (x1, y1) - (x2, y2), bạn chỉ cần tính

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

Nếu D > 0, điểm nằm ở phía bên trái. Nếu D < 0, điểm nằm ở phía bên tay phải. Nếu D = 0, điểm nằm trên đường thẳng.


Phiên bản trước của câu trả lời này đã mô tả một phiên bản có vẻ khác của bài kiểm tra bên tay trái (xem bên dưới). Nhưng có thể dễ dàng chỉ ra rằng nó tính toán cùng một giá trị.

... Để kiểm tra xem điểm có (xp, yp)nằm bên trái cạnh hay không (x1, y1) - (x2, y2), bạn cần xây dựng phương trình đường thẳng cho đường thẳng chứa cạnh. Phương trình như sau

A * x + B * y + C = 0

Ở đâu

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

Bây giờ tất cả những gì bạn cần làm là tính toán

D = A * xp + B * yp + C

Nếu D > 0, điểm nằm ở phía bên trái. Nếu D < 0, điểm nằm ở phía bên tay phải. Nếu D = 0, điểm nằm trên đường thẳng.

Tuy nhiên, thử nghiệm này, một lần nữa, hoạt động đối với bất kỳ đa giác lồi nào, có nghĩa là nó có thể quá chung chung đối với một hình chữ nhật. Một hình chữ nhật có thể cho phép thử nghiệm đơn giản hơn ... Ví dụ, trong một hình chữ nhật (hoặc trong bất kỳ hình bình hành nào khác) các giá trị của ABcó cùng độ lớn nhưng các dấu hiệu khác nhau cho các cạnh đối lập (tức là song song), có thể được khai thác để đơn giản hóa thử nghiệm .


Điều đó chỉ đúng với tập tọa độ nhà toán học. Trên màn hình PC và đối với GPS, các hướng của trục là khác nhau và bạn không thể chắc chắn rằng mình đã đặt đúng phương trình. Hoặc bạn có thể chắc chắn rằng bạn chưa. Câu trả lời của tôi là tốt hơn :-).
Gangnus

AndreyT @Gangnus, độ chính xác nhanh chóng, bạn chỉ cần kiểm tra xem dấu của phương trình có giống nhau cho tất cả các điểm của hình lồi liên quan đến P hay không, điều này cho phép bạn không phải lo lắng về hệ tọa độ hoặc hình dạng lồi của bạn theo hướng nào đã xác định;))
Jason Rogers

2
Có một số tiện ích mở rộng cho phép bạn tăng tốc mọi thứ. 1. Vì hai cạnh đối diện của hình chữ nhật song song nên các hệ số A, B của chúng có thể bằng nhau. 2. Vì hai cạnh còn lại vuông góc với chúng, các hệ số của chúng A'B'có thể được cho bởi A'=BB'=-A. 3. Không có tính điểm A xp + B ypcho cả hai cạnh, vì vậy hãy kết hợp chúng thành một bài kiểm tra duy nhất. Sau đó, thử nghiệm của bạn về việc nằm trong một hình chữ nhật trở thành (v_min < A xp + B yp < v_max) && ( w_min < B xp - A yp < w_max ).
Michael Anderson

@MichaelAnderson Và là gì v_min, v.v.?
Anonymous

v_minlà giá trị nhỏ nhất của A x + B ytất cả các giá trị bên trong hình chữ nhật (là giá trị nhỏ nhất khi được đánh giá ở các góc). v_maxlà mức tối đa tương ứng. Các w_?giá trị giống nhau, nhưng đối với Bx - A y.
Michael Anderson

41

Giả sử hình chữ nhật được biểu diễn bởi ba điểm A, B, C, vuông góc với AB và BC, bạn chỉ cần kiểm tra các hình chiếu của điểm M trên AB và BC:

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

ABlà vectơ AB, có tọa độ (Bx-Ax, By-Ay), và dot(U,V)là tích chấm của vectơ U và V : Ux*Vx+Uy*Vy.

Cập nhật . Hãy lấy một ví dụ để minh họa điều này: A (5,0) B (0,2) C (1,5) và D (6,3). Từ tọa độ điểm, ta được AB = (- 5,2), BC = (1,3), chấm (AB, AB) = 29, chấm (BC, BC) = 10.

Đối với truy vấn điểm M (4,2), ta có AM = (- 1,2), BM = (4,0), dấu chấm (AB, AM) = 9, dấu chấm (BC, BM) = 4. M nằm bên trong hình chữ nhật.

Đối với truy vấn điểm P (6,1), ta có AP = (1,1), BP = (6, -1), dấu chấm (AB, AP) = - 3, dấu chấm (BC, BP) = 3. P không nằm trong hình chữ nhật vì hình chiếu của nó trên cạnh AB không nằm trong đoạn AB.


1
0,2 - 10,2 - 10,10 - 2,10 không phải là hình chữ nhật.
Eric Bainville

2
Vui lòng vẽ các điểm và xem xét xác minh tính chính xác của nhận xét đầu tiên của bạn.
Eric Bainville

3
Đây là câu trả lời tốt nhất!
Tahlil

1
Tôi thích câu trả lời này là ngắn gọn, giữ số lượng thao tác ít hơn hoặc ít hơn các câu trả lời hay khác ở đây, nhưng cũng có ưu điểm là rất trực quan và dễ hình dung.
Ẩn danh vào

22

Tôi đã mượn câu trả lời của Eric Bainville:

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

Trong javascript trông như thế này:

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; 
}

ví dụ:

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};

sau đó:

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

Đây là một codepen để vẽ đầu ra như một bài kiểm tra trực quan :) http://codepen.io/mattburns/pen/jrrprN

nhập mô tả hình ảnh ở đây


Xin chào @matt ghi Tôi đã sử dụng phương pháp của bạn và đưa nó vào một dự án thử nghiệm của tôi: jsfiddle.net/caymanbruce/06wjp2sk/6 Nhưng tôi không thể làm cho nó hoạt động. Không hiểu tại sao nó vẫn đang kiểm tra điểm bên trong hình chữ nhật ban đầu mà không quay. Tôi sử dụng một mouseoversự kiện trong dự án của mình để bất cứ khi nào con chuột đi qua điểm được cho là bên trong hình chữ nhật, nó sẽ hiển thị một chấm tròn màu đen xung quanh con chuột và bên ngoài hình chữ nhật, nó sẽ không hiển thị gì. Tôi cần giúp đỡ để nó hoạt động nhưng tôi rất bối rối.
newguy ngày

mouseovernên được mousemove, chỉ là lỗi đánh máy.
newguy ngày


Về nguyên tắc, phương pháp của bạn là đúng, nhưng hình chữ nhật của bạn không phải là hình chữ nhật trong ví dụ của bạn. Tôi đã tạo một phiên bản cải tiến của bạn ở đây , nơi tôi bám vào công thức và sơ đồ đặt tên ban đầu, và nơi đầu vào trên thực tế là một hình chữ nhật thực sự.
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

Đọc điều này là: "nếu chúng ta nối điểm với ba đỉnh của hình chữ nhật thì góc giữa các đoạn và các cạnh đó sẽ là góc nhọn"
P Shved

3
Vấn đề với những cách tiếp cận như thế này là chúng hoạt động trên lý thuyết, nhưng trong thời gian ngắn, người ta có thể gặp vấn đề. OP không cho biết hình chữ nhật được biểu diễn như thế nào. Câu trả lời này giả định rằng nó được đại diện bởi ba điểm - a, bd. Trong khi trên lý thuyết, ba điểm là một cách hợp lệ để biểu diễn một hình chữ nhật tùy ý, nhưng trong thực tế, không thể thực hiện chính xác trong trường hợp tọa độ xen kẽ. Trong trường hợp chung, người ta sẽ có một hình bình hành, rất gần với hình chữ nhật nhưng vẫn không phải là hình chữ nhật.
AnT

3
Tức là các góc trong hình dạng đó sẽ không chính xác là 90 độ. Người ta phải rất cẩn thận khi thực hiện bất kỳ thử nghiệm dựa trên góc độ nào trong tình huống như vậy. Một lần nữa, nó phụ thuộc vào cách OP xác định "bên trong" cho một "hình chữ nhật" được biểu diễn không chính xác. Và, một lần nữa, về cách hình chữ nhật được biểu diễn.
AnT

+1 cho cả hai nhận xét của bạn. Chỉ @avd mới có thể cho chúng tôi biết liệu điều này có đủ tốt hay không.
Jonas Elfström

Hoạt động hoàn hảo đối với tôi ... Sử dụng lượng giác và hình học khá thường xuyên, thật tuyệt khi không phải nghĩ ra công thức để giải một vấn đề thông thường. Cảm ơn.
sq 2

12

Tôi nhận thấy đây là một chủ đề cũ, nhưng đối với bất kỳ ai quan tâm đến việc xem xét điều này từ góc độ toán học thuần túy, có một chủ đề tuyệt vời trên trao đổi ngăn xếp toán học, đây:

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

Chỉnh sửa: Lấy cảm hứng từ chủ đề này, tôi đã tổng hợp một phương pháp vectơ đơn giản để nhanh chóng xác định điểm của bạn nằm ở đâu.

Giả sử bạn có một hình chữ nhật với các điểm tại p1 = (x1, y1), p2 = (x2, y2), p3 = (x3, y3) và p4 = (x4, y4), theo chiều kim đồng hồ. Nếu một điểm p = (x, y) nằm bên trong hình chữ nhật thì tích chấm (p - p1). (P2 - p1) sẽ nằm giữa 0 và | p2 - p1 | ^ 2, và (p - p1). (p4 - p1) sẽ nằm giữa 0 và | p4 - p1 | ^ 2. Điều này tương đương với việc lấy hình chiếu của vectơ p - p1 dọc theo chiều dài và chiều rộng của hình chữ nhật, với p1 là gốc.

Điều này có thể có ý nghĩa hơn nếu tôi hiển thị một mã tương đương:

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"

Và đó là nó. Nó cũng sẽ hoạt động cho các hình bình hành.


Bạn có thể tóm tắt cuộc thảo luận ở đó cho đến nay không? Nếu không, đây có lẽ nên là một bình luận, không phải là một câu trả lời. Với nhiều đại diện hơn một chút, bạn sẽ có thể đăng nhận xét .
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;}

Các điểm bên trong đa giác

Tôi vừa triển khai Câu trả lời của AnT bằng c ++. Tôi đã sử dụng mã này để kiểm tra xem sự phối hợp của pixel (X, Y) có nằm bên trong hình dạng hay không.


Một số lời giải thích cho những gì bạn đang làm ở đây sẽ thực sự hữu ích.
Brad

Chỉ muốn nói lời cảm ơn. Tôi đã chuyển đổi những gì bạn phải làm việc cho Unity Shader và giảm nó cho 3 điểm thay vì 4. Hoạt động tốt! Chúc mừng.
Dustin Jensen

Nó hoạt động với tôi, đây là một triển khai trong C # tôi đã tạo cho Unity DOTS: gist.github.com/rgoupil/04b59be8ddb56c992f25e1489c61b310
JamesDev

6

Nếu bạn không thể giải bài toán cho hình chữ nhật, hãy thử chia bài toán thành các bài toán dễ hơn. Chia hình chữ nhật thành 2 hình tam giác và kiểm tra xem điểm có nằm bên trong bất kỳ hình tam giác nào như họ giải thích ở đây không

Về cơ bản, bạn quay vòng qua các cạnh trên mỗi hai cặp đường từ một điểm. Sau đó sử dụng sản phẩm chéo để kiểm tra xem điểm có nằm giữa hai đường bằng cách sử dụng sản phẩm chéo hay không. Nếu nó được xác minh cho cả 3 điểm, thì điểm đó nằm bên trong tam giác. Ưu điểm của phương pháp này là nó không tạo ra bất kỳ lỗi dấu phẩy động nào xảy ra nếu bạn kiểm tra các góc.


Đó là chính xác, nhưng thuật toán không hiệu quả đáng kể.
Gangnus,

4

Nếu một điểm nằm bên trong hình chữ nhật. Trên máy bay. Đối với tọa độ nhà toán học hoặc trắc địa (GPS)

  • Cho hình chữ nhật được đặt bởi các đỉnh A, B, C, D. Điểm là P. Toạ độ của hình chữ nhật: x, y.
  • Cho phép kéo dài các cạnh của hình chữ nhật. Vậy ta có 4 đoạn thẳng là AB , l BC , l CD , l DA , viết tắt là l 1 , l 2 , l 3 , l 4 .
  • Lập phương trình cho mọi l i . Loại phương trình của:

    f i (P) = 0.

P là một điểm. Đối với các điểm thuộc l i , đẳng thức đúng.

  • Chúng ta cần các hàm ở vế trái của phương trình. Chúng là f 1 , f 2 , f 3 , f 4 .
  • Lưu ý rằng với mọi điểm từ một phía của l i thì hàm f i lớn hơn 0, đối với các điểm từ phía kia f i nhỏ hơn 0.
  • Vì vậy, nếu chúng ta đang kiểm tra xem P có nằm trong hình chữ nhật hay không, chúng ta chỉ cần để p nằm trên các cạnh chính xác của cả bốn dòng. Vì vậy, chúng ta phải kiểm tra bốn chức năng cho các dấu hiệu của chúng.
  • Nhưng cạnh nào của đường thẳng là đúng, thuộc về hình chữ nhật? Nó là mặt bên, nơi chứa các đỉnh của hình chữ nhật không thuộc về đường thẳng. Để kiểm tra, chúng ta có thể chọn bất kỳ ai trong hai đỉnh không thuộc.
  • Vì vậy, chúng ta phải kiểm tra điều này:

    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

Các kết quả không nghiêm ngặt, vì nếu một điểm nằm trên đường viền, nó cũng thuộc hình chữ nhật. Nếu bạn không cần điểm trên biên giới, bạn có thể thay đổi sự bất bình đẳng cho những điểm nghiêm ngặt. Nhưng trong khi bạn làm việc trong các phép toán dấu phẩy động, sự lựa chọn này không liên quan.

  • Đối với một điểm nằm trong hình chữ nhật, cả bốn bất đẳng thức đều đúng. Lưu ý rằng nó cũng hoạt động cho mọi đa giác lồi, chỉ có số dòng / phương trình sẽ khác nhau.
  • Điều duy nhất còn lại là để có được một phương trình cho một đường thẳng đi qua hai điểm. Nó là một phương trình tuyến tính nổi tiếng. Hãy viết nó cho đoạn thẳng AB và điểm P:

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

Việc kiểm tra có thể được đơn giản hóa - hãy đi dọc theo hình chữ nhật theo chiều kim đồng hồ - A, B, C, D, A. Sau đó, tất cả các cạnh đúng sẽ ở bên phải của các dòng. Vì vậy, chúng ta không cần phải so sánh với bên có một đỉnh khác. Và chúng ta cần kiểm tra một tập các bất đẳng thức ngắn hơn:

f AB (P)> = 0

f BC (P)> = 0

f CD (P)> = 0

f DA (P)> = 0

Nhưng điều này đúng đối với tập tọa độ bình thường của nhà toán học (từ toán học ở trường), trong đó X ở bên phải và Y ở trên cùng. Và đối với các tọa độ trắc địa , như được sử dụng trong GPS, trong đó X ở trên cùng và Y ở bên phải, chúng ta phải biến các bất đẳng thức:

f AB (P) <= 0

f BC (P) <= 0

f CD (P) <= 0

f DA (P) <= 0

Nếu bạn không chắc chắn với hướng của các trục, hãy cẩn thận với cách kiểm tra đơn giản này - hãy kiểm tra một điểm với vị trí đã biết, nếu bạn đã chọn đúng các bất đẳng thức.


"trong đó X ở trên cùng, và Y ở bên phải, chúng ta phải biến các bất đẳng thức:" Điều đó phụ thuộc vào cách bạn xác định "theo chiều kim đồng hồ". Nếu bạn coi các tọa độ là các tọa độ toán học, thì chiều kim đồng hồ sẽ tự động trở thành ngược chiều kim đồng hồ, và bạn vẫn có thể sử dụng chính tập bất đẳng thức đầu tiên. Nói cách khác, bạn có thể suôn sẻ mà không có sự lộn xộn này nếu bạn chỉ coi các tọa độ là những tọa độ toán học trong mọi khía cạnh. Đảo ngược hoặc trao đổi tọa độ sẽ không ảnh hưởng đến vị từ này.
Palo

@Palo Toán học không có định hướng của chính nó. Đúng. Nhưng thuật toán có một số điểm và sẽ tốt hơn nhiều nếu có kết quả dễ hiểu và hợp lý (trong cuộc sống thực) ở bất kỳ điểm nào của nó, để có thể kiểm tra. Nếu không có điều đó ở cuối câu thứ hai của bạn, bạn khó có thể kiểm tra xem bạn có đang giải các bất đẳng thức một cách chính xác hay không, bằng cách sử dụng trí tưởng tượng không gian của bạn.
Gangnus,

0

Cách dễ nhất mà tôi nghĩ ra là chỉ chiếu điểm lên trục của hình chữ nhật. Hãy để tôi giải thích:

Nếu bạn có thể lấy vector từ tâm của hình chữ nhật đến cạnh trên hoặc cạnh dưới và cạnh trái hoặc cạnh phải. Và bạn cũng có một vectơ từ tâm của hình chữ nhật đến điểm của bạn, bạn có thể chiếu điểm đó lên vectơ chiều rộng và chiều cao của mình.

P = vectơ điểm, H = vectơ chiều cao, W = vectơ chiều rộng

Lấy vectơ đơn vị W ', H' bằng cách chia các vectơ cho độ lớn của chúng

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

Trừ khi tôi nhầm, điều mà tôi không nghĩ là ... (Hãy sửa cho tôi nếu tôi sai) nhưng nếu độ lớn của hình chiếu của điểm của bạn trên vectơ độ cao nhỏ hơn thì độ lớn của vectơ độ cao (đó là một nửa chiều cao của hình chữ nhật) và độ lớn của hình chiếu của điểm của bạn trên vectơ chiều rộng là, khi đó bạn có một điểm bên trong hình chữ nhật của bạn.

Nếu bạn có một hệ tọa độ phổ quát, bạn có thể phải tìm ra vectơ chiều cao / chiều rộng / điểm bằng cách sử dụng phép trừ vectơ. Phép chiếu vectơ thật tuyệt vời! nhớ lấy.


0

Trong câu trả lời matts tiếp tục. chúng tôi cần sử dụng /math/190111/how-to-check-if-a-point-is-inside-a-rectangle/190373#190373 giải pháp để làm cho nó hoạt động

Bên dưới không hoạt động
0 <= dot (AB, AM) <= dot (AB, AB) && 0 <= dot (BC, BM) <= dot (BC, BC)

Bên dưới hoạt động
0 <= dot (AB, AM) <= dot (AB, AB) && 0 <= dot (AM, AC) <= dot (AC, AC)

bạn kiểm tra bằng cách dán bên dưới vào bảng điều khiển javascript // Giải pháp Javascript cho cùng

            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});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.