Cách vẽ đường thẳng trong javascript

Phương pháp CanvasRenderingContext2D


0, một phần của API Canvas 2D, thêm một đường thẳng vào đường dẫn phụ hiện tại bằng cách kết nối điểm cuối cùng của đường dẫn phụ với tọa độ

1 đã chỉ định

Giống như các phương thức khác sửa đổi đường dẫn hiện tại, phương thức này không trực tiếp hiển thị bất kỳ thứ gì. Để vẽ đường dẫn lên canvas, bạn có thể sử dụng phương pháp


2 hoặc

3

cú pháp

lineTo[x, y]

Thông số


0

Tọa độ trục x của điểm cuối của đường


1

Tọa độ trục y của điểm cuối của đường

Giá trị trả về

Không có [


2]

ví dụ

Vẽ một đường thẳng

Ví dụ này vẽ một đường thẳng bằng phương pháp


0

HTML


JavaScript

Dòng bắt đầu tại [30, 50] và kết thúc tại [150, 100]

const canvas = document.getElementById["canvas"];
const ctx = canvas.getContext["2d"];

ctx.beginPath[]; // Start a new path
ctx.moveTo[30, 50]; // Move the pen to [30, 50]
ctx.lineTo[150, 100]; // Draw a line to [150, 100]
ctx.stroke[]; // Render the path

Kết quả

Vẽ các đường kết nối

Mỗi cuộc gọi của


0 [và các phương thức tương tự] sẽ tự động thêm vào đường dẫn con hiện tại, có nghĩa là tất cả các dòng sẽ được vuốt hoặc điền vào cùng nhau. Ví dụ này vẽ một chữ cái 'M' với một đường liền kề

CSS Visual Dictionary chứa các sơ đồ trực quan cho mọi thuộc tính CSS đơn lẻ được sử dụng phổ biến. Ngữ pháp JavaScript chứa…

hướng dẫn. trung bình. com

Một dự án mới luôn bắt đầu với một câu hỏi giải quyết vấn đề

Làm cách nào để bạn vẽ một đường trên màn hình máy tính mà không có canvas hoặc thư viện?

Là một người mới viết mã, bạn thường nghe về các thuật toán

Người tạo HTML Canvas, SVG, WebGL và các thư viện đồ họa khác phải viết mã để vẽ các đường từ đầu

Đã đến lúc vạch ra ranh giới giữa nghe về điều gì đó và thực hiện nó. . ]

Trong hướng dẫn này, tôi sẽ chỉ cho bạn các chi tiết cơ bản về việc thiết kế một thuật toán là như thế nào. Tôi sẽ lấy thuật toán Bresenham’s Line Drawing làm ví dụ

Tại sao lại là thuật toán vẽ đường của Bresenham?

Tôi nghĩ đó là một mẫu vật hoàn hảo để học hỏi vì nhiều lý do

  1. Thật bổ ích — bạn không chỉ tính toán các con số mà còn xem kết quả trực quan
  2. Nó tương đối đơn giản như ví dụ đầu tiên của bạn để nghiên cứu các thuật toán từ
  3. Nó sử dụng Hệ tọa độ Descartes — hệ tọa độ được sử dụng làm cơ sở trong nhiều thuật toán phổ biến. Đó là điều kiện tiên quyết để Machine Learning [sử dụng cái gọi là chức năng kích hoạt trong AI, là các phương trình toán học dựa trên CCS. ]
  4. Bạn có thể triển khai nó bằng JavaScript [xem bản demo trực tiếp tại đây. ]

Bạn đã bao giờ có một dự án mà bạn luôn trì hoãn sau này chưa?

Chà, vẽ một đường trong HTML mà không cần canvas là điều tôi nghĩ trong hơn một năm. Và cuối cùng tôi đã quyết định thực hiện hướng dẫn này về chủ đề

Nhân tiện, bạn có thể theo dõi tôi trên Twitter để biết thêm hướng dẫn về freemium

Hãy xem bản demo vẽ đường này đang hoạt động trực tiếp trên một trang mẫu mà tôi đã tạo

Trên đây là kết quả của thuật toán được giải thích trong hướng dẫn này. Một đường được vẽ giữa hai điểm trên màn hình raster điển hình. Trong trường hợp này, tôi đã sử dụng một lưới HTML đơn giản được tạo thành từ các phần tử DIV. Nó hơi chậm và không phù hợp để hiển thị đồ họa hiệu suất cao trong thời gian thực, nhưng nó thể hiện rõ ràng mục đích của thuật toán này

Làm thế nào một cái gì đó như thế này làm việc? . Với hai điểm cuối bất kỳ — chúng ta có thể hiển thị một đường trên màn hình raster

Trong trường hợp này, nó được biểu thị bằng một lưới HTML đơn giản được tạo từ các phần tử DIV

Làm thế nào nó hoạt động?

Các thuật toán là những con thú khó khăn

Đầu tiên, tốt nhất là hình dung bạn đang cố gắng đạt được điều gì

Thuật toán của Bresenham giải quyết vấn đề vẽ các đường trong Góc phần tư 1

Thuật toán này giải quyết việc vẽ đường cho Góc phần tư 1 trên Hệ tọa độ Descartes

Vẽ một đường theo bất kỳ hướng nào đòi hỏi phải suy nghĩ theo góc phần tư

Mặc dù thuật toán cho Góc phần tư 1 rất đơn giản — nhưng việc triển khai cho tất cả các góc phần tư [và quãng tám] lại rất phức tạp. Nhưng chỉ về mặt hậu cần. Các trường hợp còn lại là hình ảnh phản chiếu đơn giản của hai phần tám trong Góc phần tư 1

Điều này có nghĩa là thay vì phát minh lại bánh xe, tất cả những gì bạn phải làm là hoán đổi một số biến xung quanh hoặc lật dấu của chúng ở đây và ở đó

Vấn đề là - làm cách nào để chúng tôi viết mã đó bằng JavaScript?

Tại sao vẽ các dòng trong HTML mà không cần Canvas?

Nhiều lý do

Để cung cấp một lời giải thích rõ ràng về cách thức hoạt động của thuật toán vẽ Bresenham

Nhiều hướng dẫn vẽ đường thẳng của Bresenham mà tôi đã xem qua chỉ giải thích các dẫn xuất toán học. Nhưng họ không đi sâu vào chi tiết về mã cho từng octant hoặc triển khai thực tế bản demo. Nó chỉ giống như thực hiện một cái gì đó mà bạn không thực sự hiểu

Thật đơn giản — một số thứ chỉ là niềm vui. Ý tôi là, sẽ không tuyệt sao nếu vẽ các đường trong HTML mà không cần sử dụng canvas hoặc WebGL? . Bạn có thể sinh sản bao nhiêu tùy thích

Tôi đến từ một nền tảng phát triển trò chơi. Và trong các trò chơi, bạn thường xử lý các đường vẽ. Nhưng ngoài ra, tôi luôn thấy ý tưởng vẽ các đường trong HTML thật hấp dẫn. Có lẽ bởi vì tôi chưa bao giờ thấy nó được thực hiện trước đây

Tất nhiên, tốc độ kết xuất HTML thô sẽ là một vấn đề. Và vâng, sẽ cần tối ưu hóa thêm để đạt được hiệu suất có ý nghĩa. Nhưng trọng tâm của hướng dẫn vẽ đường này chủ yếu tập trung vào giải thích thuật toán vẽ đường. Bạn luôn có thể triển khai lại nó trong bất kỳ môi trường raster hoặc thư viện đồ họa nào khác

Triển khai thuật toán vẽ đường trong JS

Chúng tôi lấy hai đồng bằng và tính hệ số góc của phương trình đường thẳng, dựa trên hai điểm cuối của đường thẳng

Điểm đầu và điểm cuối của đường được cung cấp cho bốn tham số của hàm draw_line [tương ứng [x0, y0] và [x1, y1]]

Bạn có thể triển khai điều này bằng C, C++, Python, Java hoặc bất kỳ ngôn ngữ nào khác. Tất nhiên, trong hướng dẫn này, chúng tôi sẽ sử dụng JavaScript

Sau khi chúng tôi hiểu rõ về thuật toán một cách trực quan, đã đến lúc bắt đầu chuyển đổi logic thành mã

Đây là mã giả

draw_line[x0, y0, x1, y1]  // Calculate "deltas" of the line [difference between two ending points]
dx = x1 - x0
dy = y1 - y0
// Calculate the line equation based on deltas
D = [2 * dy] - dx
y = y0
// Draw the line based on arguments provided
for x from x0 to x1
// Draw pixel at this location
pixel[x, y]
// Progress the line drawing algorithm parameters
if D > 0
y = y + 1
D = D - 2*dx
end if
D = D + 2*dy

Chuyển đổi nó thành JavaScript, chúng tôi nhận được như sau

let draw_line = [x0, y0, x1, y1] => {    // Calculate "deltas" of the line [difference between two ending points]
let dx = x1 - x0;
let dy = y1 - y0;
// Calculate the line equation based on deltas
let D = [2 * dy] - dx;
let y = y0; // Draw the line based on arguments provided
for [let x = x0; x < x1; x++]
{
// Place pixel on the raster display
pixel[x, y];
if [D >= 0]
{
y = y + 1;
D = D - 2 * dx;
}
D = D + 2 * dy;
}
};

Lưu ý rằng tất cả điều này chỉ dành cho Góc phần tư 1

Giải thích logic thuật toán

Trước tiên, chúng tôi tính toán sự khác biệt giữa các điểm cuối của đường trên cả hai trục [dx và dy] thường được gọi là delta - tương ứng cho mỗi chiều trong hai chiều

Sau đó, chúng tôi tính toàn bộ delta của đường thẳng [ở đây được lưu trữ trong biến D] — bạn có thể coi nó như một phương trình toán học để vẽ một đường thẳng. Hay nói cách khác phương trình hệ số góc

Trước khi lặp qua từng khoảng của đường, hãy đặt lại bộ đếm trục y [mà chúng ta sẽ đi bằng vòng lặp for, khi đường đang được vẽ] bằng cách đặt nó về vị trí ban đầu trên đường. Ở đây y0 đề cập đến tọa độ Y của điểm đầu tiên trên đường thẳng

Cuối cùng, vẽ đường thẳng một "pixel" tại một thời điểm, bằng mã giả được hiển thị dưới dạng hàm pixel[x, y]. Sau khi pixel được hiển thị, chúng tôi có thể điều chỉnh vị trí pixel hiện tại bằng cách sử dụng các bước delta mà chúng tôi đã tính toán

Mỗi khi bộ đếm delta vượt quá 0, chúng tôi chuyển xuống pixel tiếp theo trên trục Y và điều chỉnh lại biến D nhưng ở chiều ngược lại, điều này kết thúc bằng việc vẽ dần dần đường trên cả hai chiều cho đến khi chúng tôi đi đến cuối đường

Nhưng đó không phải là tất cả. Ngoài ra, tùy thuộc vào sự thống trị của trục, vòng lặp for phải được sửa đổi để di chuyển theo hướng đó. Để hoàn thành thuật toán, chúng ta cũng phải điều chỉnh các tham số dựa trên octant [trong số tám] chúng ta đang ở. Điều này được giải thích chi tiết trong phần sau

Vẽ trong cả 4 góc phần tư / 8 Octants

Thuật toán đường thẳng của barebones Bresenham ở trên được thiết kế để chỉ vẽ một đường thẳng trong một góc phần tư [Góc phần tư 1] của hệ tọa độ Descartes. Nhưng chúng ta cần bao phủ tất cả các hướng. Rốt cuộc, một đường ngẫu nhiên có thể được vẽ từ bất kỳ điểm nào trên màn hình raster đến bất kỳ điểm nào khác

Điều này có nghĩa là ngoài mã giả ở trên, chúng ta cần quan tâm đến hai thứ khác

  • Thuật toán Quadrant-Aware. Thuật toán phải điều chỉnh các tham số của trình vòng lặp, cho mỗi trong số bốn góc phần tư. Chúng tôi có thể hoán đổi các điểm cuối của đường để đảm bảo rằng chúng tôi luôn vẽ đường từ trái sang phải và chia thuật toán thành hai phần chính [đường hướng lên hoặc hướng xuống từ điểm bắt đầu. ] Hoặc chúng ta có thể phân nhánh theo bốn trường hợp khác nhau, tương ứng cho từng góc phần tư và chỉ cần hoán đổi các trình vòng lặp trục x và trục y để phù hợp với hướng của đường
  • Axis-Dominance. Nhưng ngay cả trong mỗi góc phần tư, đường thẳng sẽ chiếm ưu thế trục x hoặc trục y. Điều này có nghĩa là thực sự không có bốn mà là tám trường hợp khác nhau. Một cho mỗi trong số tám quãng tám. May mắn thay, thuật toán vẫn giống hệt nhau, tất cả những gì chúng ta cần làm là chuyển đổi các vòng lặp và phân nhánh một vài lần

Đó là rất nhiều phân nhánh. Nhưng thuật toán được trình bày trong ví dụ sau sẽ xử lý tất cả các trường hợp có thể xảy ra

Thuật toán hoàn chỉnh của Bresenham trong JavaScript

Được rồi — tất cả những điều này nghe có vẻ tuyệt vời về mặt lý thuyết — và chúng tôi đã đề cập đến mã giả và phiên bản JavaScript — nhưng chỉ dành cho một góc phần tư. Hãy cùng xem toàn bộ enchilada

________số 8

Đây chỉ là một cách để viết thuật toán vẽ đường Bresenham. Bạn có thể tung hứng xung quanh các tham số và ứng biến khi phân nhánh. Nhưng ý tưởng cơ bản là có

Câu lệnh if chính phân nhánh giữa hai trường hợp chi phối trục tiềm năng

Mã nhận biết octant - trong hai phạm vi câu lệnh if, bạn cũng sẽ thấy rằng mã về cơ bản phản chiếu chính nó giữa trục X và Y [được theo dõi bởi các biến px và py] nhưng logic thuật toán thì khá giống nhau.

điểm ảnh[x, y]

Hãy nhớ rằng, chúng tôi không sử dụng canvas hoặc bất kỳ thư viện đồ họa nào khác khi viết các thuật toán đồ họa của riêng mình

Điều này có nghĩa là phương tiện thực tế mà bạn chọn để vẽ dữ liệu phụ thuộc hoàn toàn vào bạn. Trong bản demo này, tôi đã sử dụng lưới DIV cơ bản

Hàm pixel[x, y] này là cách bạn chọn để triển khai vẽ đường dựa trên loại màn hình raster bạn sẽ sử dụng

Về cơ bản, nó đặt một “pixel” tại vị trí X và Y trên “màn hình”/đầu ra kết xuất

Từ cuối cùng

Mọi người thường hỏi tôi cách cải thiện kỹ năng mã hóa của họ. Tôi thường khuyên bạn nên chọn một dự án cao hơn một chút so với khả năng hiện tại của bạn. Nếu bạn đảm bảo hoàn thành nó, trải nghiệm này sẽ giúp bạn nâng cao kỹ năng mã hóa của mình. Đối với tôi, đây là loại dự án

Làm cách nào để thêm một dòng trong js?

Ký tự xuống dòng là \n trong JavaScript và nhiều ngôn ngữ khác. Tất cả những gì bạn cần làm là thêm \n ký tự bất cứ khi nào bạn yêu cầu ngắt dòng để thêm một dòng mới vào một chuỗi.

Làm cách nào để vẽ các đường trong HTML?

Giải thích .
Đầu tiên, chúng ta tạo đường dẫn với beginPath
Ta đặt bút/con trỏ vẽ tại vị trí x , y x,y x,y = [50,50]
Sau đó, chúng ta sử dụng phương thức lineTo để vẽ một đường thẳng. Chúng tôi yêu cầu nó đánh dấu một dòng bắt đầu từ x , y x,y x,y = [50,50], được đặt bởi moveTo , thành x , y x,y x,y = [100,100]. định nghĩa bài văn

Làm cách nào để tạo một dòng trong Java?

Trong Windows, một dòng mới được biểu thị bằng cách sử dụng “\r\n”, đôi khi được gọi là Trả về dòng và Nguồn cấp dữ liệu hoặc CRLF. Việc thêm một dòng mới trong Java cũng đơn giản như bao gồm “\n”, “\r” hoặc “\r\n” ở cuối chuỗi của chúng tôi.

Làm cách nào để vẽ một điểm trong JavaScript?

arc[x, y, pointSize, 0, Math. PI * 2, true]; // Vẽ một điểm bằng chức năng cung của canvas có cấu trúc điểm. ctx. lấp đầy[]; . }

Chủ Đề