我一直在想一个优雅的算法来绘制这与SVG,它逃避我。如何在SVG中绘制此形状?
拉丝刚好线框是相当容易的。它只是从每个角落到其右侧的边缘,目标点间距相等。但填充它们更棘手 - 我需要实际的多边形坐标来绘制填充的形状......不是吗?
一种方式是解决一切段路口有位数学的。这会给我所有交叉点的坐标,但是我怎么知道如何对四个坐标进行组合,并且还要跟踪要填充哪些坐标?
我一直在想一个优雅的算法来绘制这与SVG,它逃避我。如何在SVG中绘制此形状?
拉丝刚好线框是相当容易的。它只是从每个角落到其右侧的边缘,目标点间距相等。但填充它们更棘手 - 我需要实际的多边形坐标来绘制填充的形状......不是吗?
一种方式是解决一切段路口有位数学的。这会给我所有交叉点的坐标,但是我怎么知道如何对四个坐标进行组合,并且还要跟踪要填充哪些坐标?
你的图片可以在4个相等部分,分别是点对称的,除了黑色和白色瓷砖的交换被划分。为了计算底部象限,例如,您遍历在左下角(x1, y1)
开始,所有的线路,走向右边缘(x2, y2)
,然后遍历能够从左上角(x3, y3)
去实现底部边缘都行(x4, y4)
,计算交点并将其保存在矩阵Px
和Py
中。我懒得做数学,所以我只是输入了line intersections的公式。最后,如果指数ix
和iy
的和为奇数,则迭代矩阵并绘制相邻点之间的斑点。
示例使用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()
此代码可能会被优化的多一点,但像他这样应该比较清楚它做什么。
结果: 将其扩展到所有4个象限,并将其作为SVG文件编写为练习读者:)。
可能的解决办法:
我们可以观察每个黑色填充单元为两个三角形的交集。三角形从每个角落扇出。所以如果我们有一个函数来计算两个三角形相交的多边形,我们需要做的就是遍历所有三角形(实际上相交)的所有交点。然后,决定是否将三角形着色为黑色,这基本上是一种奇偶校验。因此,如果我们有四条边:A,B,C,D和N三角形从每边扇出,则如果j * k是奇数,则Aj和Bk的交点应该是黑色的。
这是不完全正确的棱角并没有相互连接。它们略微扭曲,图像中央有一个黑色的“正方形”。 :) –
是的,我只是发现,当我做了我的阴谋后,更详细地研究问题中的图像。看起来OP没有画出完全连接对角的线条,而我却这么做。在他的情况下,图像具有精确的点对称性。所以要重现他的形象,拿我的形象,交换黑色和白色(在中心黑色),只是做复制和旋转。这样,正方形的中央带看起来具有双倍宽度(我不喜欢美学)。我宁愿拍摄我的图像,调换颜色,旋转90度并粘贴。这将在中心的4个瓷砖之间放置一个角落。 –