Kiểm tra một điểm nằm trên đoạn thẳng

Một phần của tài liệu Lý thuyết và demo thực hành về lập trình game 2D với API Canvas trong Html5 (Trang 50 - 51)

Có nhiều cách để kiểm tra một điểm có thuộc đường thằng (tương tự với đoạn thẳng) hay không: bằng cách sử dụng các công thức hình học hoặc thuật toán vẽ đường thẳng,… Ngoài những cách trên, ta sẽ giới thiệu một phương pháp đơn giản nhất là sử dụng phép so sánh góc để giải quyết vấn đề này.

Trong demo sau, khi bạn di chuyển chuột ngang lên trên đoạn thẳng, bạn sẽ đoạn thẳng chuyển sang màu đỏ.

Ý tưởng:

Ta có đoạn thẳng AB tạo nên góc α (so với phương ngang hoặc phương bất kì), và mọi điểm thuộc AB đều tạo nên góc α so với phương ngang.

Hay nói cách khác, ta xem đoạn thẳng AB là đường chéo của một tam giác vuông ABM. Tỉ lệ giữa hai cạnh góc vuông của tam giác này sẽ bằng với tỉ lệ hai cạnh góc vuông tạo bởi tam giác vuông AXN. Minh họa như hình dưới đây:

Như vậy việc xác định một điểm X có thuộc AB hay không chỉ cần dựa vào 2 yếu tố:

(1) X phải nằm trong vùng hình chữ nhật được tạo bởi đường chéo AB (ngoại tiếp tam giác ABM).

(2) Góc XAN và BAM phải bằng nhau.

Ngoài ra, do việc so sánh là kiểu số thực và có thể do độ rộng của đoạn thẳng khác nhau nên ta cần chấp nhận một giá trị sai số EPSILON nào đó.

51 | P a g e Muốn chính xác hơn khi độ rộng của đoạn thẳng thay đổi, bạn có thể tính góc sai số cho phép bằng cách dựa vào ½ độ rộng đoạn thẳng và khoảng cách AX để tính. Tuy nhiên, điều này không quan trọng lắm và làm cho việc kiểm tra tốn thêm chi phí.

Để đơn giản, ta sẽ tính tỉ lệ (tan) thay vì tính góc α:

Line.prototype.contains = function(x, y) { if( x < Math.min(this.handler1.cx,this.handler2.cx) || x > Math.max(this.handler1.cx,this.handler2.cx) || y < Math.min(this.handler1.cy,this.handler2.cy) || y > Math.max(this.handler1.cy,this.handler2.cy)) return false; var dx = this.handler1.cx-this.handler2.cx; var dy = this.handler1.cy-this.handler2.cy; var tan1 = Math.abs(dy/dx);

var tan2 = Math.abs((y-this.handler1.cy)/(x-this.handler1.cx)); return Math.abs(tan1 - tan2) < EPSILON;

}

Một phần của tài liệu Lý thuyết và demo thực hành về lập trình game 2D với API Canvas trong Html5 (Trang 50 - 51)

Tải bản đầy đủ (PDF)

(114 trang)