File:Osgood curve.svg

Original file (SVG file, nominally 469 × 249 pixels, file size: 6 KB)

Summary

Description
English: Fractal construction of an Osgood curve, a non-self-intersecting curve with nonzero area. It is formed from an initial triangle by removing a wedge connecting the apex of the triangle to the opposite side, and then doing the same thing recursively to the smaller triangles formed by this removal. At each level of the recursion, the removed wedges grow narrower, so that the amount of area removed in each level decreases exponentially, leaving a nonzero amount of area that is never removed.
Русский: Фрактальное построение кривой Осгуда – несамопересекающейся кривой ненулевой площади. Формируется из исходного треугольника на первой рекурсии путем удаления симметричного клина, соединяющего вершину треугольника с противоположной стороной, а затем рекурсивного выполнения того же действия с меньшими образующимися треугольниками. На каждой рекурсии удаленные клинья становятся уже и короче, так что количество удаленной площади на каждом уровне уменьшается экспоненциально, поэтому сумма площадей клиньев конечна, при этом от исходного треугольника остаётся неудаляемая ненулевая площадь.
Date
Source Own work
Author David Eppstein

Licensing

I, the copyright holder of this work, hereby publish it under the following license:
Creative Commons CC-Zero This file is made available under the Creative Commons CC0 1.0 Universal Public Domain Dedication.
The person who associated a work with this deed has dedicated the work to the public domain by waiving all of their rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.

Python source code

import sys from PADS.SVG import SVG,colors  size = 500 margin = 10  triangles = [(1j,1,2+1j)]  def subdivide(triangles,fraction):     x = 0.5*(1-fraction)     for (p,q,r) in triangles:         yield (p,(1-x)*p+x*r,q)         yield (q,x*p+(1-x)*r,r)  for i in range(13):     fraction = 1./(7*1.2**i)     triangles = list(subdivide(triangles,fraction))  svg = SVG(size+(size+2*margin)*(1+1j),sys.stdout)  svg.group(style={"stroke":colors.black, "fill":colors.blue}) shift = margin*(1+1j) for T in triangles:     points = [p*size+shift for p in T]     svg.polygon(points) svg.ungroup()  svg.close() 


# The SVG library  # from http://www.ics.uci.edu/~eppstein/PADS/SVG.py # by David Eppstein  # http://www.ics.uci.edu/~eppstein/ """SVG.py  Simple generation of SVG-format vector graphics files  D. Eppstein, November 2011. """  def _coord(x):     """String representation for coordinate"""     return ("%.4f" % x).rstrip("0").rstrip(".")  class SVG:     def __init__(self, bbox, stream,                standalone=True, prefix=None, indentation=0):         """Create a new SVG object, to be written to the given stream.         If standalone is True or omitted, the SVG object becomes a whole         XML file; otherwise, it becomes an XML object within a larger XML         file. If the prefix is nonempty, it is used to distinguish svg tags         from other tags; a reasonable choice for the prefix value would be         "s" or "svg". If the indentation is nonzero, it gives a number of         spaces by which every line of the file is indented.                  The bbox argument should be a complex number, the farthest visible         point from the origin in the positive quadrant. The bounding box         will become the rectangle between the origin and that point.         All other methods that specify points should do so using         complex number coordinates."""         self.stream = stream         if prefix:             self.prefix = prefix + ":"         else:             self.prefix = ""         if standalone:             self.stream.write('''<?xml version="1.0"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> ''')         self.indentation = indentation         self.nesting = 0         br = _coord(bbox.real)         bi = _coord(bbox.imag)         self.element('''svg width="%s" height="%s" viewBox="0 0 %s %s"      xmlns="http://www.w3.org/2000/svg" version="1.1"''' % (br,bi,br,bi),+1)      def close(self):         """Output the end of an SVG file."""         self.element("svg", -1)         if self.nesting:             raise Exception("SVG: Unclosed tags")      def element(self, e, delta=0, unspaced=False, style={}, **morestyle):         """Output an SVG element.         The delta argument distinguishes between XML tags that         open a nested section of the XML file (delta=+1), XML tags         that close the same section (delta=-1), and XML tags that         stand alone without anything nested inside them (delta=0).         Every call with delta=+1 must be matched by a call with delta=-1.         If the style argument is nonempty, it should be a dictionary         of style parameters, included within the object; these         may also be passed as keyword arguments to element.         If the same keyword is present both in style and as a keyword         argument, the keyword argument takes priority."""         if delta < 0:             self.nesting += delta         if delta >= 0 or not unspaced:             output = [" " * (self.indentation + 2*self.nesting), "<"]         else:             output = ["<"]         if delta < 0:             output.append("/")         output += [self.prefix, e]         style = dict(style)         style.update(morestyle)         if style:             output.append(' style="')             second = False             for keyword in style:                 if second:                     output.append("; ")                 second = True                 output += [keyword, ":", style[keyword]]             output.append('"')         if delta > 0:             self.nesting += delta         elif delta == 0:             output.append("/")         output.append(">")         if delta <= 0 or not unspaced:             output.append("\n")         self.stream.write("".join(output))      def group(self,style={},**morestyle):         """Start a group of objects, all with the same style"""         self.element("g", +1, style=style, **morestyle)      def ungroup(self):         """End a group of objects"""         self.element("g", -1)      def circle(self, center, radius, style={}, **morestyle):         """Circle with given center and radius"""         self.element('circle cx="%s" cy="%s" r="%s"' %                 (_coord(center.real), _coord(center.imag), _coord(radius)),             style=style, **morestyle)      def rectangle(self, p, q, style={}, **morestyle):         """Rectangle with corners at points p and q"""         x = min(p.real,q.real)         y = min(p.imag,q.imag)         width = abs((p-q).real)         height = abs((p-q).imag)         self.element('rect x="%s" y="%s" width="%s" height="%s"' %                 (_coord(x), _coord(x), _coord(width), _coord(height)),             style=style, **morestyle)      def polygon(self, points, style={}, **morestyle):         """Polygon with corners at the given set of points"""         pointlist = " ".join(_coord(p.real)+","+_coord(p.imag) for p in points)         self.element('polygon points="%s"' % pointlist,                      style=style, **morestyle)      def segment(self, p, q, style={}, **morestyle):         """Line segment from p to q"""         self.element('line x1="%s" y1="%s" x2="%s" y2="%s"' %                       (_coord(p.real), _coord(p.imag),                       _coord(q.real), _coord(q.imag)), style=style, **morestyle)      def arc(self, p, q, r, large=False, style={}, **morestyle):         """Circular arc from p to q with radius r.         If the large flag is set true, the arc will cover more than         half of a circle. The SVG "sweep-flag" is not provided;         instead, to achieve the same effect, swap p and q."""         if large:             large = "1"         else:             large = "0"         r = _coord(abs(r))         self.element('path d="M %s,%s A %s,%s 0 %s 0 %s,%s"' %                      (_coord(p.real),_coord(p.imag),r,r,large,                       _coord(q.real),_coord(q.imag)), style=style, **morestyle)      def text(self, label, location, style={}, **morestyle):         """Text label at the given location.         Caller is responsible for making the label xml-safe."""         self.element('text x="%s" y="%s"' %             (_coord(location.real),_coord(location.imag)),             delta=1, unspaced=True, style=style, **morestyle)         self.stream.write(label)         self.element('text', delta=-1, unspaced=True)  # A small color palette chosen to have high contrast # even when viewed by color-blind readers class colors:     none = "none"     white = "#FFFFFF"     black = "#000000"     red = "#BC1E46"     blue = "#0081CD"     green = "#009246"     yellow = "#FEC200"     magenta = "#CC33CC" 

Captions

Add a one-line explanation of what this file represents

Items portrayed in this file

depicts

12 December 2015

6,130 byte

249 pixel

469 pixel

image/svg+xml

946dec723f7a8af203df0633aaa460c4aa6efbf8

File history

Click on a date/time to view the file as it appeared at that time.

Date/TimeThumbnailDimensionsUserComment
current09:57, 8 September 2024Thumbnail for version as of 09:57, 8 September 2024469 × 249 (6 KB)Д.ИльинOptimization
05:22, 13 December 2015Thumbnail for version as of 05:22, 13 December 20151,020 × 520 (615 KB)David EppsteinUser created page with UploadWizard

The following 3 pages use this file:

Global file usage

The following other wikis use this file:

Metadata