(x|y|z) -> Isometrisch (Primitiv³ *g*)

Spiele, Demos, Grafikzeug und anderes unterhaltendes.
chromax
Beiträge: 20
Registriert: 26.09.2004 10:13
Kontaktdaten:

(x|y|z) -> Isometrisch (Primitiv³ *g*)

Beitrag von chromax »

Ist ne Spielerei aus Langeweile, aber vielleicht findet ja jemand gefallen daran...
Der Code nimmt Punkte mit (x,y,z), und wandelt sie in eine isometrische Darstellung um. Die Punkte kann man mit linien verbinden, und die so entstandenen Flächen mit Farben füllen. YAY!
iso.pb

Code: Alles auswählen

; Isometrisches Dingsbumsens
; © 2005 chromaX, Sinn&Zwecklos GmbH.


InitSprite()
InitKeyboard()
screenw = 1280
OpenScreen(screenw, 1024,  32, "Test")

Structure _3d
  x.l
  y.l
  z.l
EndStructure

Structure _2d
  x.l
  y.l
EndStructure

Structure _li
  P1.l
  P2.l
  col.l
EndStructure

Structure _ae
  P1.l
  P2.l
  P3.l
  col.l
EndStructure


winkelx.f = 26.565 / 180 * ACos(-1)
winkelz.f = 26.565 / 180 * ACos(-1)
xfaktor.f = 1
yfaktor.f = 1
zfaktor.f = 1

separate = RGB(5,5,5)
linecol = separate
areacol = RGB(255,255,255)

NewList ploties._3d()
NewList lines._li()
NewList areas._ae()

ReadFile(0, "file.iso")
Repeat
  line.s = ReadString()
  If multilinecomment = 1
    If FindString(line, "*/", 0)
      multilinecomment = 0
      line = StringField(line, 2, "*/")
    Else
      Continue
    EndIf
  EndIf
  If FindString(line, "/*", 0)
    line = StringField(line, 1, "/*")
    multilinecomment = 1
  EndIf
  line = Trim(StringField(line , 1, "//"))
  If LCase(Left(line , 4)) = "plot"
    line = Mid(line, 6, Len(line) - 6)
    AddElement(ploties())
    ploties()\x = Val(Trim(StringField(line, 1, ",")))
    ploties()\y = Val(Trim(StringField(line, 2, ",")))
    ploties()\z = Val(Trim(StringField(line, 3, ",")))
  EndIf
  If LCase(Left(line , 4)) = "line"
    line = Mid(line, 6, Len(line) - 6)
    AddElement(lines())
    lines()\P1 = Val(Trim(StringField(line, 1, ",")))
    lines()\P2 = Val(Trim(StringField(line, 2, ",")))
    If Val(Trim(StringField(line, 3, ",")))
      lines()\col = RGB(Val(Trim(StringField(line, 3, ","))),Val(Trim(StringField(line, 4, ","))),Val(Trim(StringField(line, 5, ","))))
    Else
      lines()\col = linecol
    EndIf
  EndIf
  If LCase(Left(line , 4)) = "area"
    line = Mid(line, 6, Len(line) - 6)
    AddElement(areas())
    areas()\P1 = Val(Trim(StringField(line, 1, ",")))
    areas()\P2 = Val(Trim(StringField(line, 2, ",")))
    areas()\P3 = Val(Trim(StringField(line, 3, ",")))
    If Val(Trim(StringField(line, 4, ",")))
      areas()\col = RGB(Val(Trim(StringField(line, 4, ","))), Val(Trim(StringField(line, 5, ","))), Val(Trim(StringField(line, 6, ","))))
    Else
      areas()\col = areacol
    EndIf
  EndIf
  If LCase(Left(line , 4)) = "lcol"
    line = Mid(line, 6, Len(line) - 6)
    linecol = RGB(Val(Trim(StringField(line, 1, ","))), Val(Trim(StringField(line, 2, ","))), Val(Trim(StringField(line, 3, ","))))
  EndIf
  If LCase(Left(line , 4)) = "acol"
    line = Mid(line, 6, Len(line) - 6)
    areacol = RGB(Val(Trim(StringField(line, 1, ","))), Val(Trim(StringField(line, 2, ","))), Val(Trim(StringField(line, 3, ","))))
  EndIf

  ;Debug line
Until Eof(0)

maxp = CountList(ploties()) - 1
Dim points._2d(maxp)

durchlauf = 0
ForEach ploties()
  points(durchlauf)\x = Cos(winkelx)*ploties()\x*xfaktor + Cos(winkelz)*ploties()\z*zfaktor
  points(durchlauf)\y = Sin(winkelz)*ploties()\z*zfaktor - Sin(winkelx)*ploties()\x*xfaktor - ploties()\y*yfaktor
  If maxy < points(durchlauf)\y
    maxy = points(durchlauf)\y
  EndIf
  durchlauf + 1
Next

yoffset = 1024 - maxy - 200
xoffset = 200

Repeat 
 Delay(10)
 StartDrawing(ScreenOutput())
  ClearScreen(0, 0, 0)
  FrontColor(255, 0, 0)
  ForEach lines()
    LineXY(points(lines()\P1)\x + xoffset, points(lines()\P1)\y + yoffset, points(lines()\P2)\x + xoffset, points(lines()\P2)\y + yoffset, separate)
  Next
  ForEach areas()
    FillArea((points(areas()\P1)\x + points(areas()\P2)\x + points(areas()\P3)\x)/3 + xoffset, (points(areas()\P1)\y + points(areas()\P2)\y + points(areas()\P3)\y)/3 + yoffset, separate, areas()\col)
  Next
  ForEach lines()
    LineXY(points(lines()\P1)\x + xoffset, points(lines()\P1)\y + yoffset, points(lines()\P2)\x + xoffset, points(lines()\P2)\y + yoffset, lines()\col)
  Next
StopDrawing()
FlipBuffers()
  For x = 1 To 15
    Delay(1)
    ExamineKeyboard()
    If KeyboardPushed(#PB_KEY_A)
      Ergebnis = GrabSprite(0, 0, 0, 1280, 1024)
      SaveSprite(0, "c:\"+Str(Minute(Date()))+Str(Second(Date()))+".bmp")
    EndIf
  Next
Until KeyboardPushed(1)

Dat ding hier macht ein Haus.
file.iso

Code: Alles auswählen

plot(0,0,0) //P0(x|y|z)
plot(0,0,50)
plot(50,0,50)
plot(0,50,0)
plot(0, 50, 50)
plot(50, 50, 50)
plot(50, 50, 0)
plot(25, 70, 0)
plot(25, 70, 50)
lcol(255,0,0) //Linienfarbe festlegen
line(0,1) //Punkt 0 mit Punkt 1 verbinden, Farbe ist lcol
line(0,3)
line(1,2)
line(1,4)
line(2,5)
line(3,4)
line(3,7)
line(4,5)
line(4,8)
line(5,6)
line(5,8)
line(6,7)
line(7,8,99,0,0) //Linie mit Farbe RGB(99,0,0) von Punkt 7 zu Punkt 8
acol(255,255,255) //Füllfarbe festlegen (Weiss)
area(0,1,3) //Fläche zwischen diesen drei Punkten mit Füllfarbe füllen
area(1,2,4)
area(4,5,8)
area(4,7,3,99,0,0) 
area(5,7,6,99,0,0)
Benutzeravatar
Lebostein
Beiträge: 674
Registriert: 13.09.2004 11:31
Wohnort: Erzgebirge

Beitrag von Lebostein »

Etwas eigenartige Hauptschleife...
1. Was sollen die vielen Delays?
2. Warum fragst du 15 mal die Screenshot-Taste ab?
3. ClearScreen() sollte nicht innerhalb von StartDrawing()-StopDrawing() aufgerufen werden (siehe Hilfetext)

So ist es besser:

Code: Alles auswählen

Repeat

 ClearScreen(0, 0, 0)
 StartDrawing(ScreenOutput())
  FrontColor(255, 0, 0)
  ForEach lines()
    LineXY(points(lines()\P1)\x + xoffset, points(lines()\P1)\y + yoffset, points(lines()\P2)\x + xoffset, points(lines()\P2)\y + yoffset, separate)
  Next
  ForEach areas()
    FillArea((points(areas()\P1)\x + points(areas()\P2)\x + points(areas()\P3)\x)/3 + xoffset, (points(areas()\P1)\y + points(areas()\P2)\y + points(areas()\P3)\y)/3 + yoffset, separate, areas()\col)
  Next
  ForEach lines()
    LineXY(points(lines()\P1)\x + xoffset, points(lines()\P1)\y + yoffset, points(lines()\P2)\x + xoffset, points(lines()\P2)\y + yoffset, lines()\col)
  Next
 StopDrawing()
 FlipBuffers()

 ExamineKeyboard()
 If KeyboardReleased(#PB_KEY_A)
  GrabSprite(0, 0, 0, 1280, 1024)
  SaveSprite(0, "c:\"+Str(Minute(Date()))+Str(Second(Date()))+".bmp")
 EndIf

Until KeyboardPushed(1)
Norbie
Beiträge: 134
Registriert: 29.08.2004 12:45
Wohnort: Chemnitz
Kontaktdaten:

Beitrag von Norbie »

Ist ziemlich Cool. Aber der Blickwinkel ist irgendwie zu Steil. Man sollte flacher über das "gelende" sehen können.
chromax
Beiträge: 20
Registriert: 26.09.2004 10:13
Kontaktdaten:

Beitrag von chromax »

Danke Lebostein für die verbesserung der Hauptschleife, war da am schluss halt etwas schludrig :oops:

Bin Norbies Anregung nachgegangen, damit das Teil flacher wird, und bin dabei auf das hier gekommen (stellts das ding aber noch verzogen dar, weiss noch nicht warum schau ich morgen...)

Code: Alles auswählen

InitKeyboard()
InitSprite()
res_x = 1280
res_y = 1024
OpenScreen(res_x, res_y, 32, "blb")

Structure _3d
  x.f
  y.f
  z.f
EndStructure

Structure _3f
  x.f
  y.f
  z.f
EndStructure

Structure _2d
  x.l
  y.l
EndStructure

Structure _li
  P1.l
  P2.l
  col.l
EndStructure

Structure _ae
  P1.l
  P2.l
  P3.l
  col.l
EndStructure

NewList pnt._3d()
NewList lines._li()
NewList areas._ae()

ReadFile(0, "wuerfel.iso")
Repeat
  line.s = ReadString()
  If multilinecomment = 1
    If FindString(line, "*/", 0)
      multilinecomment = 0
      line = StringField(line, 2, "*/")
    Else
      Continue
    EndIf
  EndIf
  If FindString(line, "/*", 0)
    line = StringField(line, 1, "/*")
    multilinecomment = 1
  EndIf
  line = Trim(StringField(line , 1, "//"))
  If LCase(Left(line , 4)) = "plot"
    line = Mid(line, 6, Len(line) - 6)
    AddElement(pnt())
    pnt()\x = Val(Trim(StringField(line, 1, ",")))
    pnt()\y = Val(Trim(StringField(line, 2, ",")))
    pnt()\z = Val(Trim(StringField(line, 3, ",")))
  EndIf
  If LCase(Left(line , 4)) = "line"
    line = Mid(line, 6, Len(line) - 6)
    AddElement(lines())
    lines()\P1 = Val(Trim(StringField(line, 1, ",")))
    lines()\P2 = Val(Trim(StringField(line, 2, ",")))
    If Val(Trim(StringField(line, 3, ",")))
      lines()\col = RGB(Val(Trim(StringField(line, 3, ","))),Val(Trim(StringField(line, 4, ","))),Val(Trim(StringField(line, 5, ","))))
    Else
      lines()\col = linecol
    EndIf
  EndIf
  If LCase(Left(line , 4)) = "area"
    line = Mid(line, 6, Len(line) - 6)
    AddElement(areas())
    areas()\P1 = Val(Trim(StringField(line, 1, ",")))
    areas()\P2 = Val(Trim(StringField(line, 2, ",")))
    areas()\P3 = Val(Trim(StringField(line, 3, ",")))
    If Val(Trim(StringField(line, 4, ","))) Or Val(Trim(StringField(line, 5, ","))) Or Val(Trim(StringField(line, 6, ",")))
      areas()\col = RGB(Val(Trim(StringField(line, 4, ","))), Val(Trim(StringField(line, 5, ","))), Val(Trim(StringField(line, 6, ","))))
    Else
      areas()\col = areacol
    EndIf
  EndIf
  If LCase(Left(line , 4)) = "lcol"
    line = Mid(line, 6, Len(line) - 6)
    linecol = RGB(Val(Trim(StringField(line, 1, ","))), Val(Trim(StringField(line, 2, ","))), Val(Trim(StringField(line, 3, ","))))
  EndIf
  If LCase(Left(line , 4)) = "acol"
    line = Mid(line, 6, Len(line) - 6)
    areacol = RGB(Val(Trim(StringField(line, 1, ","))), Val(Trim(StringField(line, 2, ","))), Val(Trim(StringField(line, 3, ","))))
  EndIf
Until Eof(0)

separate = RGB(1,1,1)


max_punkte = CountList(pnt()) - 1
Dim punkt._2d(max_punkte)

winkel._3f
winkel\x = 0 / 180 * ACos(-1) ;Ganzes um 0,0,0 x-Achse drehen
winkel\y = 0 / 180 * ACos(-1) ;Ganzes um 0,0,0 y-Achse drehen
winkel\z = 0 / 180 * ACos(-1) ;Ganzes um 0,0,0 z-Achse drehen

punkti = 0
ForEach pnt()
  x = pnt()\x
  y = pnt()\y
  z = pnt()\z
  m = x*Cos(winkel\z) - y*Sin(winkel\z)
  n = x*Sin(winkel\z) + y*Cos(winkel\z)
  x = m
  y = n
  m = x*Cos(winkel\y) - z*Sin(winkel\y)
  b = x*Sin(winkel\y) + z*Cos(winkel\y)
  x = m
  z = b
  n = y*Cos(winkel\x) - z*Sin(winkel\x)
  b = y*Sin(winkel\x) + z*Cos(winkel\x)
  y = n
  z = b
  
  ansicht._3f
  ansicht\x = -10 / 180 * ACos(-1) ;NEIGUNG DER ANSICHT
  ansicht\y = 45/ 180 * ACos(-1) ; nicht verändern!
  ansicht\z = 0 / 180 * ACos(-1) ; nicht verändern!
  
  m = x*Cos(ansicht\z) - y*Sin(ansicht\z)
  n = x*Sin(ansicht\z) + y*Cos(ansicht\z)
  x = m
  y = n
  m = x*Cos(ansicht\y) - z*Sin(ansicht\y)
  b = x*Sin(ansicht\y) + z*Cos(ansicht\y)
  x = m
  z = b
  n = y*Cos(ansicht\x) - z*Sin(ansicht\x)
  b = y*Sin(ansicht\x) + z*Cos(ansicht\x)
  y = n
  z = b
    
  punkt(punkti)\x = x
  punkt(punkti)\y = y - z/2
  punkti + 1
Next


scale = 1


Repeat
  ClearScreen(0,0,0)
  StartDrawing(ScreenOutput())
  FrontColor(255,255,255)
  Circle(res_x / 2, res_y / 2, 4)
  FrontColor(255, 255, 255)
  
  For punkti = 0 To max_punkte
    If d = 0
      FrontColor(255, 0, 0)
      d = 1
    Else
      FrontColor(255, 255, 255)
      d = 0
    EndIf

    Circle(scale * punkt(punkti)\x + res_x / 2, -scale * punkt(punkti)\y + res_y / 2,2)
  Next
  ForEach lines()
    LineXY(scale * punkt(lines()\P1)\x + res_x / 2, -scale * punkt(lines()\P1)\y + res_y/2, scale * punkt(lines()\P2)\x + res_x / 2, -scale * punkt(lines()\P2)\y + res_y / 2, separate) 
  Next 
  ForEach areas() 
    FillArea(scale * (punkt(areas()\P1)\x + punkt(areas()\P2)\x + punkt(areas()\P3)\x)/3 + res_x / 2, -scale * (punkt(areas()\P1)\y + punkt(areas()\P2)\y + punkt(areas()\P3)\y)/3 + res_y / 2, separate, areas()\col) 
  Next 
  ForEach lines() 
    LineXY(scale * punkt(lines()\P1)\x + res_x / 2, -scale * punkt(lines()\P1)\y + res_y / 2, scale * punkt(lines()\P2)\x + res_x / 2, -scale * punkt(lines()\P2)\y + res_y / 2, lines()\col) 
  Next
  StopDrawing()
  FlipBuffers()
  ExamineKeyboard()
Until KeyboardPushed(1)
GrabSprite(0, 0, 0, res_x, res_y)
SaveSprite(0, "c:\isotest.bmp")
mit dieser hier (wuerfel.iso)

Code: Alles auswählen

plot(-100, 100, -100)
plot(100, 100, -100)
plot(100, -100, -100)
plot(-100, -100, -100)
plot(100, 100, 100)
plot(-100, 100, 100)
plot(-100, -100, 100)
plot(100, -100, 100)
lcol(0,0,0)
line(1,2)
line(2,3)
line(3,0)
line(0,1)
line(5,6)
line(6,3)
line(0,5)
line(6,7)
line(2,7)
area(1,2,3,0,90,0)
area(6,5,0,90,0,0)
area(2,7,6,0,0,90)
Antworten