2012-11-16 38 views
14

Tôi có một tập hợp các tọa độ mà tôi biến thành một đường dẫn svg (sử dụng các khối beziers để làm cho nó mịn). Khi tôi áp dụng một bề dày nét nhất định, tôi nhận được kết quả sau (các dấu chấm màu xanh là tọa độ của tôi) cubic svg path with stroke widthsvg: tạo ra 'đường viền phác thảo'

gì tôi quan tâm là để có được một con đường mà chạy xung quanh hình dạng màu xám (như: chọn bất kỳ điểm trên đường viền màu xám/trắng và xoay quanh hình dạng cho đến khi bạn quay lại điểm bắt đầu).

Tôi làm cách nào để tính toán đường dẫn như vậy?

để tham khảo, đây là thông tin svg của tôi:

<g> 
    <title>number 3</title> 
    <path d="m238,50c5.67569,-1.01351 11.8327,-3.8229 20.92029,-2.14724c8.68106,0.69732 14.21173,4.90255 18.07971,7.14724c6.23697,3.61945 13.47556,9.5931 15,18c1.07056,5.90372 1.17343,10.97649 -4,16c-6.76816,6.57204 -19.45392,9.57738 -25.69687,10.59046c-3.94836,0.64074 4.73492,3.29883 10.69687,5.40954c8.05417,2.85142 15,8 21,14c6,6 5.26578,10.94739 5.26578,17.03015c-2.4541,7.30975 -4.23343,11.08675 -11.26578,12.96985c-3.98279,1.0665 -11.92578,3.49756 -17,4c-8.95618,0.88684 -15.80411,2.97838 -26,0l-9.19197,-3.44464" id="svg_1" opacity="0.5" stroke-width="10" stroke-linejoin="round" stroke="#000000" fill="none"/> 
</g> 
+0

Đó là một điều khó khăn. Bạn cần phải làm điều đó theo lập trình hoặc bạn có thể sử dụng Illustrator hoặc Inkscape? – Duopixel

+0

Tôi cần làm điều này theo chương trình, nhưng nếu bạn có thể nói cách làm trong một chương trình, điều đó cũng hữu ích ... cảm ơn! – Hoff

+1

Trong Illustrator bạn chọn đường dẫn và menu Object> Expand appearance. Tôi chỉ có một ý tưởng mơ hồ về toán học đằng sau điều này, nhưng nó sẽ không phải là một nhiệm vụ đơn giản. – Duopixel

Trả lời

1

tôi tạo ra các svgContour chức năng đó là nghĩ cho các kịch bản tương tự như sau,
đường viền kết quả bù đắp không liên quan đến giá trị stroke-width và phải được thiết lập như là một tham số để hàm.

Hiện tại, nó sẽ tìm thấy một mặt bù tại một thời điểm, nhưng chạy một lần mỗi bên bạn có thể giải quyết vấn đề này.

TLDR
Trên thực tế thông qua svgContour bạn có thể tìm thấy đường viền của bất kỳ hình dạng svg, hiện nay nó không hỗ trợ chế độ fill-nhưng một trong những mục tiêu tiếp theo là thực hiện điều đó. nó dựa trên getPathData() để có được những pathData của bất kỳ SVGGeometryElement, sau đó dữ liệu này trải qua ba giai đoạn:

  • redrawSteepCurve
    Tiền đề: vẽ một đường song song Beizer-đường cong khác không thu được chỉ bù đắp các điểm/điểm kiểm soát của đường cong trừ khi đường cong đủ phẳng (trong trường hợp này hiển thị trực quan sẽ được sử dụng tốt); phương pháp này có một SVGPathData và trong trường hợp nó tìm thấy một đường cong dốc nó chia nó cho đến khi nó đủ phẳng (trả về một SVGPathData tương đương trực quan).

  • contourPathData
    Trong giai đoạn này các pathData được dissambled tại các điểm, các điểm được kết nối trong các phân đoạn, mỗi đoạn được offsetted, điểm giao nhau sau đó được tìm thấy cho mỗi đoạn tiếp giáp (những gì chúng ta nhận lại là một danh sách các điểm bù trừ).

  • DrawLine
    Giai đoạn này đặt điểm từ bước 2 trong pathData đến từ bước 1, và cuối cùng là thu hút các đường viền.

Một ví dụ:

const path = document.querySelector('path') 
 

 
svgContour(path, 5)
svg { 
 
    width: 100vw; 
 
    height: 100vh 
 
}
<script src="https://cdn.rawgit.com/fracalo/svg-contour/master/dist/svg-contour.js"></script> 
 

 
<svg viewBox='300 0 100 200'> 
 
    <g> 
 
    <title>number 3</title> 
 
    <path d="m238,50c5.67569,-1.01351 11.8327,-3.8229 20.92029,-2.14724c8.68106,0.69732 14.21173,4.90255 18.07971,7.14724c6.23697,3.61945 13.47556,9.5931 15,18c1.07056,5.90372 1.17343,10.97649 -4,16c-6.76816,6.57204 -19.45392,9.57738 -25.69687,10.59046c-3.94836,0.64074 4.73492,3.29883 10.69687,5.40954c8.05417,2.85142 15,8 21,14c6,6 5.26578,10.94739 5.26578,17.03015c-2.4541,7.30975 -4.23343,11.08675 -11.26578,12.96985c-3.98279,1.0665 -11.92578,3.49756 -17,4c-8.95618,0.88684 -15.80411,2.97838 -26,0l-9.19197,-3.44464" 
 
    id="svg_1" opacity="0.5" stroke-width="10" stroke-linejoin="round" stroke="#000000" fill="none" /> 
 
    </g> 
 
</svg>

đường viền được bắt nguồn từ!

+0

đó là tuyệt vời, cảm ơn! – Hoff

1

Tôi không chắc liệu điều này giải quyết vấn đề của bạn. Nó phụ thuộc vào những gì bạn muốn làm với đường viền phác thảo.

PostScript có chức năng tính toán đường viền cho đường nét vuốt ve, khi điền, sẽ tạo ra cùng một đầu ra hình ảnh như vuốt đường dẫn ban đầu. Tuy nhiên, dữ liệu đường dẫn kết quả có thể kém thanh lịch hơn bạn mong đợi.

Sau đây chương trình PostScript (chúng ta hãy gọi nó path2outlines.ps biến một con đường PostScript thành một "fillable" con đường SVG:.

%! 
% First, we're converting to outlines. 
strokepath 

% This is just a string buffer 
/S 99 string def 

% This defines a procedure for printing coordinates to stdout 
/printCoordinates {  % coord* number command 
    print     % coord* number 
    array astore   % array 
    {      % coord 
    ()print   % coord 
    //S cvs    % string 
    print    % 
    }forall 
    (\n)print 
} bind def 

% This iterates over the path segments and prints the SVG path data. 
{2(M) printCoordinates} 
{2(L) printCoordinates} 
{6(C) printCoordinates} 
{(Z\n)print} 
pathforall 

quit 

Bạn có để nuôi nó tập tin dữ liệu như thế này (% bắt đầu một bình luận) Hãy gọi này data.ps:

%! 
% First, set up the graphics state parameters 
% Equivalent to stroke-width="10" 
10 setlinewidth 

% Equivalent to stroke-linejoin="round" (0 = miter, 1 = round, 2 = bevel) 
1 setlinejoin 

% Now, we're defining the path. 
% Use postfix notation, i.e. first coordinates, then command. 
% m/M = moveto 
% l = rlineto 
% L = lineto 
% c = rcurveto 
% C = curveto 

238 50 moveto 
5.67569 -1.01351 11.8327 -3.8229 20.92029 -2.14724 rcurveto 
8.68106 0.69732 14.21173 4.90255 18.07971 7.14724 rcurveto 
6.23697 3.61945 13.47556 9.5931 15 18 rcurveto 
1.07056 5.90372 1.17343 10.97649 -4 16 rcurveto 
-6.76816 6.57204 -19.45392 9.57738 -25.69687 10.59046 rcurveto 
-3.94836 0.64074 4.73492 3.29883 10.69687 5.40954 rcurveto 
8.05417 2.85142 15 8 21 14 rcurveto 
6 6 5.26578 10.94739 5.26578 17.03015 rcurveto 
-2.4541 7.30975 -4.23343 11.08675 -11.26578 12.96985 rcurveto 
-3.98279 1.0665 -11.92578 3.49756 -17 4 rcurveto 
-8.95618 0.88684 -15.80411 2.97838 -26 0 rcurveto 
-9.19197 -3.44464 rlineto 

Tùy thuộc vào nền tảng mà bạn đang sử dụng, bạn có thể sử dụng Ghostscript để gọi nó hơi tương tự như:

gs -q data.ps path2outlines.ps > outlinePath.txt 

Hãy thử, nhưng tôi không chắc liệu bạn có hài lòng hay không. Độ phức tạp của đầu ra có thể gợi ý về độ phức tạp thực tế của vấn đề. Đặc biệt là con đường tự giao nhau là một vấn đề.

Chỉnh sửa (nói về các vấn đề): Tôi tin rằng về mặt toán học không thể tạo ra đường cong Bézier hoàn toàn "song song" với đường cong Bézier đã cho.

0

Điều này rất khắt khe. Thành thật mà nói tôi nghi ngờ rằng bạn sẽ có thể viết một mã sorce mà sẽ làm điều đó, không có một lib sẽ làm điều đó cho bạn.

Kỹ thuật này đôi khi được gọi là "bộ đệm". Giống như tạo một bộ đệm xung quanh một đối tượng.

Nếu bạn có thể sử dụng Lập trình lang C thì bạn nên xem thư viện LEDA. Trong java tôi không biết bất cứ điều gì, có thể là lib GeoTools.

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