CS Challenge 1, Cube Slicing

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: 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: 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.