2017-12-16 6 views
0

無限の繰り返し線パターンを作成したいと思います。しかし、線は、線の端から水平方向および垂直方向の両方にオフセットされている。以下に示す説明図である。無限の並列パターンを作成する

Elemental Pattern

今は水平および垂直の両方の方向にオフセットし、このパターンを希望。パターンの使用方法は図2のようになります。

今は三角法を使って手作業で幅と高さの四角形の線を作成していますが、私は<pattern>をSVGに利用したいと思います。なし<pattern>レンダリングされたパターンのスケールを変更することは非常に困難です。

残念ながら、チュートリアルのオンラインまたはリファレンスのドキュメントからオフセットの繰り返しを行う方法が見つかりませんでした。私が試してみました何

をこれは私が、これまでのS指定された行の長さをやっていることで、Xオフセット、Yは

  1. をオフセット幅のボックスを作成し、有底の高さは、(として残さ0,0)
  2. 0,0からLへの最初の行を作成し、0
  3. (x、y)が境界をヒットしたら、0
  4. を2L + Sに対してL + S 0から別のラインを作成しますボックス - 停止

ここで、上方向にオフセットを伝播して(1,4)を繰り返します。オフセットの後で、ボックスの外にいる場合: - 非常に大きな線を描画します(ボックスと交差する場合):交点から描画を開始します。

2組のオフセットがボックスと交差しなくなるまで繰り返す。私はこのすべてをPythonで書き、<line>を作成しました。

残念ながら、私はこれをスケールすることはできませんし、サイズのパターンの変更で満たされた長方形を持つことはできません。私は簡単なパターンのために100sの線を描いています。ここで

は私のpythonのコードです:

def cosd(angle): 
    return np.cos(angle*np.pi/180.0) 

def sind(angle): 
    return np.sin(angle*np.pi/180.0) 


class pattern(): 
    def __init__(self, angle, x, y, x_offset, y_offset, dashes): 
     self.angle = angle 
     self.p = Point(x, y) 
     self.x_offset = x_offset 
     self.y_offset = y_offset 
     self.dashes = dashes 
     self.svg_lines = [] 

    # Check if the origins are in the box 
    def in_box(self, poly): 
     if poly.encloses_point(self.p) == False: 
      if len(intersection(self.p, poly)) < 1: 
       return False 
      else: 
       return True 
     else: 
      return True 

    def offset_me(self, direction='+'): 
     """ 
      x offset creates vector U in direction of angle of Length = x_offset 
      y offset creates vector V in direction perp of U with length of y_offset 
      Adding these two vector provides new offset location 
     """ 
     x1 = self.p[0] 
     y1 = self.p[1] 
     angle = self.angle 
     theta = 90 - angle 
     if direction == '-': 
      theta = -1*theta 
     x3 = x1 + cosd(angle)*self.x_offset + cosd(theta)*self.y_offset 
     y3 = y1 + sind(angle)*self.x_offset + sind(theta)*self.y_offset 
     self.p = Point(x3, y3) 
     print "Offsetting in " + direction 

    def draw_svg_line(self, p1, p2): 
     print Segment(p1, p2) 
     self.svg_lines.append(Segment(p1, p2)) 

    def clean_report_svg_lines(self,poly): 
     rep = self.svg_lines 
     result = [] 
     for item in rep: 
      if len(intersection(item,poly)) > 0 or poly.encloses_point(item.points[0]): 
       if item not in result: 
        result.append(item) 

     txt = [] 
     for item in result: 
      x1 = item.points[0][0] 
      y1 = item.points[0][1] 
      x2 = item.points[1][0] 
      y2 = item.points[1][1] 
      svg_str = '<line x1="{}" y1="{}" x2="{}" y2="{}" style="stroke:rgb(255,0,0);stroke-width:0.5" />'.format(x1,y1,x2,y2) 
      txt.append(svg_str) 

     return txt 

    def draw_all(self, poly): 

     # Draw in Positive Direction 
     starter_point = self.p.copy() 
     #self.draw_me(poly, direction='+') 
     while poly.encloses_point(self.p): 
      self.draw_me(poly, direction='+') 

     self.p = starter_point 
     starter_point = self.p.copy() 
     #self.draw_me(poly, direction='-') 
     while poly.encloses_point(self.p): 
      self.draw_me(poly, direction='-') 

    def draw_me(self, poly, direction='+'): 
     angle = self.angle 
     # Draw backwards 
     my_dash = self.dashes 
     if direction == '-': 
      my_dash.reverse() 

     for L in self.dashes: 
      abs_L = abs(L) 
      if L > 0: 
       if direction == '-': 
        x2 = self.p[0] - cosd(angle)*abs_L 
        y2 = self.p[1] - sind(angle)*abs_L 
       else: 
        x2 = self.p[0] + cosd(angle)*abs_L 
        y2 = self.p[1] + sind(angle)*abs_L 
       line = Segment(self.p, Point(x2,y2)) 
       inter = intersection(line, poly) 
       self.draw_svg_line(self.p,Point(x2,y2)) 
       self.p = Point(x2,y2) 
      elif L == 0: 
       pass 
      elif L < 0: 
       if direction == '-': 
        self.p = Point(self.p[0] - abs_L*cosd(angle), self.p[1] - abs_L*sind(angle)) 
       else: 
        self.p = Point(self.p[0] + abs_L*cosd(angle), self.p[1] + abs_L*sind(angle))  

    def print_me(self): 
     print self.p 
     print self.angle 

    def travel(self,p,L, direction='+'): 
     angle = self.angle 
     x2 = p[0] + cosd(angle)*L 
     y2 = p[1] + sind(angle)*L 
     if direction == '-': 
      x2 = p[0] - cosd(angle)*L 
      y2 = p[1] - sind(angle)*L 
     p2 = Point(x2,y2) 
     return p2 

    def get_starting_point(self, poly): 
     # Its already in box 
     if self.in_box(poly): 
      return True, self.p 

     length = sum([abs(x) for x in self.dashes]) 
     p2 = self.travel(self.p, length) 
     if poly.encloses_point(p2): 
      return True, p2 

     if intersection(Line(self.p, p2),poly): 
      # It has intersections but which way? 
      i = intersection(Line(self.p, p2),poly) 
      print type(i[0]) 
      if isinstance(i[0], sympy.geometry.point.Point2D): 
       i = Segment(i[0], i[1]) 
      else: 
       i = i[0] 
      p_midpoint = i.midpoint 
      print p_midpoint[0] 
      direction = '+' 
      if p_midpoint[0] - self.p[0] <= 0: 
       direction = '-' 
      # Now we know which way it is go back until we hit.... 
      while len(intersection(Segment(self.p, p2),poly)) < 1: 
       self.p = self.travel(self.p, length,direction) 
       p2 = self.travel(self.p, length,direction) 
      return True, p2 
     else: 
      return False, None 


    # Get origins to the box 
    def offset_draw(self, poly): 
     starting_p = self.p.copy() 
     possible, self.p = self.get_starting_point(poly) 
     self.draw_all(poly) 

     # Positive Draw 
     while possible: 
      self.draw_all(poly) 
      self.offset_me(direction='+') 
      possible, self.p = self.get_starting_point(poly) 

     self.p = starting_p 
     print self.p 
     self.offset_me(direction='-') 
     possible, self.p = self.get_starting_point(poly) 

     # Negetive Draw 
     while possible: 
      self.draw_all(poly) 
      self.offset_me(direction='-') 
      possible, self.p = self.get_starting_point(poly)   

私はSVGパターンタグに私のpythonコード(行要素)のペースト結果をコピー:あなたはこのd3をタグ付けされたので、私が想定し、 Codepen example

+1

私は私がこれまで試してみました何を編集します推測する... – pozza

+0

それは次のようになりこのウェブサイトで質の高い回答を得るには適切かつ適切な方法です。 –

+0

私は自分の試みを書きました – pozza

答えて

2

d3の答えは容認できますか?かかわらず、それはパターンを構築する方法を紹介しますとpythonに簡単に翻訳できる必要があります。

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
    </head> 
 

 
    <body> 
 
    <script> 
 
     
 
     var width = 1000, 
 
      height = 1000, 
 
      offsetX = 25, 
 
      offsetY = 25, 
 
      lineLength = 75, 
 
      strokeWidth = 3; 
 
     
 
     var svg = d3.select('body') 
 
     .append('svg') 
 
     .attr('width', width) 
 
     .attr('height', height); 
 
     
 
     var p = svg.append('pattern') 
 
     .attr('id', 'myPattern') 
 
     .attr('x', 0) 
 
     .attr('y', 0) 
 
     .attr('width', (offsetX + lineLength)/width) 
 
     .attr('height', (offsetY * 2)/height); 
 
     
 
     p.append("line") 
 
     .attr("x1", 0) 
 
     .attr("x2", lineLength) 
 
     .attr("y1", strokeWidth) 
 
     .attr("y2", strokeWidth) 
 
     .style("stroke-width", strokeWidth) 
 
     .style("stroke", "black"); 
 
     
 
     p.append("line") 
 
     .attr("x1", offsetX) 
 
     .attr("x2", lineLength + offsetX) 
 
     .attr("y1", offsetY + strokeWidth) 
 
     .attr("y2", offsetY + strokeWidth) 
 
     .style("stroke-width", strokeWidth) 
 
     .style("stroke", "black"); 
 
     
 
     p.append("circle") 
 
     .attr("cx", lineLength) 
 
     .attr("cy", strokeWidth) 
 
     .attr("r", strokeWidth); 
 
     
 
     p.append("circle") 
 
     .attr("cx", strokeWidth) 
 
     .attr("cy", strokeWidth) 
 
     .attr("r", strokeWidth); 
 
     
 
     p.append("circle") 
 
     .attr("cx", offsetX) 
 
     .attr("cy", offsetY + strokeWidth) 
 
     .attr("r", strokeWidth); 
 
     
 
     p.append("circle") 
 
     .attr("cx", lineLength + offsetX - strokeWidth) 
 
     .attr("cy", offsetY + strokeWidth) 
 
     .attr("r", strokeWidth); 
 
     
 
     svg.append("rect") 
 
     .attr("width", width) 
 
     .attr("height", height) 
 
     .attr("fill","url(#myPattern)"); 
 

 
    </script> 
 
    </body> 
 

 
</html>

関連する問題