2011-01-12 38 views
5

Hãy nói rằng tôi có một con đường Bezier khối như sau (định dạng để sử dụng với các chức năng đường Raphael):Vẽ nửa của một con đường Bezier trong Raphael

M55 246S55 247 55 248

Chỉ cần một ví dụ. Điều này được lấy từ ứng dụng vẽ của tôi, nơi tôi sử dụng con trỏ để vẽ một đường khi người dùng giữ nút chuột xuống, giống như bút chì hoặc điểm đánh dấu. Tôi đang sử dụng sự kiện mousemove của jquery để vẽ đường giữa hai điểm mỗi khi người dùng di chuyển chuột. Có một điểm khác (điểm tham chiếu) được lấy trước khi đường thẳng được vẽ, để có thể tạo đường cong Bezier.

Đây là câu hỏi của tôi: có thể làm cho Raphael chỉ vẽ một nửa của một con đường nhất định không? Tôi biết về hàm getSubpath(), nhưng nếu sự hiểu biết của tôi về các đường cong Bezier là chính xác, thì sẽ rất khó để tính toán đối số thứ hai. Vấn đề với chức năng animate là nó tạo ra các đường đôi (tức là, nó tạo ra đường cong mà tôi muốn, và đường bao quanh nó không được hiển thị, có thể vì chuột đang được di chuyển nhanh hơn hình động có thể xử lý).

Tất nhiên, nếu cách tiếp cận của bản thân tôi bị thiếu sót theo một cách nào đó (hoặc sự hiểu biết của tôi về các giải pháp khả thi), tôi muốn nghe nó. Bất kỳ trợ giúp sẽ được đánh giá cao.

+0

Bạn có ý nghĩa gì bởi "một nửa"? Bạn muốn vẽ một nửa nào? – Gabe

+0

Tôi muốn vẽ nửa đầu (từ khi bắt đầu di chuyển chuột đến điểm giữa của đường cong Bezier). Lý giải cho điều này là để loại bỏ các cạnh luôn luôn xuất hiện nếu bạn chỉ cần vẽ các đường từ một vị trí con trỏ sang vị trí con trỏ tiếp theo. – Fibericon

Trả lời

3

Nó là một chút lộn xộn, nhưng có lẽ điều này sẽ trả lời nó:

line[line.length] = paper.path(drawPath); //drawPath being the fill line length 

//get a subpath, being half the length of your bezier curve 
subPath = line[line.length - 1].getSubpath(0, line[line.length - 1].getTotalLength()/2); 

//remove the full-length bezier curve 
line[line.length - 1].remove(); 

//Draw your new line 
line[line.length - 1] = paper.path(subpath); 

Thành thực mà nói, này này khá hiệu quả. Nhưng, tôi không thể nghĩ ra một cách tốt hơn để đi về nó. Bạn không thể chỉ lấy các tiếp tuyến và chia một nửa, vì một đường cong bezier sẽ dài hơn chiều dài của một đường tiếp tuyến (như một con quạ bay). Điều này có nghĩa rằng bạn phải xử lý dòng thông qua rapheal và sau đó nhận được một subPath của một nửa chiều dài.

+0

Đó sẽ là nó! Nó thực sự là chậm hơn, nhưng không có gì để được thực hiện về điều đó tôi giả sử. – Fibericon

+1

Giải pháp thích hợp sẽ là để thiết lập lại phương trình cho đường cong khối bezier như hàm t' = 2t: http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B.C3.A9zier_curves – fuzzyTew

+0

Điều đó thực sự là thật. Bạn có nhớ bao gồm ở đâu và làm thế nào để làm điều đó trong Rapheal. – Beaker

1

Điểm giữa có thể được tính toán, không biết về bất kỳ chức năng nào trong Raphael sẽ làm giảm một nửa số bezier cho bạn.

Từ vẻ của những lệnh, nó đánh dấu SVG tiêu chuẩn (xem spec SVG để hiểu nó tốt hơn: http://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands)

M => MoveTo vị trí tuyệt đối 55,24 S => mượt đường cong đến tuyệt đối 55,247 55,248

Đường cong trơn có thể được viết lại dưới dạng CurveTo hoặc C chuẩn nếu bạn muốn, S chỉ là viết tắt của nó và curveto/C bạn có thể dễ dàng tính điểm trung tâm.

+0

Tôi đã thử nghiệm điều này, nhưng việc sử dụng CurveTo dường như làm cho vấn đề đường đôi trở nên tồi tệ hơn. – Fibericon

+0

Bạn có ảnh chụp màn hình của đường đôi mà bạn đang nhận được không? –

-1

Chia đường cong bezier thành một nửa chỉ là một chút toán, không có gì quá khó. Bạn có thể được giúp đỡ bởi các path extensions for raphaël, và nó sẽ được khá đơn giản để thêm một phương pháp có để làm việc tách.

Phần "chỉ một chút về toán" có thể, ví dụ: sử dụng De Castelau's algorithm để tách đường cong tại bất kỳ điểm đã cho nào.

+1

'Chia một đường cong bezier thành một nửa chỉ là một chút toán, không có gì quá khó.' Tôi nghĩ câu hỏi của anh xoay quanh chuyện này và không có gì quá khó trả lời. Có lẽ bạn có thể cụ thể hơn? – Beaker

Các vấn đề liên quan