2014-02-19 127 views
5

我一直在想一個優雅的算法來繪製這與SVG,它逃避我。如何在SVG中繪製此形狀?

拉絲剛好線框是相當容易的。它只是從每個角落到其右側的邊緣,目標點間距相等。但填充它們更棘手 - 我需要實際的多邊形座標來繪製填充的形狀......不是嗎?

一種方式是解決一切段路口有位數學的。這會給我所有交叉點的座標,但是我怎麼知道如何對四個座標進行組合,並且還要跟蹤要填充哪些座標?

回答

5

你的圖片可以在4個相等部分,分別是點對稱的,除了黑色和白色瓷磚的交換被劃分。爲了計算底部象限,例如,您遍歷在左下角(x1, y1)開始,所有的線路,走向右邊緣(x2, y2),然後遍歷能夠從左上角(x3, y3)去實現底部邊緣都行(x4, y4),計算交點並將其保存在矩陣PxPy中。我懶得做數學,所以我只是輸入了line intersections的公式。最後,如果指數ixiy的和爲奇數,則迭代矩陣並繪製相鄰點之間的斑點。

示例使用Python/matplotlib:

from __future__ import division 
import matplotlib.pyplot as plt 
import numpy as np 

def intersect(x1, y1, x2, y2, x3, y3, x4, y4): 
    det = (x1-x2)*(y3-y4) - (y1-y2)*(x3-x4) 
    px = ((x1*y2-y1*x2)*(x3-x4) - (x1-x2)*(x3*y4-y3*x4))/det 
    py = ((x1*y2-y1*x2)*(y3-y4) - (y1-y2)*(x3*y4-y3*x4))/det 
    return px, py 

n = 10 
Px = np.zeros((n+1, n+1)) 
Py = np.zeros((n+1, n+1)) 

x1, y1 = 0, 0 
x2 = 1 
x3, y3 = 0, 1 
y4 = 0 
for ix in range(n+1): # index left to right along bottom 
    x4 = ix/n 
    for iy in range(n+1): # index bottom to top along right side 
     y2 = iy/n 
     px, py = intersect(x1, y1, x2, y2, x3, y3, x4, y4) 
     plt.plot([x1,x2], [y1,y2], 'k') 
     plt.plot([x3,x4], [y3,y4], 'k') 
     plt.plot(px, py, '.r', markersize=10, zorder=3) 
     Px[ix, iy] = px 
     Py[ix, iy] = py 

for ix in range(n): 
    for iy in range(n): 
     if (ix + iy) % 2: # only plot if sum is odd 
      xy = [[Px[ix, iy], Py[ix, iy]], # rectangle of neighboring points 
        [Px[ix, iy+1], Py[ix, iy+1]], 
        [Px[ix+1, iy+1], Py[ix+1, iy+1]], 
        [Px[ix+1, iy], Py[ix+1, iy]]] 
      poly = plt.Polygon(xy,facecolor='gray',edgecolor='none') 
      plt.gca().add_patch(poly) 
plt.show() 

此代碼可能會被優化的多一點,但像他這樣應該比較清楚它做什麼。

結果: pattern 將其擴展到所有4個象限,並將其作爲SVG文件編寫爲練習讀者:)。

+0

這是不完全正確的棱角並沒有相互連接。它們略微扭曲,圖像中央有一個黑色的「正方形」。 :) –

+0

是的,我只是發現,當我做了我的陰謀後,更詳細地研究問題中的圖像。看起來OP沒有畫出完全連接對角的線條,而我卻這麼做。在他的情況下,圖像具有精確的點對稱性。所以要重現他的形象,拿我的形象,交換黑色和白色(在中心黑色),只是做複製和旋轉。這樣,正方形的中央帶看起來具有雙倍寬度(我不喜歡美學)。我寧願拍攝我的圖像,調換顏色,旋轉90度並粘貼。這將在中心的4個瓷磚之間放置一個角落。 –

0

可能的解決辦法:

我們可以觀察每個黑色填充單元爲兩個三角形的交集。三角形從每個角落扇出。所以如果我們有一個函數來計算兩個三角形相交的多邊形,我們需要做的就是遍歷所有三角形(實際上相交)的所有交點。然後,決定是否將三角形着色爲黑色,這基本上是一種奇偶校驗。因此,如果我們有四條邊:A,B,C,D和N三角形從每邊扇出,則如果j * k是奇數,則Aj和Bk的交點應該是黑色的。