Catenary_animation.gif(150 × 80 piksler, filstørrelse: 75 KB, MIME-type: image/gif, gjentas, 90 rammer, 5,1 s)


Wikimedia Commons' logo

Beskrivelse

Beskrivelse
English: Animation of a catenary curve for different seperations of the endpoints.
Dato
Kilde

Eget verk

see sourcecode below
Opphavsperson Geek3

Source Code

The image is created by the following source-code. Requirements:

python source code:

#!/usr/bin/python
# -*- coding: utf8 -*-

from lxml import etree
import os
import scipy as sc
import scipy.optimize as op
import scipy.integrate as ig
from math import *

class SvgDocument:
    '''
    creates a svg document structure using lxml.etree
    '''
    def __init__ (self, name, width=800, height=600, bgcolor='#ffffff',
        center=None, unit=1.0):
        self.name = name
        self.width = int(width)
        self.height = int(height)
        self.unit = float(unit)
        if center == None: self.center = [width / 2., height / 2.]
        else: self.center = [float(i) for i in center]
        
        # create document structure
        self.svg = etree.Element('svg',
            nsmap={None:'http://www.w3.org/2000/svg',
            'xlink':'http://www.w3.org/1999/xlink'})
        self.svg.set('version', '1.1')
        self.svg.set('baseProfile', 'full')
        self.svg.set('width', str(int(width)))
        self.svg.set('height', str(int(height)))
        
        # title
        self.title = etree.SubElement(self.svg, 'title')
        self.title.text = self.name
        
        # background
        if bgcolor != None: 
            self.background = etree.SubElement(self.svg, 'rect')
            self.background.set('id', 'background')
            self.background.set('x', '0')
            self.background.set('y', '0')
            self.background.set('width', str(width))
            self.background.set('height', str(height))
            self.background.set('fill', bgcolor)
        
        # image elements
        self.content = etree.SubElement(self.svg, 'g')
        self.content.set('id', 'image')
        self.content.set('transform',
            'translate({0},{1}) scale({2},-{2})'.format(
            self.center[0], self.center[1], self.unit))
    
    def draw_object(self, name, params, group=None):
        '''
        Draw arbitraty svg object.
        Params must be a dictionary of valid svg parameters.
        '''
        if group == None:
            obj = etree.SubElement(self.content, name)
        else:
            obj = etree.SubElement(group, name)
        for i, j in params.iteritems():
            obj.set(str(i), str(j))
        return obj
    
    
    def write(self, filename=None):
        # write content to file
        if filename == None: filename = self.name
        outfile = open(filename + '.svg', 'w')
        outfile.write(etree.tostring(self.svg, xml_declaration=True,
            pretty_print=True, encoding='utf-8'))
        outfile.close()
        print 'image written to', filename + '.svg'

# physics: calculate the catenary curve
def catenary(x, r):
    # catenary curve f(x) with l=2 and horizontal distance 2r
    if r == 1.0:
        return 0.0
    # search a-value for given length and distance
    def fct(a):
        if a == 0.0: return r - 1.0
        return sinh(r * a) / a - 1.0
    x0 = 1.0
    while fct(x0) > 0.0: x0 /= 2.0
    while fct(2.0 * x0) < 0.0: x0 *= 2.0
    a = 1.0 / op.brentq(fct, x0, 2*x0)
    return a * (cosh(x / a) - cosh(r / a))

render_mult = 8 # supersampling to improve quality
folder = 'frames'
commands = ['mkdir ' + folder]
for c in commands: print c; os.system(c)

# render frames
frames = 100
names = []
for i in range(frames):
    name = 'catenary_{0:0>2}'.format(i)
    names.append(name)
    w, h = 150, 80
    r0 = 65.0
    doc = SvgDocument(name, width=w, height=h, center=[w/2, 10], unit=1)
    a = 0.5 + 0.5 * cos(i * 2*pi / frames)
    r = a**1.5 + 12*a**2 - 21*a**2.5 + 9*a**3
    for ri in [-r, r]:
        doc.draw_object('circle', {'cx':str(ri*r0), 'cy':'0', 'r':'7',
            'style':'fill:#888; stroke:none'})
    
    if r != 0.0:
        x = sc.linspace(-r, r, 401)
        path_data = zip(r0 * x, [r0 * catenary(xx, r) for xx in x])
    else:
        path_data = [[0.0, 0.0], [0.0, -r0], [0.0, 0.0]]
    
    # append extra segment to have last point displayed
    v = sc.array(path_data[-1]) - sc.array(path_data[-2])
    v *= 0.1 / r0 / sqrt(v[0]**2 + v[1]**2)
    path_data.append(sc.array(path_data[-1]) + v)
    
    path = 'M ' + ' L '.join([str(xy[0]) + ',' + str(xy[1]) for xy in path_data])
    doc.draw_object('path', {'d':path, 'stroke-linecap':'round',
        'style':'fill:none; stroke:black; stroke-width:4',
        'stroke-linejoin':'round', 'stroke-dasharray':'0,5'})
    
    doc.write(filename=folder + '/' + name)

for name in names:
    commands = ['rsvg -w{0} -h{1} {3}/{2}.svg {3}/{2}.png'.format(
            w * render_mult, h * render_mult, name, folder),
        'rm {1}/{0}.svg'.format(name, folder),
        'convert -scale {0}x{1} {3}/{2}.png {3}/{2}.gif'.format(
            w, h, name, folder),
        'rm {1}/{0}.png'.format(name, folder)]
    for c in commands: print c; os.system(c)

commands = ['gifsicle -d5 -l0 --colors 256 '
    + folder + '/*.gif > catenary_animation.gif',
    'rm -rf ' + folder]
for c in commands: print c; os.system(c)

Lisensiering

Jeg, rettighetsinnehaver av dette arbeidet, publiserer det herved under følgende lisenser:
GNU head Det tillates at dette dokumentet kopieres, distribueres og/eller modifiseres under retningslinjene som beskrevet i GNU fri dokumentasjonslisens, versjon 1.2 eller senere utgave utgitt av Free Software Foundation; med alle seksjoner, uten noen forsidetekster og baksidetekster. En kopi av lisensen er inkludert i avsnittet GNU Free Documentation License.
w:no:Creative Commons
navngivelse del på samme vilkår
Denne filen er lisensiert under lisensen Creative Commons Navngivelse-DelPåSammeVilkår 3.0 Unported
Du står fritt:
  • til å dele – til å kopiere, distribuere og overføre verket
  • til å blande – til å endre verket
Under de følgende betingelsene:
  • navngivelse – Du må kreditere verket på passende vis, lenke til lisensen og indikere hvorvidt det har blitt gjort endringer. Du kan gjøre det på enhver rimelig måte, men ikke på en måte som antyder at lisensgiveren støtter deg eller din bruk av verket.
  • del på samme vilkår – Dersom du remikser, omarbeider eller på annen måte bygger på dette verket, må du kun distribuere resultatet under den samme eller en samsvarende lisens som denne.
Du kan velge lisens etter eget valg.

Bildetekster

Legg til en kort forklaring på hva filen representerer

Elementer som er med i denne fila

motiv

image/gif

c58f33fb2dba9864f699017027d46ad4c67095b6

77 108 byte

5,099999999999992 sekund

80 piksel

150 piksel

Filhistorikk

Klikk på et tidspunkt for å vise filen slik den var på det tidspunktet.

Dato/klokkeslettMiniatyrbildeDimensjonerBrukerKommentar
nåværende11. aug. 2014 kl. 12:26Miniatyrbilde av versjonen fra 11. aug. 2014 kl. 12:26150 × 80 (75 KB)Ev9nBackground converted to transparent.
16. okt. 2010 kl. 21:27Miniatyrbilde av versjonen fra 16. okt. 2010 kl. 21:27150 × 80 (81 KB)Geek3own work

Den følgende siden bruker denne filen:

Global filbruk

Følgende andre wikier bruker denne filen:

Metadata