Help with 3D
Author |
Message |
Lucas
|
Posted: Sun Mar 20, 2011 2:11 pm Post subject: Help with 3D |
|
|
What is it you are trying to achieve?
wrote a code that lets me rotate 'LUC' on X, Y, and Z axis, but its a wire frame and i would like to able to draw the faces of the objects
What is the problem you are having?
dont know how to tell what faces of the objects i can 'see' and which ones i cant
Describe what you have tried to solve this problem
tried a couple of different techniques
Post any relevant code (You may choose to attach the file instead of posting the code if it is too long)
Turing: |
setscreen ("graphics: 800; 600")
setscreen ("offscreenonly")
var points : int := 44
var ox, oy : int
var x, y, z, tx, tz, ty, xr, yr, zr : array 1 .. points of real
var dx, dy : array 1 .. points of int
var Vx : real := 0
var Vy : real := - 850
var Vz : real := 0
var direction : int
var move : string (1)
procedure initialvalues
% "L"
x (1) := - 1
y (1) := 50
z (1) := 200
x (2) := - 1
y (2) := - 50
z (2) := 200
x (3) := - 100
y (3) := - 50
z (3) := 200
x (4) := - 100
y (4) := 50
z (4) := 200
x (5) := - 1
y (5) := 50
z (5) := 1
x (6) := - 1
y (6) := - 50
z (6) := 1
x (7) := - 100
y (7) := - 50
z (7) := - 100
x (8) := - 100
y (8) := 50
z (8) := - 100
x (9) := 100
y (9) := 50
z (9) := 1
x (10) := 100
y (10) := - 50
z (10) := 1
x (11) := 100
y (11) := - 50
z (11) := - 100
x (12) := 100
y (12) := 50
z (12) := - 100
% "U"
x (13) := 300
y (13) := 50
z (13) := 200
x (14) := 300
y (14) := - 50
z (14) := 200
x (15) := 200
y (15) := - 50
z (15) := 200
x (16) := 200
y (16) := 50
z (16) := 200
x (17) := 300
y (17) := 50
z (17) := 1
x (18) := 300
y (18) := - 50
z (18) := 1
x (19) := 200
y (19) := - 50
z (19) := - 100
x (20) := 200
y (20) := 50
z (20) := - 100
x (21) := 500
y (21) := 50
z (21) := - 100
x (22) := 500
y (22) := - 50
z (22) := - 100
x (23) := 400
y (23) := - 50
z (23) := 1
x (24) := 400
y (24) := 50
z (24) := 1
x (25) := 500
y (25) := 50
z (25) := 200
x (26) := 500
y (26) := - 50
z (26) := 200
x (27) := 400
y (27) := - 50
z (27) := 200
x (28) := 400
y (28) := 50
z (28) := 200
% "C"
x (29) := 800
y (29) := 50
z (29) := 200
x (30) := 800
y (30) := - 50
z (30) := 200
x (31) := 800
y (31) := - 50
z (31) := 100
x (32) := 800
y (32) := 50
z (32) := 100
x (33) := 700
y (33) := 50
z (33) := 100
x (34) := 700
y (34) := - 50
z (34) := 100
x (35) := 600
y (35) := - 50
z (35) := 200
x (36) := 600
y (36) := 50
z (36) := 200
x (37) := 700
y (37) := 50
z (37) := 1
x (38) := 700
y (38) := - 50
z (38) := 1
x (39) := 600
y (39) := - 50
z (39) := - 100
x (40) := 600
y (40) := 50
z (40) := - 100
x (41) := 800
y (41) := 50
z (41) := 1
x (42) := 800
y (42) := - 50
z (42) := 1
x (43) := 800
y (43) := - 50
z (43) := - 100
x (44) := 800
y (44) := 50
z (44) := - 100
ox := maxx div 2
oy := maxy div 2
for a : 1 .. points
x (a ) := x (a ) - 350
if x (a ) > - 1 and y (a ) > 0 then
tx (a ) := arctand (x (a ) / y (a ))
elsif x (a ) > 0 and y (a ) < 1 then
tx (a ) := (- 90 - arctand (y (a ) / x (a ))) + 180
elsif x (a ) < 1 and y (a ) < 0 then
tx (a ) := arctand (x (a ) / y (a )) + 180
else
tx (a ) := (- 90 - arctand (y (a ) / x (a ))) + 360
end if
if x (a ) > - 1 and z (a ) > 0 then
ty (a ) := arctand (x (a ) / z (a ))
elsif x (a ) > 0 and z (a ) < 1 then
ty (a ) := (- 90 - arctand (z (a ) / x (a ))) + 180
elsif x (a ) < 1 and z (a ) < 0 then
ty (a ) := arctand (x (a ) / z (a )) + 180
else
ty (a ) := (- 90 - arctand (z (a ) / x (a ))) + 360
end if
if y (a ) > - 1 and z (a ) > 0 then
tz (a ) := arctand (y (a ) / z (a ))
elsif y (a ) > 0 and z (a ) < 1 then
tz (a ) := (- 90 - arctand (z (a ) / y (a ))) + 180
elsif y (a ) < 1 and z (a ) < 0 then
tz (a ) := arctand (y (a ) / z (a )) + 180
else
tz (a ) := (- 90 - arctand (z (a ) / y (a ))) + 360
end if
xr (a ) := sqrt ((x (a ) ** 2) + (y (a ) ** 2))
yr (a ) := sqrt ((x (a ) ** 2) + (z (a ) ** 2))
zr (a ) := sqrt ((z (a ) ** 2) + (y (a ) ** 2))
dx (a ) := (((100 / (y (a ) - Vy + 100)) * (x (a ) - Vx )) + Vx ) div 1
dy (a ) := (((100 / (y (a ) - Vy + 100)) * (z (a ) - Vz )) + Vz ) div 1
end for
end initialvalues
procedure draw
for a : 1 .. points
dx (a ) := (((200 / (y (a ) - Vy + 200)) * (x (a ) - Vx )) + Vx ) div 1
dy (a ) := (((200 / (y (a ) - Vy + 200)) * (z (a ) - Vz )) + Vz ) div 1
%drawfilloval (dx (a) + ox, dy (a) + oy, 1, 1, red)
end for
% "L"
drawline (dx (1) + ox, dy (1) + oy, dx (2) + ox, dy (2) + oy, red)
drawline (dx (2) + ox, dy (2) + oy, dx (3) + ox, dy (3) + oy, red)
drawline (dx (3) + ox, dy (3) + oy, dx (4) + ox, dy (4) + oy, red)
drawline (dx (4) + ox, dy (4) + oy, dx (1) + ox, dy (1) + oy, red)
drawline (dx (5) + ox, dy (5) + oy, dx (6) + ox, dy (6) + oy, red)
drawline (dx (7) + ox, dy (7) + oy, dx (8) + ox, dy (8) + oy, red)
drawline (dx (9) + ox, dy (9) + oy, dx (10) + ox, dy (10) + oy, red)
drawline (dx (10) + ox, dy (10) + oy, dx (11) + ox, dy (11) + oy, red)
drawline (dx (11) + ox, dy (11) + oy, dx (12) + ox, dy (12) + oy, red)
drawline (dx (12) + ox, dy (12) + oy, dx (9) + ox, dy (9) + oy, red)
drawline (dx (1) + ox, dy (1) + oy, dx (5) + ox, dy (5) + oy, red)
drawline (dx (2) + ox, dy (2) + oy, dx (6) + ox, dy (6) + oy, red)
drawline (dx (3) + ox, dy (3) + oy, dx (7) + ox, dy (7) + oy, red)
drawline (dx (4) + ox, dy (4) + oy, dx (8) + ox, dy (8) + oy, red)
drawline (dx (5) + ox, dy (5) + oy, dx (9) + ox, dy (9) + oy, red)
drawline (dx (6) + ox, dy (6) + oy, dx (10) + ox, dy (10) + oy, red)
drawline (dx (7) + ox, dy (7) + oy, dx (11) + ox, dy (11) + oy, red)
drawline (dx (8) + ox, dy (8) + oy, dx (12) + ox, dy (12) + oy, red)
% "U"
drawline (dx (13) + ox, dy (13) + oy, dx (14) + ox, dy (14) + oy, red)
drawline (dx (14) + ox, dy (14) + oy, dx (15) + ox, dy (15) + oy, red)
drawline (dx (15) + ox, dy (15) + oy, dx (16) + ox, dy (16) + oy, red)
drawline (dx (16) + ox, dy (16) + oy, dx (13) + ox, dy (13) + oy, red)
drawline (dx (17) + ox, dy (17) + oy, dx (18) + ox, dy (18) + oy, red)
drawline (dx (19) + ox, dy (19) + oy, dx (20) + ox, dy (20) + oy, red)
drawline (dx (21) + ox, dy (21) + oy, dx (22) + ox, dy (22) + oy, red)
drawline (dx (23) + ox, dy (23) + oy, dx (24) + ox, dy (24) + oy, red)
drawline (dx (25) + ox, dy (25) + oy, dx (26) + ox, dy (26) + oy, red)
drawline (dx (26) + ox, dy (26) + oy, dx (27) + ox, dy (27) + oy, red)
drawline (dx (27) + ox, dy (27) + oy, dx (28) + ox, dy (28) + oy, red)
drawline (dx (28) + ox, dy (28) + oy, dx (25) + ox, dy (25) + oy, red)
drawline (dx (13) + ox, dy (13) + oy, dx (17) + ox, dy (17) + oy, red)
drawline (dx (14) + ox, dy (14) + oy, dx (18) + ox, dy (18) + oy, red)
drawline (dx (15) + ox, dy (15) + oy, dx (19) + ox, dy (19) + oy, red)
drawline (dx (16) + ox, dy (16) + oy, dx (20) + ox, dy (20) + oy, red)
drawline (dx (17) + ox, dy (17) + oy, dx (24) + ox, dy (24) + oy, red)
drawline (dx (18) + ox, dy (18) + oy, dx (23) + ox, dy (23) + oy, red)
drawline (dx (19) + ox, dy (19) + oy, dx (22) + ox, dy (22) + oy, red)
drawline (dx (20) + ox, dy (20) + oy, dx (21) + ox, dy (21) + oy, red)
drawline (dx (21) + ox, dy (21) + oy, dx (25) + ox, dy (25) + oy, red)
drawline (dx (22) + ox, dy (22) + oy, dx (26) + ox, dy (26) + oy, red)
drawline (dx (23) + ox, dy (23) + oy, dx (27) + ox, dy (27) + oy, red)
drawline (dx (24) + ox, dy (24) + oy, dx (28) + ox, dy (28) + oy, red)
% "C"
drawline (dx (29) + ox, dy (29) + oy, dx (30) + ox, dy (30) + oy, red)
drawline (dx (30) + ox, dy (30) + oy, dx (31) + ox, dy (31) + oy, red)
drawline (dx (31) + ox, dy (31) + oy, dx (32) + ox, dy (32) + oy, red)
drawline (dx (32) + ox, dy (32) + oy, dx (29) + ox, dy (29) + oy, red)
drawline (dx (33) + ox, dy (33) + oy, dx (34) + ox, dy (34) + oy, red)
drawline (dx (35) + ox, dy (35) + oy, dx (36) + ox, dy (36) + oy, red)
drawline (dx (37) + ox, dy (37) + oy, dx (38) + ox, dy (38) + oy, red)
drawline (dx (39) + ox, dy (39) + oy, dx (40) + ox, dy (40) + oy, red)
drawline (dx (41) + ox, dy (41) + oy, dx (42) + ox, dy (42) + oy, red)
drawline (dx (42) + ox, dy (42) + oy, dx (43) + ox, dy (43) + oy, red)
drawline (dx (43) + ox, dy (43) + oy, dx (44) + ox, dy (44) + oy, red)
drawline (dx (44) + ox, dy (44) + oy, dx (41) + ox, dy (41) + oy, red)
drawline (dx (29) + ox, dy (29) + oy, dx (36) + ox, dy (36) + oy, red)
drawline (dx (30) + ox, dy (30) + oy, dx (35) + ox, dy (35) + oy, red)
drawline (dx (31) + ox, dy (31) + oy, dx (34) + ox, dy (34) + oy, red)
drawline (dx (32) + ox, dy (32) + oy, dx (33) + ox, dy (33) + oy, red)
drawline (dx (33) + ox, dy (33) + oy, dx (37) + ox, dy (37) + oy, red)
drawline (dx (34) + ox, dy (34) + oy, dx (38) + ox, dy (38) + oy, red)
drawline (dx (35) + ox, dy (35) + oy, dx (39) + ox, dy (39) + oy, red)
drawline (dx (36) + ox, dy (36) + oy, dx (40) + ox, dy (40) + oy, red)
drawline (dx (37) + ox, dy (37) + oy, dx (41) + ox, dy (41) + oy, red)
drawline (dx (38) + ox, dy (38) + oy, dx (42) + ox, dy (42) + oy, red)
drawline (dx (39) + ox, dy (39) + oy, dx (43) + ox, dy (43) + oy, red)
drawline (dx (40) + ox, dy (40) + oy, dx (44) + ox, dy (44) + oy, red)
end draw
procedure rotateX
for a : 1 .. points
xr (a ) := sqrt ((x (a ) ** 2) + (y (a ) ** 2))
if x (a ) > - 1 and y (a ) > 0 then
tx (a ) := arctand (x (a ) / y (a ))
elsif x (a ) > 0 and y (a ) < 1 then
tx (a ) := (- 90 - arctand (y (a ) / x (a ))) + 180
elsif x (a ) < 1 and y (a ) < 0 then
tx (a ) := arctand (x (a ) / y (a )) + 180
else
tx (a ) := (- 90 - arctand (y (a ) / x (a ))) + 360
end if
end for
for a : 1 .. 30
for b : 1 .. points
tx (b ) := tx (b ) + direction
x (b ) := sind (tx (b )) * xr (b )
y (b ) := cosd (tx (b )) * xr (b )
end for
draw
View.Update
delay (20)
cls
end for
end rotateX
procedure rotateY
for a : 1 .. points
yr (a ) := sqrt ((x (a ) ** 2) + (z (a ) ** 2))
if x (a ) > - 1 and z (a ) > 0 then
ty (a ) := arctand (x (a ) / z (a ))
elsif x (a ) > 0 and z (a ) < 1 then
ty (a ) := (- 90 - arctand (z (a ) / x (a ))) + 180
elsif x (a ) < 1 and z (a ) < 0 then
ty (a ) := arctand (x (a ) / z (a )) + 180
else
ty (a ) := (- 90 - arctand (z (a ) / x (a ))) + 360
end if
end for
for a : 1 .. 30
for b : 1 .. points
ty (b ) := ty (b ) + direction
x (b ) := sind (ty (b )) * yr (b )
z (b ) := cosd (ty (b )) * yr (b )
end for
draw
View.Update
delay (20)
cls
end for
end rotateY
procedure rotateZ
for a : 1 .. points
zr (a ) := sqrt ((z (a ) ** 2) + (y (a ) ** 2))
if y (a ) > - 1 and z (a ) > 0 then
tz (a ) := arctand (y (a ) / z (a ))
elsif y (a ) > 0 and z (a ) < 1 then
tz (a ) := (- 90 - arctand (z (a ) / y (a ))) + 180
elsif y (a ) < 1 and z (a ) < 0 then
tz (a ) := arctand (y (a ) / z (a )) + 180
else
tz (a ) := (- 90 - arctand (z (a ) / y (a ))) + 360
end if
end for
for a : 1 .. 30
for b : 1 .. points
tz (b ) := tz (b ) + direction
y (b ) := sind (tz (b )) * zr (b )
z (b ) := cosd (tz (b )) * zr (b )
end for
draw
View.Update
delay (20)
cls
end for
end rotateZ
initialvalues
loop
getch (move )
if move = "d" then
direction := 3
rotateX
elsif move = "a" then
direction := - 3
rotateX
elsif move = "w" then
direction := 3
rotateZ
elsif move = "s" then
direction := - 3
rotateZ
elsif move = "e" then
direction := 3
rotateY
elsif move = "q" then
direction := - 3
rotateY
end if
end loop
|
Please specify what version of Turing you are using
4.1.1 |
|
|
|
|
|
Sponsor Sponsor
|
|
|
Raknarg
|
Posted: Mon Mar 21, 2011 9:35 am Post subject: RE:Help with 3D |
|
|
I have an idea. Im not sure if it would work, but you could try.
So if you use the Draw.FillPolygon feature, you could basically set the point of all your corners and draw them that way.
So for your program you would just use a polygon for all the faces on your shape.
However theres one issue. You would need a separate array for every face. If you try to draw it with a compund array (which is way simpler) such as array 1 .. 5, 1 .. 5, its not usable for Draw.FillPolygon.
Other-wise, you could put a point for every single dot and draw faces like that.
This means it would require a rediculous amount of code (like Hunters Light Wars 1.0).
But its still possible.
Those are the only 2 ways I can think of of having a 3D picture that isn't wire-frame in turing.
I would suggest looking up that old 3D Hangman game from before though. It has o head thatb is wire-frame like yours but it also has coloured faces. |
|
|
|
|
|
Raknarg
|
Posted: Mon Mar 21, 2011 10:35 am Post subject: RE:Help with 3D |
|
|
Oh, i have one other way.
In the past, I've used a bunch of lines to simulate a polygon. What you can do is for every face, you have a for loop. The line would begin at one corner and continue in a circular fashion until it fills the whole polygon. |
|
|
|
|
|
DemonWasp
|
Posted: Mon Mar 21, 2011 11:34 am Post subject: RE:Help with 3D |
|
|
To actually answer the OP's question:
For each pixel, the face you can "see" at that pixel is the closest one that actually draws to that pixel.
There are a few ways to tackle the problem.
First, you could draw all the faces from back-to-front. This would require a global sort of all faces. This also faces the issue that in some cases a small polygon that should appear behind a larger polygon actually appears in front, because distances are measured from the camera to the middle of the polygon.
Second, you could draw to a buffer and keep track of the "depth", or z-value, of each pixel. This is what a graphics card does when using DirectX or OpenGL (roughly). While this does fix the problem described in the first method, it also introduces the unfortunate performance problem that you need to calculate a distance for each pixel, at each frame. This gets prohibitively slow with Turing (or any language -- generally, this is done on the graphics card, not the CPU -- but particularly Turing is bad).
Third, you could pretend to draw faces by just not drawing edges / vertices that are occluded by forward points. The easiest way to do that would be to "shoot" a ray from the camera to each vertex in an object. Calculate the intersections between that ray and your object (see: http://www.cs.princeton.edu/courses/archive/fall00/cs426/lectures/raycast/sld016.htm ). If there are any intersections which are closer to the camera than that vertex, then you should NOT draw that vertex (this is usually called "culling").
The third option should perform reasonably well, give the vague illusion of having filled volume, and won't suffer the problem in the first solution. However, it is both the least fulfilling in terms of drawing a 3D image, and possibly relatively complex. |
|
|
|
|
|
Lucas
|
Posted: Mon Mar 21, 2011 7:52 pm Post subject: RE:Help with 3D |
|
|
Raknarg - that would draw every face, not the ones i can "see"
DemonWasp - thx, ill try the third one, pretty sure ill understand it
idea though: calculate the average depth of each face, and then draw the polygons in order of the ones furthest back first? |
|
|
|
|
|
DemonWasp
|
Posted: Mon Mar 21, 2011 8:54 pm Post subject: RE:Help with 3D |
|
|
Your idea is listed as the first solution in my previous post.
However, no matter how you calculate the "average depth" of a face, there's a way for a face that SHOULD appear behind it to appear in front instead. Additionally, that method doesn't handle the case where two polygons go right through each other (though neither does my third solution). |
|
|
|
|
|
copthesaint
|
Posted: Tue Mar 22, 2011 11:17 am Post subject: Re: Help with 3D |
|
|
Heres an example of a crappy buffer I made in the last 20 min, sorry for no commenting but I think this will help you.
Turing: | class buff
export add, update, draw
var xVal, yVal, xVal2, yVal2, dVal, clr : flexible array 0 .. - 1 of int
var xSortVal, ySortVal, xSortVal2, ySortVal2, clrSort, dSortVal : flexible array 0 .. - 1 of int
var upBound, maxBound : int := - 1
var upBoundSort, maxBoundSort : int := - 1
proc add (x : int, y : int, x2 : int, y2 : int, d : int, c : int)
if upBound = maxBound then
maxBound := maxBound + 1
new xVal, maxBound
new yVal, maxBound
new xVal2, maxBound
new yVal2, maxBound
new clr, maxBound
new dVal, maxBound
end if
upBound := upBound + 1
xVal (upBound ) := x
yVal (upBound ) := y
xVal2 (upBound ) := x2
yVal2 (upBound ) := y2
clr (upBound ) := c
dVal (upBound ) := d
end add
proc remove (i : int)
xVal (i ) := xVal (upBound )
yVal (i ) := yVal (upBound )
xVal2 (i ) := xVal2 (upBound )
yVal2 (i ) := yVal2 (upBound )
clr (i ) := clr (upBound )
dVal (i ) := dVal (upBound )
upBound := upBound - 1;
end remove
proc addSort (x : int, y : int, x2 : int, y2 : int, d : int, c : int)
if upBoundSort = maxBoundSort then
maxBoundSort := maxBoundSort + 1
new xSortVal, maxBoundSort
new ySortVal, maxBoundSort
new xSortVal2, maxBoundSort
new ySortVal2, maxBoundSort
new clrSort, maxBoundSort
new dSortVal, maxBoundSort
end if
upBoundSort := upBoundSort + 1
xSortVal (upBoundSort ) := x
ySortVal (upBoundSort ) := y
xSortVal2 (upBoundSort ) := x2
ySortVal2 (upBoundSort ) := y2
clrSort (upBoundSort ) := c
dSortVal (upBoundSort ) := d
end addSort
proc update
loop
var iNum : int := - 1
var iNumValue : int := 0
for i : 0 .. upBound
if dVal (i ) > iNumValue then
iNum := i
iNumValue := dVal (i )
end if
end for
addSort (xVal (iNum ), yVal (iNum ), xVal2 (iNum ), yVal2 (iNum ), dVal (iNum ), clr (iNum ))
remove (iNum )
exit when upBound = - 1
end loop
end update
proc draw
for i : 0 .. upBoundSort
drawfillbox (xSortVal (i ), ySortVal (i ), xSortVal2 (i ), ySortVal2 (i ), clrSort (i ))
end for
upBoundSort := - 1
end draw
end buff
var point1 : pointer to buff
new buff, point1
point1 -> add (50, 50, maxx - 50, maxy - 50, 10, black)
point1 -> add (100, 100, maxx - 100, maxy - 100, 3, red)
point1 -> add (75, 75, maxx - 75, maxy - 75, 5, green)
point1 -> add (175, 175, maxx - 175, maxy - 175, 1, blue)
point1 -> update
point1 -> draw |
|
|
|
|
|
|
Lucas
|
Posted: Tue Mar 22, 2011 7:55 pm Post subject: RE:Help with 3D |
|
|
Demon wasp - lol sry, my bad :/
copthesaint - well once i read the turorial on classes and learn what buffers are, im sure itl be very useful thatl maybe take a day or two |
|
|
|
|
|
Sponsor Sponsor
|
|
|
Raknarg
|
Posted: Wed Mar 23, 2011 10:28 am Post subject: RE:Help with 3D |
|
|
whoops, missed the question. -.-' |
|
|
|
|
|
|
|