### Author Topic: A Simple Exploration of _MAPTRIANGLE(3D) Perspective  (Read 103 times)

#### Richard Notley

• Sr. Member
•    • Posts: 349
• QwerKey ##### A Simple Exploration of _MAPTRIANGLE(3D) Perspective
« on: April 23, 2018, 10:29:32 am »
We saw in my Program "3D Bouncing Balls" (qv) the marvellous properties of _MAPTRIANGLE(3D), where quite simple code gives a very realistic representation of 3D effects.  It did appear, however, that the shape of the spherical balls was distorted when the balls were away from the centre of the screen.

The code here shows a simple display of  _MAPTRIANGLE(3D) perspective.  There are 5 views of the same pyramid.  The pyramid sits on a yellow square and points directly upwards to the viewer.

When the pyramid is at the screen centre (x- and y- are zero in the  _MAPTRIANGLE 3D space) the top of the pyramid is closer to the viewer than is the base, although it is not actually obvious because each of the 4 sides is geometrically the same.

However, when the pyramid moves away from the screen centre, the perspective changes the observed geometries of the faces, as it must, to give the 3D effect on the 2D screen.

This is exactly what was observed with the balls, where this effect gives rise to distortions as the sphere is no longer symmetrical.

What I would like to remark upon is the sheer brilliance of the  _MAPTRIANGLE(3D) QB64 construction - whoever implemented this must be in the genius category.

An inspection of the code here will show that for the different views I have not altered the order of the  _MAPTRIANGLE(3D) statements for the faces of the pyramids.  Yet the program somehow knows not to display the hidden face.  How on earth is that implemented when there is no actual code to say "this face is behind the others - do not display it"?

Richard

Code: [Select]
`' Explore _MAPTRIANGLE perspectiveCONST True = -1`, False = 0`_TITLE "3D Bouncing Balls"RANDOMIZE (TIMER)CONST Uscreen% = 1000, Vscreen% = 800CONST Pi! = 4 * ATN(1), PerspDist% = 550'DIM MapConv%(NoPhis%%, NoAlphas%%, 1, 2)''Conversion from 2D'FOR N%% = 0 TO NoPhis%%'    FOR M%% = 0 TO NoAlphas%%'        MapConv%(N%%, M%%, 0, 0) = 128 + CINT(127 * SIN((Pi! / 2) - M%% * Alpha!) * COS(N%% * Phi!))'        MapConv%(N%%, M%%, 0, 1) = 128 + CINT(127 * SIN((Pi! / 2) - M%% * Alpha!) * SIN(N%% * Phi!))'        MapConv%(N%%, M%%, 1, 0) = CINT(Rad1%% * SIN((Pi! / 2) - M%% * Alpha!) * COS(N%% * Phi!))'        MapConv%(N%%, M%%, 1, 1) = CINT(Rad1%% * SIN((Pi! / 2) - M%% * Alpha!) * SIN(N%% * Phi!))'        MapConv%(N%%, M%%, 1, 2) = CINT(Rad1%% * COS((Pi! / 2) - M%% * Alpha!))'    NEXT M%%'NEXT N%%'Screen BackgroundTempImage& = _NEWIMAGE(Uscreen%, Vscreen%, 32)_DEST TempImage&COLOR _RGB(255, 255, 255), _RGB(10, 60, 60)CLSFOR UCol% = 0 TO Uscreen% - 1    FOR VCol% = 0 TO Vscreen% - 1        PSET (UCol%, VCol%), _RGB(100, INT(180 * UCol% / Uscreen%), INT(180 * VCol% / Vscreen%))    NEXT VCol%NEXT UCol%Background& = MakeHardware&(TempImage&)'Square imageTempImage& = _NEWIMAGE(256, 256, 32)_DEST TempImage&COLOR _RGB(255, 255, 0), _RGB(255, 255, 0)CLSSquare1& = MakeHardware&(TempImage&)TempImage& = _NEWIMAGE(256, 256, 32)_DEST TempImage&COLOR _RGB(0, 255, 255), _RGB(0, 255, 255)CLSSquare2A& = MakeHardware&(TempImage&)TempImage& = _NEWIMAGE(256, 256, 32)_DEST TempImage&COLOR _RGB(0, 255, 255), _RGB(0, 225, 225)CLSSquare2B& = MakeHardware&(TempImage&)TempImage& = _NEWIMAGE(256, 256, 32)_DEST TempImage&COLOR _RGB(0, 255, 255), _RGB(0, 195, 195)CLSSquare2C& = MakeHardware&(TempImage&)TempImage& = _NEWIMAGE(256, 256, 32)_DEST TempImage&COLOR _RGB(0, 255, 255), _RGB(0, 165, 165)CLSSquare2D& = MakeHardware&(TempImage&)'Create screenSCREEN _NEWIMAGE(Uscreen%, Vscreen%, 32)_SCREENMOVE 50, 13_DEST 0_DISPLAYORDER _HARDWARE 'do not even render the software layer, just the hardware one.Stereo` = TrueWHILE Stereo`    _LIMIT 120 'Game Frames/Second Rate    Count% = Count% + 1    _PUTIMAGE (0, 0), Background&    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square1& TO(-50, -50, -PerspDist%)-(50, -50, -PerspDist%)-(-50, 50, -PerspDist%)    _MAPTRIANGLE (255, 255)-(0, 255)-(255, 0), Square1& TO(50, 50, -PerspDist%)-(-50, 50, -PerspDist%)-(50, -50, -PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2A& TO(-40, -40, -PerspDist%)-(40, -40, -PerspDist%)-(0, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2B& TO(40, -40, -PerspDist%)-(40, 40, -PerspDist%)-(0, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2C& TO(40, 40, -PerspDist%)-(-40, 40, -PerspDist%)-(0, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2D& TO(-40, 40, -PerspDist%)-(-40, -40, -PerspDist%)-(0, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square1& TO(-50 + 400, -50, -PerspDist%)-(50 + 400, -50, -PerspDist%)-(-50 + 400, 50, -PerspDist%)    _MAPTRIANGLE (255, 255)-(0, 255)-(255, 0), Square1& TO(50 + 400, 50, -PerspDist%)-(-50 + 400, 50, -PerspDist%)-(50 + 400, -50, -PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2A& TO(-40 + 400, -40, -PerspDist%)-(40 + 400, -40, -PerspDist%)-(0 + 400, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2B& TO(40 + 400, -40, -PerspDist%)-(40 + 400, 40, -PerspDist%)-(0 + 400, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2C& TO(40 + 400, 40, -PerspDist%)-(-40 + 400, 40, -PerspDist%)-(0 + 400, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2D& TO(-40 + 400, 40, -PerspDist%)-(-40 + 400, -40, -PerspDist%)-(0 + 400, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square1& TO(-50 - 400, -50, -PerspDist%)-(50 - 400, -50, -PerspDist%)-(-50 - 400, 50, -PerspDist%)    _MAPTRIANGLE (255, 255)-(0, 255)-(255, 0), Square1& TO(50 - 400, 50, -PerspDist%)-(-50 - 400, 50, -PerspDist%)-(50 - 400, -50, -PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2A& TO(-40 - 400, -40, -PerspDist%)-(40 - 400, -40, -PerspDist%)-(0 - 400, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2B& TO(40 - 400, -40, -PerspDist%)-(40 - 400, 40, -PerspDist%)-(0 - 400, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2C& TO(40 - 400, 40, -PerspDist%)-(-40 - 400, 40, -PerspDist%)-(0 - 400, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2D& TO(-40 - 400, 40, -PerspDist%)-(-40 - 400, -40, -PerspDist%)-(0 - 400, 0, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square1& TO(-50, -50 + 300, -PerspDist%)-(50, -50 + 300, -PerspDist%)-(-50, 50 + 300, -PerspDist%)    _MAPTRIANGLE (255, 255)-(0, 255)-(255, 0), Square1& TO(50, 50 + 300, -PerspDist%)-(-50, 50 + 300, -PerspDist%)-(50, -50 + 300, -PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2A& TO(-40, -40 + 300, -PerspDist%)-(40, -40 + 300, -PerspDist%)-(0, 0 + 300, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2B& TO(40, -40 + 300, -PerspDist%)-(40, 40 + 300, -PerspDist%)-(0, 0 + 300, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2C& TO(40, 40 + 300, -PerspDist%)-(-40, 40 + 300, -PerspDist%)-(0, 0 + 300, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2D& TO(-40, 40 + 300, -PerspDist%)-(-40, -40 + 300, -PerspDist%)-(0, 0 + 300, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square1& TO(-50, -50 - 300, -PerspDist%)-(50, -50 - 300, -PerspDist%)-(-50, 50 - 300, -PerspDist%)    _MAPTRIANGLE (255, 255)-(0, 255)-(255, 0), Square1& TO(50, 50 - 300, -PerspDist%)-(-50, 50 - 300, -PerspDist%)-(50, -50 - 300, -PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2A& TO(-40, -40 - 300, -PerspDist%)-(40, -40 - 300, -PerspDist%)-(0, 0 - 300, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2B& TO(40, -40 - 300, -PerspDist%)-(40, 40 - 300, -PerspDist%)-(0, 0 - 300, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2C& TO(40, 40 - 300, -PerspDist%)-(-40, 40 - 300, -PerspDist%)-(0, 0 - 300, 100 - PerspDist%)    _MAPTRIANGLE (0, 0)-(255, 0)-(0, 255), Square2D& TO(-40, 40 - 300, -PerspDist%)-(-40, -40 - 300, -PerspDist%)-(0, 0 - 300, 100 - PerspDist%)    IF _KEYHIT = 27 THEN Stereo` = False 'Esc  to quit    _DISPLAYWENDSYSTEMFUNCTION MakeHardware& (Imagename&)    MakeHardware& = _COPYIMAGE(Imagename&, 33)    _FREEIMAGE Imagename&END FUNCTION`
QB64 Projects: https://www.dropbox.com/s/yzn5uf4dzztao2f/QB64%20Projects.pdf?dl=0

#### Petr

• Hero Member
•     • • Posts: 656 ##### Re: A Simple Exploration of _MAPTRIANGLE(3D) Perspective
« Reply #1 on: April 23, 2018, 12:51:31 pm »
Quote
How on earth is that implemented when there is no actual code to say "this face is behind the others - do not display it"?

Maybe using parameter _CLOCKWISE and _ANTICLOCKWISE?
Thank you for sharing, 3D with MAPTRIANGLE interest me.
Coding is relax.

#### Richard Notley

• Sr. Member
•    • Posts: 349
• QwerKey ##### Re: A Simple Exploration of _MAPTRIANGLE(3D) Perspective
« Reply #2 on: April 24, 2018, 06:16:41 am »
Petr, none of the _MAPTRIANGLE statements in the code here have any additional arguments (and certainly neither _CLOCKWISE nor _ANTICLOCKWISE).  I have never tried _CLOCKWISE or _ANTICLOCKWISE, as they remain a mystery to me - what exactly is going clockwise or anticlockwise in a static triangle??.  So, I remain mystified as to how the software knows not put the image of the backward-facing pyramid faces.  If the equivalent _PUTIMAGE statements were used, all faces would show.

I believe that Ashish is preparing a tutorial (somewhere or other) on coding in 3D.  We shall all benefit from that, I trust.

Richard
QB64 Projects: https://www.dropbox.com/s/yzn5uf4dzztao2f/QB64%20Projects.pdf?dl=0