Kolmiulotteinen kuutio

Oletko tehnyt jotain, mistä muut voisivat hyötyä. Postita vinkit tänne.
Post Reply
User avatar
CosmoConsole
Newcomer
Posts: 6
Joined: Mon Dec 02, 2013 9:33 pm

Kolmiulotteinen kuutio

Post by CosmoConsole » Mon Dec 02, 2013 10:02 pm

Netistä löysin koodia, jolla saa piirrettyä 3D-kuution - en varma millä kielellä - mutta päätin portata koodin CoolBasicia varten ja tulos oli yllättävän hyvä. Sain aikaan itse myös wireframe-piirtotoiminnon, eli kuution voi piirtää kahdeksalla pisteellä, tai wireframena.

Code: Select all

SCREEN 800, 600

Function IIf(cond,truev,falsev)
 If cond Then
  Return truev
 Else
  Return falsev
 EndIf
EndFunction

Scale# = 1
Size = 5
Mode = 0
DMode = 0
CamX = 0
CamY = 0
CamZ = 300
MoveX = 0
MoveY = 0
MoveZ = 0
AngleX = 0
AngleY = 0
AngleZ = 0
ARot = False
PivX = 0
PivY = 0
PivZ = 0
Dim X (8)
Dim Y (8)
Dim Z (8)
Dim TX (8)
Dim TY (8)
I = 60
For j = 1 To 8
 X (j) = I * IIf(j>4,-1,1)
 Y (j) = I * IIf((j Mod 4)>1,-1,1)
 Z (j) = I * IIf((j Mod 2),-1,1)
Next j
Repeat
 For N = 1 To 8
  XD = X (N) - PivX
  YD = Y (N) - PivY
  ZD = Z (N) - PivZ
  
  ZX = XD*Cos(ANGLEZ) - YD*Sin(ANGLEZ) - XD
  ZY = XD*Sin(ANGLEZ) + YD*Cos(ANGLEZ) - YD
  
  YX = (XD+ZX)*Cos(AngleY) - ZD*Sin(AngleY) - (XD+ZX)
  YZ = (XD+ZX)*Sin(AngleY) + ZD*Cos(AngleY) - ZD
  
  XY = (YD+ZY)*Cos(AngleX) - (ZD+YZ)*Sin(AngleX) - (YD+ZY)
  XZ = (YD+ZY)*Sin(AngleX) + (ZD+YZ)*Cos(AngleX) - (ZD+YZ)
  
  XROTOFFSET = YX+ZX
  YROTOFFSET = ZY+XY
  ZROTOFFSET = XZ+YZ
  
  If Mode = 0 Then
   SX = ( X (N) + XROTOFFSET + CamX ) / Scale + MoveX
   SY = ( Y (N) + YROTOFFSET + CamY ) / Scale + MoveY
  Else
   SZ = ( Z (N) + ZROTOFFSET + CamZ )
   SX = ( X (N) + XROTOFFSET + CamX ) / SZ / Scale + MoveX
   SY = ( Y (N) + YROTOFFSET + CamY ) / SZ / Scale + MoveY
  EndIf
  Color cbWhite
  If Mode = 0 Then
   If Not DMode Then
    Circle SX + 400, SY + 300, Size / Scale
   Else
    TX (N-1) = SX + 400
    TY (N-1) = SY + 300
   EndIf
  Else
   PZ = (Z (N) + ZROTOFFSET + CamZ)
   Circle SX + 400, SY + 300, Size / PZ / Scale
   
   PX = ( ( PivX + CamX ) / ( PivZ + CamZ ) ) / Scale + MoveX + 400
   PY = ( ( PivY + CamY ) / ( PivZ + CamZ ) ) / Scale + MoveY + 300
   Dot PX, PY
  EndIf
 Next N
 
 FG = 1 + (KeyDown(cbkeylcontrol) * 3)
 
 If KeyDown(cbKeyLeft) Then MoveX = MoveX - (2 * FG)
 If KeyDown(cbKeyRight) Then MoveX = MoveX + (2 * FG)
 If KeyDown(cbKeyUp) Then MoveY = MoveY - (2 * FG)
 If KeyDown(cbKeyDown) Then MoveY = MoveY + (2 * FG)
 If KeyDown(cbKeyO) Then Scale# = Scale# * 1.02
 If KeyDown(cbKeyP) Then Scale# = Scale# / 1.02
 
 If KeyDown(cbKeyQ) Then AngleY = AngleY - FG
 If KeyDown(cbKeyE) Then AngleY = AngleY + FG
 If KeyDown(cbKeyW) Then AngleX = AngleX - FG
 If KeyDown(cbKeyS) Then AngleX = AngleX + FG
 If KeyDown(cbKeyA) Then AngleZ = AngleZ - FG
 If KeyDown(cbKeyD) Then AngleZ = AngleZ + FG
 
 If KeyDown(cbKeyF) Then PivX = PivX - (2 * FG)
 If KeyDown(cbKeyH) Then PivX = PivX + (2 * FG)
 If KeyDown(cbKeyT) Then PivY = PivY - (2 * FG)
 If KeyDown(cbKeyG) Then PivY = PivY + (2 * FG)
 If KeyDown(cbKeyR) Then PivZ = PivZ - (2 * FG)
 If KeyDown(cbKeyY) Then PivZ = PivZ + (2 * FG)
 
 If KeyDown(cbKey1) Then CamX = CamX - (4 * FG)
 If KeyDown(cbKey2) Then CamX = CamX + (4 * FG)
 If KeyDown(cbKey3) Then CamY = CamY - (4 * FG)
 If KeyDown(cbKey4) Then CamY = CamY + (4 * FG)
 If KeyDown(cbKey5) Then CamZ = CamZ - (4 * FG)
 If KeyDown(cbKey6) Then CamZ = CamZ + (4 * FG)
 
 If ARot Then AngleY = AngleY + FG
 If ARot Then AngleX = AngleX - FG
 If ARot Then AngleZ = AngleZ - FG
 
 If DMode Then
  Color 128, 128, 128
  Line TX (4), TY (4), TX (2), TY (2)
  Line TX (0), TY (0), TX (7), TY (7)
  Line TX (0), TY (0), TX (1), TY (1)
  Line TX (2), TY (2), TX (3), TY (3)
  Line TX (4), TY (4), TX (5), TY (5)
  Line TX (7), TY (7), TX (6), TY (6)
  Line TX (0), TY (0), TX (6), TY (6)
  Line TX (4), TY (4), TX (3), TY (3)
  Line TX (2), TY (2), TX (5), TY (5)
  Line TX (7), TY (7), TX (1), TY (1)
  Line TX (3), TY (3), TX (5), TY (5)
  Line TX (6), TY (6), TX (1), TY (1)
  Color 255, 255, 255
  Line TX (0), TY (0), TX (4), TY (4)
  Line TX (0), TY (0), TX (2), TY (2)
  Line TX (4), TY (4), TX (7), TY (7)
  Line TX (2), TY (2), TX (6), TY (6)
  Line TX (0), TY (0), TX (3), TY (3)
  Line TX (3), TY (3), TX (1), TY (1)
  Line TX (2), TY (2), TX (1), TY (1)
  Line TX (4), TY (4), TX (6), TY (6)
  Line TX (7), TY (7), TX (5), TY (5)
  Line TX (6), TY (6), TX (5), TY (5)
  Line TX (3), TY (3), TX (7), TY (7)
  Line TX (1), TY (1), TX (5), TY (5)
 EndIf
 
 If KeyHit(cbKeySpace) Then
  If Mode = 0 Then
   Mode = 1
   Scale# = Scale# / CamZ
  Else
   Mode = 0
   Scale# = Scale# * CamZ
  EndIf
 EndIf
 If KeyHit(cbKeyReturn) Then
  ARot = Not ARot
 EndIf
 If KeyHit(cbKeyBackspace) Then
  DMode = Not DMode
 EndIf 
 DrawScreen
Forever
Seuraavat näppäimet toimivat (lista spoilerissa, koska pitkä):
Askelpalautin (backspace) - Vaihda piste- ja viiva (wireframe) piirtotilan välillä.
Palautusnäppäin (enter/return) - Kytke päälle/pois päältä automaattinen pyöritys.
Välilyönti (space) - Alkuperäisessä koodissa vaihtoi isometriseen tilaan, joka ei tässä kuitenkaan vaikuttaisi tekevän paljon mitään kuin jähmettävän piirron kunnes painetaan uudestaan.
W/S - Pyöritys pystysuunnassa
A/D - Pyöritys vaakasuunnassa
Q/E - Pyöritys 2D-kuvasuunnassa (vaikea selittää)
T/G - Liikuta kuutiota W/S kääntymisen mukaan
F/H - Liikuta kuutiota A/D kääntymisen mukaan
R/Y - Liikuta kuutiota Q/E kääntymisen mukaan
P/O - Siirrä kuutiota lähemmäs/kauemmas
Ylös/alas - Siirrä kuutiota ylös / alas (nuolinäppäimet)
Vasen/oikea - Siirrä kuutiota vasemmalle / oikealle (nuolinäppäimet)
1/2 - Liikuttaa kameraa suhteessa kuutioon vaakasuunnassa.
3/4 - Liikuttaa kameraa suhteessa kuutioon pystysuunnassa.
5/6 - Liikuttaa kameraa suhteessa kuutioon syvyyssuunnassa (tosin ei näkyvää eroa)

User avatar
MaGetzUb
Guru
Posts: 1715
Joined: Sun Sep 09, 2007 12:35 pm
Location: Alavus

Re: Kolmiulotteinen kuutio

Post by MaGetzUb » Thu Dec 05, 2013 6:01 pm

Ihan komea, tosin tuo on vain ortograaffisesti esitetty 3-ulotteinen kuutio, koska syvyysvaikutelma eli perspektiivi puuttuu kokonaan. :)
Solar Eclipse
Meneillä olevat Projektit:
We're in a simulation, and God is trying to debug us.

User avatar
CosmoConsole
Newcomer
Posts: 6
Joined: Mon Dec 02, 2013 9:33 pm

Re: Kolmiulotteinen kuutio

Post by CosmoConsole » Fri Dec 06, 2013 6:12 pm

MaGetzUb wrote:Ihan komea, tosin tuo on vain ortograaffisesti esitetty 3-ulotteinen kuutio, koska syvyysvaikutelma eli perspektiivi puuttuu kokonaan. :)
Tiedän, esitys on täysin isometrinen. Saatiin kuitenkin yhden kamun kanssa aikaan syvyysvaikutelma, tosin se on melko buginen, ehkä julkaisen senkin version kunhan olen hionut vielä pikkuisen.

User avatar
koodaaja
Moderator
Moderator
Posts: 1583
Joined: Mon Aug 27, 2007 11:24 pm
Location: Otaniemi - Mikkeli -pendelöinti

Re: Kolmiulotteinen kuutio

Post by koodaaja » Sat Dec 07, 2013 1:05 pm

Bugittomastikin projektion saa tehtyä verraten yksinkertaisesti. Projisoitu 2D-koordinaatti on (w/2+C*x/(z+D), h/2+C*y/(z+D)), missä (x,y,z) on piirrettävä piste, w ja h näytön koko ja C projektion voimakkuuden kertova vakio. Z-arvoihin on usein hyvä lisätä suhteellisen suuria vakioita (kaavassa D) jotta projektiosta saa vähemmän vääristävän ja kappaleet ovat silti nähtävissä olevan kokoisia. Ainakin omien 3D-viritelmieni alkuongelmia oli myös unohtaa käyttää floatteja - kokonaisluvuilla liikkeistä tulee erittäin töksähteleviä.

Varsin lupaavalta se tähän asti näyttää, nyt vaan joku mielekkäämpi modelli kehiin ja peliä tulemaan!

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests