Springen naar inhoud

2d naar 3d


  • Log in om te kunnen reageren

#1

ZVdP

    ZVdP


  • >1k berichten
  • 2097 berichten
  • VIP

Geplaatst op 10 augustus 2008 - 21:37

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

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)
Geplaatste afbeelding

Veranderd door ZVdP, 10 augustus 2008 - 21:39

"Why must you speak when you have nothing to say?" -Hornblower
Conserve energy: Commute with a Hamiltonian

Dit forum kan gratis blijven vanwege banners als deze. Door te registeren zal de onderstaande banner overigens verdwijnen.

#2

EvilBro

    EvilBro


  • >5k berichten
  • 6703 berichten
  • VIP

Geplaatst op 11 augustus 2008 - 07:09

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.

#3

ZVdP

    ZVdP


  • >1k berichten
  • 2097 berichten
  • VIP

Geplaatst op 11 augustus 2008 - 13:13

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

#4

Rogier

    Rogier


  • >5k berichten
  • 5679 berichten
  • VIP

Geplaatst op 11 augustus 2008 - 14:26

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.

#5

ZVdP

    ZVdP


  • >1k berichten
  • 2097 berichten
  • VIP

Geplaatst op 11 augustus 2008 - 15:35

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)

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?

Veranderd door ZVdP, 11 augustus 2008 - 15:37

"Why must you speak when you have nothing to say?" -Hornblower
Conserve energy: Commute with a Hamiltonian

#6

Rogier

    Rogier


  • >5k berichten
  • 5679 berichten
  • VIP

Geplaatst op 11 augustus 2008 - 18:00

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.

#7

ZVdP

    ZVdP


  • >1k berichten
  • 2097 berichten
  • VIP

Geplaatst op 11 augustus 2008 - 18:41

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





0 gebruiker(s) lezen dit onderwerp

0 leden, 0 bezoekers, 0 anonieme gebruikers

Ook adverteren op onze website? Lees hier meer!

Gesponsorde vacatures

Vacatures