2d naar 3d

Moderators: dirkwb, Xilvo

Forumregels
(Middelbare) school-achtige vragen naar het forum "Huiswerk en Practica" a.u.b.
Zie eerst de Huiswerkbijsluiter
Reageer
Gebruikersavatar
Berichten: 2.097

2d naar 3d

Afgelopen jaar hadden we een opdracht om een spelletje te programmeren in Modula 2.

En aangezien ik dit wel leuk vond, ben ik in mijn vrije tijd ook bezig met kleine, niet al te (grafisch) ingewikkelde spelletjes te maken.

Momenteel ben ik bezig met een versie van '3d logic'.

Alles is geprogrammeerd en werkt. Enkel de grafische kant heeft nog wat werk nodig; ik ben begonnen met 2D voor-,zij- en bovenaanzichten.

Vandaag heb ik daar een isometrisch aanzicht bijgedaan (is het eenvoudigste 3D zicht, denk ik :D )

Daarvoor heb ik de formules van wikipedia gebruikt.

Dus voor 3D naar 2D:
\( x_{2D}= \frac{1}{\sqrt{6}} ( \sqrt{3} \cdot x_{3D}-\sqrt{3} \cdot z_{3D}) \)
\( y_{2D}=\frac{1}{\sqrt{6}} ( x_{3D} + 2y_{3D} + z_{3D}) \)
So far so good...

Op dit moment moet je nog altijd in de 2D aanzichten klikken om een vakje in te kleuren (linksbovenaan screen)

Aangezien dit nogal onhandig is, had ik dit graag rechtstreeks op de kubus willen doen.

Daarvoor heb ik dus de omgekeerde formule voor nodig: van gegeven 2D coördinaten naar de oorspronkelijke 3D.

Het probleem is dat ik onderweg tijdens de overzetting naar 2D mijn z-coördinaat kwijtspeel.

En ik dus maar de twee vergelijkingen van hierboven heb, om daar de 3 3D-coördinaten uit te halen.

Hoe krijg ik mijn 3D-coördinaten?

(de kwaliteit van de afbeelding is niet geweldig, maar het geeft misschien wel een beter beeld van de situatie)

Afbeelding
"Why must you speak when you have nothing to say?" -Hornblower

Conserve energy: Commute with a Hamiltonian

Berichten: 7.068

Re: 2d naar 3d

En ik dus maar de twee vergelijkingen van hierboven heb, om daar de 3 3D-coördinaten uit te halen.
Twee vergelijkingen, drie onbekende, dat gaat dus niet lukken... de 2D x en y leggen een lijn vast. Je zou het snijpunt van de lijn en de kubus kunnen gaan zoeken.

Het kan mijn inziens echter simpeler. Maak een plaatje met exact dezelfde lay-out als je al hebt, maar kleur hierin elk vakje met een unieke kleur. Je kunt nu een kleur koppelen aan een specifiek vakje. Dit nieuwe plaatje laat je NIET op het scherm zien. Als je nu een 2D x en y coordinaat krijgt dan kijk je welke kleur dit coordinaat heeft in het verborgen plaatje. Dit vertelt je dan direct welk vakje dit is.

Gebruikersavatar
Berichten: 2.097

Re: 2d naar 3d

Het kan mijn inziens echter simpeler. Maak een plaatje met exact dezelfde lay-out als je al hebt, maar kleur hierin elk vakje met een unieke kleur. Je kunt nu een kleur koppelen aan een specifiek vakje. Dit nieuwe plaatje laat je NIET op het scherm zien. Als je nu een 2D x en y coordinaat krijgt dan kijk je welke kleur dit coordinaat heeft in het verborgen plaatje. Dit vertelt je dan direct welk vakje dit is.
Dat zou inderdaad (wiskundig) makkelijker zijn. Om te programmeren wel iets moeilijker:

Ik zou dit doen door de kubus te tekenen op scherm, in te kleuren met een procedure die ik al heb, maar dit niet weer te geven.

Enkel, de standaard functie bij de compiler om een pixel uit te lezen van het scherm (en op te slaan in een array) werkt niet (hij geeft altijd 0=zwart).

Ik zou het ook via een Windows procedure kunnen doen, enkel komen de pixels die Windows geeft niet overeen met die gebruikt in de graph library.

Daarenboven zijn er in de standaard graph library maar 20 kleuren beschikbaar.

Ik herinnerde me dat je kan zien aan de uitkomst van een formule (positief of negatief) of een punt boven of onder een vlak ligt. (ik denk gewoon het punt invullen in de vergelijking van het vlak?)

Gaat dit ook in 2D: afhankelijk van het teken zien dat een punt boven of onder een rechte ligt?

Zo zou ik de positie van de muis kunnen insluiten tussen de 4 rechten van een vakje.

Dit zou denk ik vrij gemakkelijk zijn, aangezien ik alle hoekpunten van de kubus ergens al in een array heb zitten.
"Why must you speak when you have nothing to say?" -Hornblower

Conserve energy: Commute with a Hamiltonian

Gebruikersavatar
Berichten: 5.679

Re: 2d naar 3d

ZVdP schreef:Dat zou inderdaad (wiskundig) makkelijker zijn. Om te programmeren wel iets moeilijker:

Ik zou dit doen door de kubus te tekenen op scherm, in te kleuren met een procedure die ik al heb, maar dit niet weer te geven.

Enkel, de standaard functie bij de compiler om een pixel uit te lezen van het scherm (en op te slaan in een array) werkt niet (hij geeft altijd 0=zwart).

Ik zou het ook via een Windows procedure kunnen doen, enkel komen de pixels die Windows geeft niet overeen met die gebruikt in de graph library.

Daarenboven zijn er in de standaard graph library maar 20 kleuren beschikbaar.
Dat klinkt als een hele beperkte library. Je zou gewoon plaatjes in het geheugen net zo moeten kunnen verwerken als op het scherm, en alleen met de systeemkleuren kunnen werken is echt achterhaald. Misschien is Simple DirectMedia Layer wat voor je?
Ik herinnerde me dat je kan zien aan de uitkomst van een formule (positief of negatief) of een punt boven of onder een vlak ligt. (ik denk gewoon het punt invullen in de vergelijking van het vlak?)

Gaat dit ook in 2D: afhankelijk van het teken zien dat een punt boven of onder een rechte ligt?

Zo zou ik de positie van de muis kunnen insluiten tussen de 4 rechten van een vakje.

Dit zou denk ik vrij gemakkelijk zijn, aangezien ik alle hoekpunten van de kubus ergens al in een array heb zitten.
Dat kan, je kunt de z-coördinaat nemen van het uitproduct van de muispositie en ieder van de vier zijden van een vakje. Als het punt in het vak ligt, moeten die vier getallen moeten allemaal positief of allemaal negatief zijn (afhankelijk van de oriëntatie van de zijden van je vlakken en je coördinatenstelsel).

Hiervoor is het wel nodig dat de zijden allevier met de klok mee of allevier tegen de klok in zijn gedefinieerd. Bijvoorbeeld als de vier hoekpunten van een vakje ABCD zijn, dan moet A->B->C->D->A een vierkantje vormen (en geen zandloper). Als dat lastig te forceren is kun je ook meerdere volgordes verifiëren, als er één is waarbij het uitproduct voor allevier de zijden hetzelfde teken geeft, dan ligt het punt in het vakje.
In theory, there's no difference between theory and practice. In practice, there is.

Gebruikersavatar
Berichten: 2.097

Re: 2d naar 3d

Dat klinkt als een hele beperkte library. Je zou gewoon plaatjes in het geheugen net zo moeten kunnen verwerken als op het scherm, en alleen met de systeemkleuren kunnen werken is echt achterhaald. Misschien is Simple DirectMedia Layer wat voor je?
Ja, het is allemaal wel een beetje verouderd, maar het is ook een gratische compiler.

Met afbeeldingen in het geheugen kan je niet veel doen, niets eigenlijk. Je krijgt een ID in de vorm van een Cardinal,

die je kan gebruiken om het plaatje ergens op het scherm te tekenen.
Dat kan, je kunt de z-coördinaat nemen van het uitproduct van de muispositie en ieder van de vier zijden van een vakje. Als het punt in het vak ligt, moeten die vier getallen moeten allemaal positief of allemaal negatief zijn (afhankelijk van de oriëntatie van de zijden van je vlakken en je coördinatenstelsel).

Hiervoor is het wel nodig dat de zijden allevier met de klok mee of allevier tegen de klok in zijn gedefinieerd. Bijvoorbeeld als de vier hoekpunten van een vakje ABCD zijn, dan moet A->B->C->D->A een vierkantje vormen (en geen zandloper). Als dat lastig te forceren is kun je ook meerdere volgordes verifiëren, als er één is waarbij het uitproduct voor allevier de zijden hetzelfde teken geeft, dan ligt het punt in het vakje.
Eens kijken of ik het goed begrepen heb, want er gaat iets fout bij de uitvoering :D

Het resultaat van het kruisproduct geeft me: (x*Ay-y*Ax)

Met x,y: de muispositie

en Ax,Ay: de zijden (verschil van de hoekpunten)

Code: Selecteer alles

PROCEDURE CheckSquare(square,x,y:INTEGER):BOOLEAN;

VAR test,test1,test2,test3:INTEGER;

BEGIN

test:=x*(cubeiso^[square][1][1]-cubeiso^[square][0][1])-y*(cubeiso^[square][1][0]-cubeiso^[square][0][0]);

test1:=x*(cubeiso^[square][2][1]-cubeiso^[square][1][1])-y*(cubeiso^[square][2][0]-cubeiso^[square][1][0]);

test2:=x*(cubeiso^[square][3][1]-cubeiso^[square][2][1])-y*(cubeiso^[square][3][0]-cubeiso^[square][2][0]);

test3:=x*(cubeiso^[square][0][1]-cubeiso^[square][3][1])-y*(cubeiso^[square][0][0]-cubeiso^[square][3][0]);

IF ((test<0) AND (test1<0) AND (test2<0) AND (test3<0)) OR ((test>0) AND (test1>0) AND (test2>0) AND (test3>0)) THEN

  RETURN TRUE;

ELSE

  RETURN FALSE;

END;

END CheckSquare;
waarbij:

x en y de muispositie,

square: het vakje dat getest wordt

cubeiso: array met de coördinaten van de hoekpunten: eerste [] duiden het vakje aan, tweede [] geven het hoekpunt aan (0=linksboven,1=rechtsboven,2=rechtsonder,3=linksonder), derde [] geven de coördinaat aan (0=x,1=y)

Maar waar ik ook klik op het scherm, hij geeft altijd FALSE.

EDIT: Ik zie juist mijn fout denk ik: ik neem het kruisproduct met de richtingsvector van de zijde, wat niet echt kan kloppen.

Maar nu zit ik wel even vast met wat je bedoelt met het kruisproduct tussen een punt en een zijde?
"Why must you speak when you have nothing to say?" -Hornblower

Conserve energy: Commute with a Hamiltonian

Gebruikersavatar
Berichten: 5.679

Re: 2d naar 3d

Als P de muispositie is, en A en B de punten van een zijde (die loopt van A naar B) dan bedoel ik het kruisproduct tussen (P-A) en (B-A). En idem zo voor de zijden van B naar C, C naar D, en D naar A.
In theory, there's no difference between theory and practice. In practice, there is.

Gebruikersavatar
Berichten: 2.097

Re: 2d naar 3d

Als P de muispositie is, en A en B de punten van een zijde (die loopt van A naar B) dan bedoel ik het kruisproduct tussen (P-A) en (B-A). En idem zo voor de zijden van B naar C, C naar D, en D naar A.
Bedankt, het werkt perfect! :D
"Why must you speak when you have nothing to say?" -Hornblower

Conserve energy: Commute with a Hamiltonian

Reageer