PROG0047 - Racetrack Playa

no tags 

Racetrack Playa is een schilderachtig opgedroogd meer in Death Valley National Park (Californië, VSA). Dit uitzonderlijk vlak en horizontaal meer ligt op 1130 m boven de zeespiegel en is aan de noordkant slechts 4 cm hoger dan aan de zuidkant. Tijdens perioden van zware regenval vloeit water uit de bergen naar Racetrack Playa, waar het kortstondig een ondiep meer vormt. De hete woestijnzon doet het dunne laagje water snel verdampen, waardoor een zachte gladde modderlaag overblijft. Bij het opdrogen krimpt en scheurt de modder tot een mozaïekpatroon van aaneengesloten veelhoeken.

Het meer is vooral bekend omwille van een mysterieus geologisch fenomeen van "zeilende rotsblokken" die bewegen zonder interventie van mensen of dieren en daarbij lange sporen in de zachte grond achterlaten. Rotsblokken met een ruwe onderkant laten rechte gegroefde sporen na, terwijl rotsen met een platte onderkant de neiging hebben om af te dwalen. Soms kantelen de rotsblokken en komen daarbij met een andere zijde op de grond te liggen, waardoor ze plots een ander spoor achterlaten. De sporen verschillen zowel in richting als in lengte. Rotsblokken die in elkaars buurt liggen, kunnen bijvoorbeeld eerst een tijdje parallel bewegen en daarna plotseling naar links of naar rechts uitwijken, of zelfs rechtsomkeer maken.

sailing stone
Een zeilend rotsblok in Racetrack Playa.

De sporen werden voor het eerst waargenomen en bestudeerd aan het begin van de twintigste eeuw. Daaruit bleek onder andere dat de rotsblokken eens om de twee à drie jaar bewegen en dat hun sporen doorgaans drie à vier jaar zichtbaar blijven. Er zijn in de loop der jaren heel wat uiteenlopende theorieën aangebracht om het bewegen van de rotsblokken te verklaren. Zo dacht men bijvoorbeeld dat de rotsblokken voortgedreven werden door sterke winterwinden (tot 145 kilometer per uur), door drijvende ijsschotsen die zich aan het wateroppervlak vormen of door ijskragen die rond de stenen groeien en als een soort parachute fungeren.

Tijdens de winter van 2013-2014 slaagden geologen van het Scripps Institute of Oceanography er uiteindelijk in om de bewegingen van de rotsblokken te registeren met behulp van GPS en time-lapse-fotografie. Op 20 december 2013 konden ze minstens 60 bewegende rotsblokken waarnemen, waarvan sommige zich tussen december 2013 en januari 2014 tot 224 meter verplaatsten in verschillende fasen. Hun studie weerlegde eerdere hypothesen die de bewegingen toeschreven aan de wind of aan dikke ijslagen die rotsen voortstuwen. In plaats daarvan stelden ze vast dat de rotsblokken bewegen wanneer een ijslaag van slechts een paar milimeter dik begint te smelten tijdens perioden met lichte wind. Als deze flinterdunne ijsvliezen over het smeltwater schuiven, kunnen ze de rotsblokken meevoeren tot maximaal vijf meter per minuut. Hoe massieve rotsblokken van honderden kilogrammen bewegen en waarom er soms stenen ontbreken op het einde van een spoor blijft voorlopig een raadsel.

Opgave

In deze opgave stellen we een rotsblok voor als een balkvormig object. Het blok ligt altijd op het grondvlak (XY-vlak) van een driedimensionale ruimte met een vast assenstelsel zoals aangegeven in onderstaande figuur. Het blok wordt steeds bekeken vanuit een standpunt langs de positieve X-as in de richting van het YZ-vlak. Het voorvlak van het blok ligt altijd parallel met het YZ-vlak. De afmetingen van het blok worden beschreven door zijn breedte $B \in \mathbb{N}_0$ (gemeten langs de X-as), lengte $L \in \mathbb{N}_0$ (gemeten langs de Y-as) en hoogte $H \in \mathbb{N}_0$ (gemeten langs de Z-as). De positie van het blok wordt beschreven aan de hand van de positie van het hoekpunt $(x, y)$ linksonder in het voorvlak (in de figuur aangeduid met een zwarte stip), waarbij geldt dat $x, y \in \mathbb{Z}$.

blok
Beschrijving van de afmetingen en positie van een balkvormig object in een driemensionale ruimte met vast assenstelsel. De afmetingen van het object worden beschreven door de breedte $B$, de lengte $L$ en de hoogte $H$. De positie van het object wordt beschreven aan de hand van het hoekpunt linksonder in het voorvlak, dat wordt aangegeven met een zwarte stip. Op de figuur ligt dit hoekpunt in de oorsprong $(0, 0)$ van het grondvlak.

De oppervlakte $A$ van het rotsblok wordt gegeven door: $$A = 2(L\cdot B + L\cdot H + H\cdot B)$$ Het volume $V$ wordt gegeven door: $$V = L\cdot H\cdot B$$ De lengte van de binnendiagonale lijn $d$ wordt gegeven door: $$d = \sqrt{L^2 + H^2 + B^2}$$ Er zijn twee manieren waarop het rotsblok kan bewegen: schuiven of kantelen. Het rotsblok kan over zijn volledige lengte naar links of naar rechts schuiven, of kan over zijn volledige breedte naar voor of naar achter schuiven. Dit wordt geïllustreerd in onderstaande figuren.

verschuiven naar rechts
Het blok wordt over zijn volledige lengte naar rechts verschoven.
verschuiven naar voor
Het blok wordt over zijn volledige breedte naar voor verschoven.

Het rotsblok kan ook naar links, rechts, voor of achter kantelen. Dit wordt geïllustreerd in onderstaande figuren.

kantelen naar rechts
Het blok wordt naar rechts gekanteld.
kantelen naar voor
Het blok wordt naar voor gekanteld.

Gevraagd wordt om een klasse Blok te definiëren waarmee rotsblokken kunnen voorgesteld worden die afmetingen en een positie hebben zoals hierboven beschreven, en die ook op de twee aangegeven manieren kunnen bewegen. Deze klasse moet minstens de volgende methoden ondersteunen:

  • Een initialisatiemethode __init__ met drie parameters lengte, hoogte, breedte waaraan gehele getallen moeten doorgegeven worden die respectievelijk de lengte, de hoogte en de breedte van het blok aangeven. De initialisatiemethode heeft ook nog een optionele vierde parameter positie waaraan een lijst of een tuple van twee gehele getallen kan doorgegeven worden dat de positie aangeeft van het hoekpunt linksonder in het voorvlak. Indien niet expliciet een waarde wordt doorgegeven aan de parameter positie, dan ligt dit hoekpunt in de oorsprong $(0, 0)$ van het grondvlak.
  • Een methode oppervlakte (zonder argumenten) die de oppervlakte van het blok teruggeeft als een floating point getal.
  • Een methode volume (zonder argumenten) die het volume van het blok teruggeeft als een floating point getal.
  • Een methode diagonaal (zonder argumenten) die de lengte van de binnendiagonale lijn teruggeeft als een floating point getal.
  • Een methode __repr__ (zonder argumenten) die een stringvoorstelling teruggeeft met de huidige afmetingen en positie van het blok. Deze stringvoorstelling moet lezen als een Python statement dat kan gebruikt worden om een nieuw object van de klasse Blok aan te maken dat de huidige afmetingen en positie heeft van het blok waarop de methode wordt aangeroepen. De positie moet altijd weergegeven worden als een tuple met twee gehele getallen. Leid de correcte opmaak van deze stringvoorstelling af uit onderstaande voorbeelden.
  • Een methode schuif waaraan een string moet doorgegeven worden die bestaat uit één enkele letter. Deze letter geeft de richting aan waarin de methode het blok moet verschuiven: links (L), rechts (R), voor (V) of achter (A). De methode moet een verwijzing teruggeven naar het Blok-object waarop de methode wordt aangeroepen, zodat het aanroepen van methoden kan aaneengeschakeld worden. Indien aan de methode geen hoofdletter wordt doorgegeven die overeenkomt met één van de vier richtingen, dan moet de methode een AssertionError opwerpen met de boodschap ongeldige richting.
  • Een methode kantel waaraan een string moet doorgegeven worden die bestaat uit één enkele letter. Deze letter geeft de richting aan waarin de methode het blok moet kantelen: links (L), rechts (R), voor (V) of achter (A). De methode moet een verwijzing teruggeven naar het Blok-object waarop de methode wordt aangeroepen, zodat het aanroepen van methoden kan aaneengeschakeld worden. Indien aan de methode geen hoofdletter wordt doorgegeven die overeenkomt met één van de vier richtingen, dan moet de methode een AssertionError opwerpen met de boodschap ongeldige richting.
  • Een methode zeil waaraan een string met even lengte moet doorgegeven worden. Deze string moet alternerend bestaan uit letters die een bepaalde beweging aangegeven (S voor schuiven en K voor kantelen) en letters die een bepaalde richting aangeven (L voor links, R voor rechts, V voor voorwaarts en A voor achterwaarts). Zo staat SA bijvoorbeeld voor schuif naar achter, KR voor kantel naar rechts, en SAKR voor schuif eerst naar achter en kantel daarna naar rechts. De methode moet de omschreven bewegingen achter elkaar uitvoeren en een verwijzing teruggeven naar het Blok-object waarop de methode wordt aangeroepen, zodat het aanroepen van methoden kan aaneengeschakeld worden. Indien de gegeven string op een even positie een karakter bevat dat niet overeenkomt met één van de hoofdletters die de bewegingen aanduiden, dan moet de methode een AssertionError opwerpen met de boodschap ongeldige beweging. Indien de gegeven string op een oneven positie een karakter bevat dat niet overeenkomt met één van de hoofdletters die de richtingen aanduiden, dan moet de methode een AssertionError opwerpen met de boodschap ongeldige richting.

Voorbeeld

>>> rots = Blok(5, 2, 3)
>>> rots
Blok(lengte=5, hoogte=2, breedte=3, positie=(0, 0))
>>> rots.oppervlakte()
62.0
>>> rots.volume()
30.0
>>> rots.diagonaal()
6.164414002968976
>>> rots2 = rots.schuif('R')
>>> rots2
Blok(lengte=5, hoogte=2, breedte=3, positie=(0, 5))
>>> rots is rots2
True
>>> rots.schuif('V')
Blok(lengte=5, hoogte=2, breedte=3, positie=(3, 5))
>>> rots.kantel('L')
Blok(lengte=2, hoogte=5, breedte=3, positie=(3, 3))
>>> rots.kantel('A')
Blok(lengte=2, hoogte=3, breedte=5, positie=(0, 3))
>>> rots.kantel('A').schuif('L').kantel('L').schuif('A')
Blok(lengte=5, hoogte=2, breedte=3, positie=(-8, -4))
>>> rots.zeil('SA')
Blok(lengte=5, hoogte=2, breedte=3, positie=(-11, -4))
>>> rots.zeil('KR')
Blok(lengte=2, hoogte=5, breedte=3, positie=(-11, 1))
>>> rots.zeil('SVSVKLSLKAKASRSVKRKVKRKRSASV')
Blok(lengte=2, hoogte=3, breedte=5, positie=(-2, 6))

>>> rots.kantel('X')
Traceback (most recent call last):
AssertionError: ongeldige richting
>>> rots.zeil('XY')
Traceback (most recent call last):
AssertionError: ongeldige beweging
>>> rots.zeil('KY')
Traceback (most recent call last):
AssertionError: ongeldige richting


Added by:Peter Dawyndt
Date:2011-07-25
Time limit:10s
Source limit:50000B
Memory limit:1536MB
Cluster: Cube (Intel G860)
Languages:PY_NBC
Resource:None