CS Challenge 1, Cube Slicing
- Har jeg virkelig bestået Matematik på A-niveau?
- Selv tilsyneladende simple ting kan have overraskende specialtilfælde
I denne Challenge kigger vi på en terning med sidelængde 1. Hvis man
roterer den omkring de 3 rumlige akser og skærer den over i et
vandret plan, så kan man opnå overraskende mange
tværsnit, fx:
- et enkelt punkt
- et linjestykke
- en ligesidet trekant
- en ligebenet trekant
- en skæv trekant
- et kvadrat
- et rektangel
- en skæv firkant
- en femkant
- en sekskant
- slet ingenting
Brug nogle minutter på at forestille dig, hvordan
disse eksempler kan fremkomme (brug eventuelt en fysisk terning).
Fx kan den overraskende sekskant laves sådan her:
Vi tænker på terningen som siddende i et koordinatsystem,
med x-, y- og z-akser:
Terningens centrum sider i (0,0,0). Terningen kan beskrives ved hjælp af de 12 sider, der hver svarer til et
linjesegment i rummet, og 7 af dem har disse
koordinater for deres endepunkter:
((-0.5, -0.5, -0.5), (0.5, -0.5, -0.5))
((-0.5, 0.5, -0.5), (0.5, 0.5, -0.5))
((-0.5, -0.5, -0.5), (-0.5, 0.5, -0.5))
((0.5, -0.5, -0.5), (0.5, 0.5, -0.5))
((-0.5, -0.5, 0.5), (0.5, -0.5, 0.5))
((-0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
((-0.5, -0.5, 0.5), (-0.5, 0.5, 0.5))
Spørgsmål A
Angiv koordinaterne for de sidste 5 linjesegmenter i
terningen.
Du skal færdigøre programmerne Cube.java og
LineSegment.java,
som kan hentes samlet i Cube.zip. Det kaldes som:
java Cube α β γ h
Her er α,
β, og γ, de
vinkler terningen er roteret om de forskellige akser.
For letheds skyld angives de i grader mellem -89 og +89
(overvej, hvorfor det er nok).
Med h angiver man
højden, hvor den roterede terning skal
skæres over. For letheds skyld angives det
i 1/1000-dele, med værdier mellem -1000 og +1000
(overvej, hvorfor det er nok). Som output tegner
programmet det valgte tværsnit.
Spørgsmål B
Angiv, hvordan programmet skal kaldes for at vise:
- ingenting
- et linjestykke
- en ligebenet trekant
- et kvadrat
- en femkant
Det er måske lettest at gøre dette
med dit program, når det er færdigt.
Hint: en af mange femkanter kan fx opnås med kaldet:
java Cube 40 50 60 200
Du kan køre programmet i en Windows command shell ved
at udføre kommandoerne:
javac -cp vecmath.jar *.java
java -cp vecmath.jar Cube 45 45 45 350
Programmet virker ved at beregne skæringspunterne mellem
de 12 roterede linjesegmenter og det angivne plan. Hvis alle
disse punkter samles sammen og man beregner deres
konvekse hylster, så
giver det netop tværsnittet. Bemærk, at
et linjesegment og et plan kan have 0 skæringspunkter,
1 skæringspunkt, eller 2 skæringspunkter
(begge endepunkter, hvis linjesegmentet ligger i planet).
Spørgsmål C
Forklar, i ganske få linjer, hvorfor
algoritmen virker. Det vil sige, hvorfor giver det
konvekse hylster af disse skæringspunkter det rigtige
tværsnit?
Programmet er næsten skrevet færdigt. Du skal
angive værdierne for de manglende linjesegmenter
l8,
l9,
l10,
l11 og l12, som en del af en
ny adgave af programmet.
Du skal skrive kroppen af metoden:
public void intersectXYPlane(final double h, ConvexHull hull)
der ligger i klassen LineSegment.
Den skal beregne skæringspunkterne mellem
det aktuelle linjesegment og planet i højde h og rapportere dem til
det konvekse hylster hull ved hjælp af metoden
add fra klassen ConvexHull.
På et tidspunkt skal man afgøre, om to tal er ens. På grund af
små unøjagtigheder ved Javas talrepræsentation, skal du afgøre
dette ved at teste, om deres forskel er mindre end konstanten
ALMOST_ZERO.
Spørgsmål D
Skriv og aftest den manglende kode i Cube.java og
LineSegment.java.
BlueJ version:
BlueJCube.zip.
Du deltager i vores Challenge ved senest den 6. september at sende en e-mail
til mis@cs.au.dk med subject Challenge 1 og
svarene på spørgsmål A, B og C
(i plain text) samt et
attachment med svaret på spørgsmål D i form af
din nye udgave af filerne Cube.javaz og LineSegment.java.
Du bliver registreret som deltager gennem denne første e-mail. Du skal
derfor angive dit navn og din studielinje (dat/it/mat). Herefter er du identificeret
af din e-mail adresse.