## Making pixel based 3D objects - VASE

User projects written in or related to FreeBASIC.
BasicCoder2
Posts: 3351
Joined: Jan 01, 2009 7:03

### Making pixel based 3D objects - VASE

These programs don't seem to fit into any particular section of the forum but I thought making 3D objects is a kind of project. This uses the old idea of objects being made up of small pixel sized "boxes" in a 3D array that has interested me for some time as it seems easy to visualize. Dodicat is a master at these demos but I have to keep within my own programming limitations although I have been going over some of his earlier examples for ideas. This is one I added tonight. I have been thinking mostly about how to best generate or even draw and edit these objects. For example to give the vase handles I need to generate a tubular shape bent like the letter C.

It is a continuation of the thread in Tricks & Tips.
viewtopic.php?f=7&t=25951

The rotation of these objects is still not right in that rotating one seems often to cause the other axes to move. Also I need to be able to not just rotate them but also move them about an absolute space while viewing them from different relative positions.

Code: Select all

`'some useful definesConst Pi = 4 * Atn(1)Dim Shared As single TwoPi = 8 * Atn(1)Dim Shared As single RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As single DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 1280,600,32dim shared as any ptr covercover = imagecreate(360,180,rgb(255,255,255))'bload "cover2.bmp",coverfor j as integer = 0 to 179 step 10    for i as integer = 0 to 359 step 10        line cover,(i,j)-(i+10,j+10),rgb(int(rnd(1)*256),int(rnd(1)*256),int(rnd(1)*256)),bf        line cover,(i,j)-(i+10,j+10),rgb(0,0,0),b        line cover,(i+1,j+1)-(i+10,j+10),rgb(0,0,0),b    next inext jput (0,0),cover,transsleepdim shared as integer posx,posy,invposx = 640  'position of iso display on screenposy = 300type POINT3D    as integer x    as integer y    as integer z    as ulong   cend type'make eight points of a absPt'compute max dots to displaydim shared as integer MAX_DOTS'=============   THESE LOOPS COMPUTE MAX_DOTS ==============dim as single col,rowread colread rowwhile col<>255    for angle as single = 0 to 359        MAX_DOTS = MAX_DOTS + 1    next angle    read col,rowwendfor x as single = -250 to 250    MAX_DOTS = MAX_DOTS + 1next xfor y as single = -250 to 250    MAX_DOTS = MAX_DOTS + 1next yfor z as single = -250 to 250    MAX_DOTS = MAX_DOTS + 1next z'==========================================================================dim shared as Point3D abs3D(0 to MAX_DOTS)  'absolute positionsdim shared as Point3D rel3D(0 to MAX_DOTS)  'relative positions after any rotationdim shared as single angle,x,y,z,rx,ry,rz,px,pydim shared as single RotX,RotY,RotZdim shared as single ratioX,ratioY,ratioZRotX = 0rotY = 0rotZ = 0'creates pointsdim as integer iidim as single dx,dyrestore VaseOutLineDataread rowread colwhile col<>255    for angle as single = 0 to 359        dx = cos(angle*DtoR)*col        dy = sin(angle*DtoR)*col        abs3D(ii).x = dx        abs3D(ii).y = dy        abs3D(ii).z = row - 100        abs3D(ii).c = point(angle,row,cover)        ii = ii + 1    next angle    read row,colwend'create axis pointsfor x as single = -250 to 250    abs3D(ii).x = x    abs3D(ii).y = 0    abs3D(ii).z = 0    abs3D(ii).c = rgb(255,0,0)    ii = ii + 1next xfor y as single = -250 to 250    abs3D(ii).x = 0    abs3D(ii).y = y    abs3D(ii).z = 0    abs3D(ii).c = rgb(0,255,0)    ii = ii + 1next yfor z as single = -250 to 250    abs3D(ii).x = 0    abs3D(ii).y = 0    abs3D(ii).z = z    abs3D(ii).c = rgb(0,0,255)    ii = ii + 1next z' sub coded by dodicatSub QsortZ(array() As Point3D,begin As Long,Finish As Ulong)    Dim As Long i=begin,j=finish    Dim As Point3D x =array(((I+J)\2))    While I <= J        While array(I).z > X .z:I+=1:Wend        While array(J).z < X .z:J-=1:Wend        If I<=J Then Swap array(I),array(J): I+=1:J-=1    Wend    If J >begin Then QsortZ(array(),begin,J)    If I <Finish Then QsortZ(array(),I,Finish)End Subsub rotatePoints()        dim as single cosAngleX,sinAngleX,angleX    dim as single cosAngleY,sinAngleY,angleY    dim as single cosAngleZ,sinAngleZ,angleZ        angleX    = RotX*DtoR        cosAngleX = cos(angleX)    sinAngleX = sin(angleX)        angleY    = RotY*DtoR        cosAngleY = cos(angleY)    sinAngleY = sin(angleY)        angleZ    = RotZ*DtoR        cosAngleZ = cos(angleZ)    sinAngleZ = sin(angleZ)        '=========================================    'dim as single x2,y2,z2,x3,y3,z3    dim as single newX,newY,newZ,x,y,z        for i as integer = 0 to MAX_DOTS - 1                x = abs3D(i).x        y = abs3D(i).y        z = abs3D(i).z                '***Rotation on the X-axis        NewY = y*cosAngleX - z*sinAngleX        NewZ = z*cosAngleX + y*sinAngleX        y = NewY        z = NewZ        '***Rotation on the Y-axis        NewZ = z*cosAngleY - x*sinAngleY        NewX = x*cosAngleY + z*sinAngleY        x = NewX                '***Rotation on the Z-axis        NewX = x*cosAngleZ - y*sinAngleZ        NewY = y*cosAngleZ + x*sinAngleZ        rel3D(i).x = NewX        rel3D(i).y = NewY        rel3D(i).z = NewZ        rel3D(i).c = abs3D(i).c            next i        'sort by distance along z axis    Qsortz(rel3D(),Lbound(rel3D),Ubound(rel3D)) '***dodisort code ***    end subsub update()        screenlock    cls    'draw points in rel3D list    for i as integer = 0 to MAX_DOTS-1        'circle (rel3D(i).x + rel3D(i).z + posx, rel3D(i).x + rel3D(i).y - rel3D(i).z + posy),1,rel3D(i).c,,,,f        circle (rel3D(i).x - (-rel3D(i).z) + posx,((rel3D(i).x + (-rel3D(i).z) ) / 2) + posy + rel3D(i).y),1,rel3D(i).c,,,,f    next i    locate 2,1    print " USE X,Z and arrow keys to change rotations"    print    print " Space bar resets all degrees of rotation to start"    print    print " rotX ";RotX;"  rotY =";RotY;"  rotZ =";RotZ    screenunlock    end subupdate()dim as single now1now1 = timerdo    'getmouse mx,my,,mb   ' if timer - now1 > 0.01 then   '     now1 = timer        rotatePoints()                if multikey(&H39) then  'space key to reset all angles of rotation to zero            rotX = 0            rotY = 0            rotZ = 0            while multikey(&H39):wend        end if                'rotate around x axis        if multikey(&H48) then            RotX = RotX + 1            if RotX = 360 then RotX = 0        end if        if multikey(&H50) then            RotX = RotX - 1            if RotX < 0 then RotX = 359        end if                'rotate around y axis        if multikey(&H4B) then            RotY = RotY + 1            if RotY = 360 then RotY = 0        end if        if multikey(&H4D) then            RotY = RotY - 1            if RotY < 0 then RotY = 359        end if                'rotate around z axis        if multikey(&H2C) then   'Z KEY            RotZ = RotZ + 1            if RotZ = 360 then RotZ = 0        end if        if multikey(&H2D) then   'X KEY            RotZ = RotZ - 1            if RotZ < 0 then RotZ = 359        end if            'end if        update()        sleep 2loop until multikey(&H01)VaseOutLineData:data 0,0,1,1,1,2,2,3,3,4,4,5,5,5,6,5,7,6,8,6,9,6,10,6,11,6,12,6,13,6,14,6,15,6data 16,6,17,6,18,6,19,6,20,6,21,6,22,6,23,6,24,6,25,6,26,7,27,7,28,7,29,7,29,8data 29,9,29,10,30,11,30,12,31,13,31,14,32,15,32,16,33,17,33,18,34,19,34,20,34data 21,35,22,35,23,35,24,35,25,36,26,36,27,37,28,38,29,39,30,40,31,41,31,42,31data 43,31,44,31,45,31,45,32,45,33,45,34,45,35,45,36,45,37,46,38,47,39,48,40,49data 41,50,42,51,43,52,43,53,44,54,44,55,45,56,45,57,45,58,46,59,46,60,46,61,46data 62,47,63,47,64,47,65,48,66,48,67,48,68,48,69,48,70,48,71,48,72,49,73,49,74data 49,75,49,76,49,77,49,78,49,79,49,80,49,81,49,82,49,83,48,84,48,85,48,86,48data 87,48,88,48,89,48,90,48,91,48,92,48,93,47,94,47,95,47,96,47,97,47,98,47,99data 47,100,47,101,46,102,46,103,46,104,46,105,46,106,46,107,45,108,45,109,45data 110,45,111,44,112,44,113,44,114,43,115,43,116,43,117,42,118,42,119,41,120data 41,121,40,122,40,123,39,124,39,125,38,126,38,127,37,128,36,129,36,130,35data 131,34,132,34,133,33,134,33,135,32,136,31,137,30,138,29,139,28,140,27,141data 26,142,24,142,25,143,23,144,22,145,21,146,19,146,20,147,18,148,16,148,17data 149,15,150,14,151,12,151,13,152,10,152,11,153,10,154,10,155,10,156,10,157data 10,157,11,157,12,157,13,157,14,157,15,158,16,159,17,160,17,161,18,162,19data 163,19,164,20,165,20,166,21,167,22,168,23,168,24,169,25,169,26,169,27,170data 27,171,27,172,27,173,27,174,27,175,27,176,27,177,27,178,0,178,1,178,2,178data 3,178,4,178,5,178,6,178,7,178,8,178,9,178,10,178,11,178,12,178,13,178,14data 178,15,178,16,178,17,178,18,178,19,178,20,178,21,178,22,178,23,178,24,178data 25,178,26,178,27,255,255`
Last edited by BasicCoder2 on Oct 02, 2017 8:35, edited 2 times in total.
BasicCoder2
Posts: 3351
Joined: Jan 01, 2009 7:03

### Re: Making pixel based 3D objects - MOON

This is the same as the Earth example except I have used 16 shades of gray instead of just two colors.

Code: Select all

`'some useful definesConst Pi = 4 * Atn(1)Dim Shared As single TwoPi = 8 * Atn(1)Dim Shared As single RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As single DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 1280,600,32dim shared as any ptr moonMap2moonMap2 = imagecreate (90,180)dim as string datum,chardim as ubyte bytfor j as integer = 0 to 180    read datum    for i as integer = 0 to 90        char = mid(datum,i+1,1)        byt = asc(char)-65        byt = byt * 8        pset moonMap2,(i,j),rgb(byt,byt,byt)    next inext j'bload "monomoon.bmp",moonMap2put (0,0),moonMap2,transprintprint "  PRESS SPACE ARROW KEY"sleepdim shared as integer posx,posy,invposx = 640  'position of iso display on screenposy = 300type POINT3D    as integer x    as integer y    as integer z    as ulong   cend type'make eight points of a absPt'compute max dots to display and total dots to rotatedim shared as integer MAX_DOTS'=============   THESE LOOPS COMPUTE MAX_DOTS AND TOT_DOTS ==============for angle1 as single = 0 to 179    for angle2 as single = 0 to 359        MAX_DOTS = MAX_DOTS + 1    next angle2next angle1'TOT_DOTS = MAX_DOTS   'only rotate first TOT_DOTS'create axis points not rotatedfor x as single = -250 to 250    MAX_DOTS = MAX_DOTS + 1next xfor y as single = -250 to 250    MAX_DOTS = MAX_DOTS + 1next yfor z as single = -250 to 250    MAX_DOTS = MAX_DOTS + 1next z'==========================================================================dim shared as Point3D abs3D(0 to MAX_DOTS)  'absolute positionsdim shared as Point3D rel3D(0 to MAX_DOTS)  'relative positions after any rotationdim shared as single angle,x,y,z,rx,ry,rz,px,pydim shared as single rotX,rotY,rotZdim shared as single ratioX,ratioY,ratioZrotX = 0rotY = 0rotZ = 0'now give values to dots on sphere surface'creates pointsdim as integer iidim as single radiusradius = 60for angle1 as single = 0 to 179    for angle2 as single = 0 to 359        abs3D(ii).c = point(angle1\2,angle2\2,moonMap2)        abs3D(ii).x = radius * sin((angle1)*DtoR) * cos((angle2)*DtoR)        abs3D(ii).y = radius * sin((angle1)*DtoR) * sin((angle2)*DtoR)        abs3D(ii).z = radius * cos((angle1)*DtoR)        ii = ii + 1    next angle2next angle1'create axis pointsfor x as single = -250 to 250    abs3D(ii).x = x    abs3D(ii).y = 0    abs3D(ii).z = 0    abs3D(ii).c = rgb(255,0,0)    ii = ii + 1next xfor y as single = -250 to 250    abs3D(ii).x = 0    abs3D(ii).y = y    abs3D(ii).z = 0    abs3D(ii).c = rgb(0,255,0)    ii = ii + 1next yfor z as single = -250 to 250    abs3D(ii).x = 0    abs3D(ii).y = 0    abs3D(ii).z = z    abs3D(ii).c = rgb(0,0,255)    ii = ii + 1next z' sub coded by dodicatSub QsortZ(array() As Point3D,begin As Long,Finish As Ulong)    Dim As Long i=begin,j=finish    Dim As Point3D x =array(((I+J)\2))    While I <= J        While array(I).z > X .z:I+=1:Wend        While array(J).z < X .z:J-=1:Wend        If I<=J Then Swap array(I),array(J): I+=1:J-=1    Wend    If J >begin Then QsortZ(array(),begin,J)    If I <Finish Then QsortZ(array(),I,Finish)End Subsub rotatePoints()        dim as single cosAngleX,sinAngleX,angleX    dim as single cosAngleY,sinAngleY,angleY    dim as single cosAngleZ,sinAngleZ,angleZ        angleX    = rotX*DtoR        cosAngleX = cos(angleX)    sinAngleX = sin(angleX)        angleY    = rotY*DtoR        cosAngleY = cos(angleY)    sinAngleY = sin(angleY)        angleZ    = rotZ*DtoR        cosAngleZ = cos(angleZ)    sinAngleZ = sin(angleZ)        '=========================================    dim as single x2,y2,z2,x3,y3,z3    for i as integer = 0 to MAX_DOTS - 1        x2 = (abs3D(i).x * cosAngleZ) - (abs3D(i).y * sinAngleZ)        y2 = (abs3D(i).x * sinAngleZ) + (abs3D(i).y * cosAngleZ)        x3 = (x2 * cosAngleY) - (abs3D(i).z * sinAngleY)        z2 = (x2 * sinAngleY) + (abs3D(i).z * cosAngleY)        y3 = (y2 * cosAngleX) - (z2 * sinAngleX)        z3 = (y2 * sinAngleX) + (z2 * cosAngleX)        rel3D(i).x = x3        rel3D(i).y = y3        rel3D(i).z = z3        rel3D(i).c = abs3D(i).c            next i    'sort by distance along z axis    Qsortz(rel3D(),Lbound(rel3D),Ubound(rel3D)) '***dodisort code ***    end subsub update()        screenlock    cls    'draw points in rel3D list    for i as integer = 0 to MAX_DOTS-1        'circle (rel3D(i).x + rel3D(i).z + posx, rel3D(i).x + rel3D(i).y - rel3D(i).z + posy),1,rel3D(i).c,,,,f        circle (rel3D(i).x - (-rel3D(i).z) + posx,((rel3D(i).x + (-rel3D(i).z) ) / 2) + posy + rel3D(i).y),1,rel3D(i).c,,,,f    next i    locate 2,1    print " USE X,Z and arrow keys to change rotations"    print    print " Space bar resets all degrees of rotation to start"    print    print " rotX ";RotX;"  rotY =";RotY;"  rotZ =";RotZ    screenunlock    end subupdate()dim as single now1now1 = timerdo    'getmouse mx,my,,mb   ' if timer - now1 > 0.01 then   '     now1 = timer        rotatePoints()                if multikey(&H39) then  'space key to reset all angles of rotation to zero            rotX = 0            rotY = 0            rotZ = 0            while multikey(&H39):wend        end if                'rotate around x axis        if multikey(&H48) then            rotX = rotX + 1            if rotX = 360 then rotX = 0        end if        if multikey(&H50) then            rotX = rotX - 1            if rotX < 0 then rotX = 359        end if                'rotate around y axis        if multikey(&H4B) then            rotY = rotY + 1            if rotY = 360 then rotY = 0        end if        if multikey(&H4D) then            rotY = rotY - 1            if rotY < 0 then rotY = 359        end if                'rotate around z axis        if multikey(&H2C) then   'Z KEY            rotZ = rotZ + 1            if rotZ = 360 then rotZ = 0        end if        if multikey(&H2D) then   'X KEY            rotZ = rotZ - 1            if rotZ < 0 then rotZ = 359        end if            'end if        update()        sleep 2loop until multikey(&H01)data "MLKLKKJIIHIIGFGGFFFFFFFGDFDEEEEGEGGFFGIGIJKKIJKKIJIILJJJKKHIJHIIIIJJIIIIHHIIIKJIIKKKJJJKKJ"data "LLKLJKKKGHJHHHHFFEGGGHGFFEDEEEEEFGFHGHHHHHIIIIIIJKJJJKJJLKIJJIJMLJJIKMJHHHHJIJJIJKKJJJJJKI"data "MKKKJKKKIHGGIIHGEFEFGFFFGEDEDEEFEGFGHHLIHIIHHHHJJJIIIIIJKJJIIJKNMKJIKKIKGHHIJJJJJKKJJKJKJI"data "NKKLJILKIHGGGGGGFFFFEFFFFFEEEEEFHFFGHIJIHIHHHIIIHKKKHHIJLKIGHILKJJKKJKLIIKIHMJJKIKKJILJLJI"data "NKKLJJKKIGFGGHFFFHGFEDGFGFEEEEDGEFFEHKJJIIGGHHIIIJKKJHJJKKHHHJKIIJKLKJJIJLHHMKJKIJKJIKJLJI"data "NKKLJKKKIIIGHGEEDEFDEEEEDEEDEDDEFFFGJIJHIIHHHIHHKJLLJKJIJIGHHHKKJHLJKIILHIIHLJJKJJJJJJJLJI"data "NKKMKKLKHHJFGHFFEEFDFEDEEDCDEDDEFHHGHJLKKKJIIJIIIJJJJJKKLHHJJJKKJIIIIHHJJHHHJJJKKJKJJJJLJI"data "OKKMKLMJKIHHHHFEEFFFEEEEEFEEEEFEGIHHHIMKJIIIIHGGIJJIIHJLLKJJIIIJIIIIIHGJIHHIKJJLKJKKJKJKII"data "OJLLKJIIIHGIIHIGFFFEFEFFFHGFGFFFFGGJILILKJKHJIIIHJJJJKKLLKJJIIIIIIIJHHHIIJIIJIIJKJKKJLJJIH"data "NIKLMJKJHGGHHGGFFEEEEEEEFEEEFGFGGHIHKJKKJIIIJKIJIJKKJLJJJKLKIIIJJIHJHIIHHJGIJJIJKJKKJLJJIH"data "NJJLLIIIHGHHGGFFDEEEEDDEEEDDDEEFFGHIGHIIIHHHILJJHIHJLKGKJKJKJJIIIIHIJIHHIIHIJJIJKJKLJKJJJI"data "NKJKLIIIIHGGGGFFDEEEEEDDCEFFFEEFEGGFHHIIIIIHIIJJGIHHHGIJJIJJIJKIIHIIJJHIJHIJJJJJKKKLJKJJJI"data "NKKKLJJIHHHGGGFFEEEEEDDDCEFEFEEFFGGGGHGHIJJJKIHHIHIHIHIJIJJJJIIJHIHIMKGHIIIJIHIJKJKLKKJJJH"data "NJLKLJKIHIHGGFFEDDEEDDEFDDDCFEEDFGFGHIGHJJJJJJHHIHHHHGJHIIJIJIJJIIHJLLGHIIIJIHIIKJKKKKJJJH"data "NJKJKJKIHIIGFGFEEEDEEDEEDEEDFFEEGFEHHHJKIHJJJIHHHIIGGGJIJKIJJJJIIIIIHHGHJIJKHHIKJJJKLLLJJH"data "NJJJKJJJHHHGGFGEEFEFFDEEEFEFFEEEFFFGHHJIHIIHIHHGGIJIHGHIJKLJJJJJIIJHHHHIIIKJHIJJJKJJLKLIKI"data "NKIKKKJJHIHIHGGEEFEFFDEFEFGFFFEEGFGHHIIIIHIJHHHHHIHHHIHIJKKIIJKMKJIJIHJHILLKIIIJJKJJLLMIJI"data "NKIKKKJJHIHIHGFEEEEEEEEFEFFFFGFFHGGGIHHIIIIJHHIIIIGHGHHHHJIJIJJLLJJIHGJHJMKLIHIJJKJJKLMJJH"data "OJILKIHIJHIHHGFFFEEEFFFFFEEFFIHGFFGGHIHHIHIIIIJIIIHGIIIHHIIJJJKLMKJIHHHGIJJJHJHJKJKKJLMJJI"data "NJJKKJHIIHIIFFGEFFEEFEEFFFFHHIHGIIGGHHHHHHHHIJIJIHHHHHIIIHIIIIJKKKIHHGHJJIIIIIHJJKJKLLMJJI"data "OJIKKKIJJIIGGGIFEFFEEEGFFFFGHGGIIFGHHHGHIIIHKJIIJJIJIIHJIIIIIIIJJKIIHHHIIIHHJIIJIKKKKMLKJH"data "NIKJKKJJJIIFGGHGEFFFEEGGFGHIIHHIHFGGHGGHHIJIKJKIJIIJIHHIIIIIIIHIJJIIHHIHIHIIIHIJJKKKJMLKJH"data "OJKJJJKKIJIFFGGFHEEFFFGGHIIHHHHIHGFGIHHHGIIJKKJJIHIHIJHIIIJIHIIIJIIIJJGIIHIHHIIIKJJJJMLLJH"data "OJKKJJJJIHHGHGGFFEGFGHFGHHHHGIKHGGFHHHGGHHKKKLJJJJJHIGHHIHIJJIIIIHHHIIHIIIHHIHIIIJJKJLLLJI"data "OJLKJIIJIIHHHGFFFFFGHGHGGHHIJHHHGFHGHHGGGHIHIIIJHIHHHHHHHIHJJIHGGHJIGIIJIHHIIHIIIIJJJKKLJI"data "NJKKKIIJJJHHGHFFFFGFFGHHFGHHIHIHGHHGFGGGIHIIKJFGIHHIJHHHHHHKHHGHHIIHHHIHIIGIHHIHIHJIJKKLJI"data "NIKKKJIIKKHHFHGFFFGFGGGGGGGHHHHHHHHGGGFFHHHIJIHIHIHIIHHHHHGJHHGHHIIHHGHHIIHIHHHGHIJIJKKKJI"data "NIKKKIIJJIIHGHGGGFFHGFGFGHHGGGGHHGGJGGHHFIIIJJHIGGILJIHHHGGJIGHIIHHGGHHHIHHIIIHJHIJJKJLKIH"data "NILLKIIJJHHHIFHFHGGIHHGGHGHGGGGGIJIIGGGGHHIHIHIIHHHIIIJIIGGJHIHGFHJHHHIGHHIHIGIJJIKIKKLKII"data "NIKLJIIJJIIHHHGHIHKHGHFGGHGGGGGGHIGIGHHHHGGGHGHKHHJJHJJJHGGHHJHFGGGIIHIGIIHGIGIIJIKIKJKJII"data "NIKLJJIJJIIIHHGHIGJGGGFGGGHGGGGFGGGGHGGGHGGGHHGIHHJJIJJJGHHHIIHFHGGHHGHGHHHHHGHIJIKIKJJJJI"data "MHJLJIIIHIHJHHIHFGGHHGGHHHFGHGGHHIHHHHGGFHGGGGGGIIHIJJJIHHIHHHGIGIGHIIHIHGIHIJHIJJKIKJKKKI"data "NHKLJIJIIIIHHHHHHIIHGHHGHGGGGGGGGIIIHGHGGGGGHHGIJHHIJIIJJHGGHGGFGGKHIIHIHHHHHHHIJJKJKKJILI"data "NIKKJIJJHIIHIJHHHHIHHHGGGGGGGGGGGIIIIHJIHHHHGIIIHHJJJIIIHFFGGGGHHHIGHJIHHHGHHHHJJJJJJJJIJI"data "NIKKJIJJIIJHIIHGHHGHHHGGGGGGGGGHGHHIIHIIIHHHHIIIHIJJJIJHGGGGGHGHGHIIGHHIHHGHHGHIJJJIJIJIJI"data "OJJKJIJJIIIIHGIHIHHIHGHFHGFGGHHHIIIIIJJJJGHHJIJJIJIIKJIGGHGHHHGGHIJIGGGHHHHIHHHIJJIJJJJIJJ"data "OKJLKJIJJIHIIHHJIHHIGHGGGGGFHJJHIIJIJJKLJIHHIJJIIIIJIHIGFGGHGGHHIJJJIHGGHHJHIHIIKJIMJKJHIJ"data "NKIKJKJJJIJIIIIIHGHHHGGGGGGGGIIJIIJKJKKJJIIJHJJIHGHIIHHHHGFHGGGGHJIIGHIGHGIIHHIJJIIKJKKHIJ"data "OKIKKKJKIJHJIIJIHHKGGHGGGGGGHHHIIHHIILKIJJIIIIKIHHHIHGGHHGFFGFGGGIHIGGGGHHHIHIIJJJJKJKKHII"data "OKIKKKJJIJIJJHIIIHLGHIGGGGGHGHHJJJIHJLKJJJIIIINKGHHHHGGIIGGGGFGGGHHHHGGHHHHHIIIJJJJKJKJHII"data "OKIKJLLIIIJIIJIJHGGJHHGGGGGGGHHGJGIEGJLKKIIIHIKJIGGGGGHHHHFGFGHGGHGHHHGHGHHHJIIIKIKJJKIHIJ"data "OKIKKLKKIJJIHIHHGHHGHHGGGHGGGIGGHGEDDIKLKJIJHIIIHGGHFFGGGHFFGGHIHHGGIGIHHGIIIJJJJJJJJKJIII"data "OJIKKKJKIJJKKIHHHHHGIHFGGHGIHIGGICEEGFLMJIIIIHIIGHIIHHHJJHFGFGGHGGGHHGHHHHJJIKJJKJJIJKJIII"data "NKIJKKJKJIJKLJJHHHGFIIGHGHGJHHIIICCEGHHJJIIHIHIIGGIJHGGJJHIIHGGGGGGHGHHJIIJKIKJIKJJIJKJIII"data "NKILKKKJJJJJHLKHHIHHGGIHHGHHHHIHIEFCFJKLIJIIHGIIGHHHHHHHHHHGGFGHHGGHGHHIIIKJJJKJJJJJJKJIJI"data "OKILJKJJILJIIIJHIHHIGHKIGGGHHHIIKHHHHHIGJIIIIGHGGGGHGHIHHHHEFGGGGFHIFJHIHGIJKIKJJJJKJKLIJI"data "NKILKLJKJJJIJJHHHHHIHHIIGHHIIIIJJIIKHFIHIHHHIHGHHEGGGHLFGGGFFFGFFFFFGGHHHHHIJJJKJJJKKKLJIJ"data "NJILKLJKKIKIIJHGIHIGGGHHHHGIIHIJIHFHEHHIHGHGHHHHHGGGGHHFGFFGFGGGGFFEGHIHGIIIJIKJJJJKLKLJIJ"data "NIILKKJKKJJIJJIJHIIHHHHHHHGHIHIIJIIGHGFFGHGGGGHHGHHHHGHGEGDDFDFFFGFFGGHHGIGKKIJJIJJJMLLJIJ"data "OIJLLKKKKKKIIIIHGIHGGHIHGGHHHHHGHKIHHGFHGGHFGGHIIHFFFFGEECCCEDEEEEFFFFHGHHGLJKIJJJJJNMKIJJ"data "NJIKKKKLLJJJJIJIIIHHHHGGHGHGHHHHGHGHHHHHHGFFFGIIIHGFFFEDCCCCCBEDDEEFGGFGHGIIKJKJJKKKNMLJJJ"data "NJIKKKKLKJJJIJJJIIHHHHIHGHIFGHGHGGGHGGGGHGGFFGFGHGHGFFCDDDDDBBECCFDDFGGHGGJHKJKKJKJKMMLKJJ"data "MJILKKKKKJJJJJJIHIHIHHHHGHFGGGGHGHGGFGFFGGFFHJHHHHFDCDCEECCDCCBCCGCCECGFFGHIJIKJIJJKKMLKJJ"data "MIJKKKKKJJJKJKJKHIIIHIHGGHGIGGGHGGHFGHGGGGGGGHGGFGDECDCBDDDDCCBDCCCDDEECEGHJJJJJIJJKLMMKKK"data "LHJKKLKIKJJJJLJKIIHIHHGGGHHHFGGGHGJGGGGHGFEGIGGGEFCBBBBCDCDDBCCCCCCCCDEDEGIJIJJKJKKKLLNKLK"data "LIILJKKJJJKJKKJIIHHGIHGHGHHGHGGHHIHGFFHGFADEGGHGFEDCCCBCBBCBCECCCCCCDDEDEGIJKJJKKKKLKLNJKK"data "MIJLJJKLKJJIKJKIIHGGHHGGHGGFGHHGIJIHDHGGGCCCGGGGEDCCBCCCBCCBCDCCCCCCDDEDFGIJKKJKKKKLKLOJKK"data "MHJJJJKLLKNJKKJHIGFHGHGHJFFFGFFJLKJHHEFGGLFGCEEECBBBBBBDCBBCBBBCCCCCDDEFGHJIKLKMKLKLLLNKJK"data "MIHKJJLKKLLKKLJIHGGGGGHIHGHHGGGJLJHHGGGGGFEDDBCBBBBBCABBCBBBCBCCCCCDDEEGHHJIMKLMLLKLMLMKJK"data "MIHKKJKJMMNKJKJIIIHGGGHHIIJHGIHHHIHHEHHGEDDCBBBBCBBBBBBBBBBBBCCCCCCDDEEGHIIJLJMNLLKLLLLKJJ"data "NIIKKJKJMMNKKKJIHHHHGHHGHIIGHIGGGHHGFGGFEDCABBABCBBBBBBBBBBBBBCCCCCDDEEGHIIJKKMNMMKLMKLJJJ"data "MIIKJKJJMNNKKKJIIHHHGHFDFGGGGGFHIHFGEEEDCBABBBBBCBBAABBBBBCCCCCCDCDDDDEFGGIJJKMMMLKKMKLKKJ"data "LIIJKKKLMMNKJKKJIHHGGGGDEEFIGHGGHGDEFECBCBBBBBBBBBBABBBBCCCCCCBCCCCDDDDFGHHIJJLMLLKLMLKKKJ"data "LJIKJKLLKMMKJJKJIIHGGHFGFFGGGHIKGEEEEEEDABBCABBBBBBBBBCDCDCCCCCCCDCEEDCFGHHJILMMLLLMNLLJJJ"data "LJIKJKKLLLLKJJLJIIHGGHEHGEGGHIIGHEFFDDEEABBCABBBBBBBBBBDCCCCCCCDCDCDDCCGGHHJJLLMLLLMNLKJJJ"data "KJIKKKJMKKLKKJLJGGFFFEFGHGGFHIHHEGFFEEDCCCCCBBBBBBBBBBBDGFDDCCCCCCCDEDDEFGGIJKKLKLLMMKKKJI"data "KJIJKKKKKLKMJJJJGFFGFEEFGFEGHGHFHEFHEEDCBBBBBBBBBBBBCBCCEDEDDCCCCDEFFDDEFFHIIILKKLLMMKKKJJ"data "KJIJKKLLKLKKJKJKHFFEFFEEHGEEEGHBDCDFEEDCCBBBBBBBBBBCCBBDDDCDDDCEEFEGFDFGFGHHIIJKKLMLMLKJJJ"data "KKIJKKKLKKLKKJILGGHGGGFFGFEDGEFCDCCDEECCBBBBBBBCDDCCCCCDDDDCDCCDDEEGIHFHEEHGIIJJKKLLNLKKKJ"data "KLIJKJJLJKLKJJILGHHGFFGGGFEEFEECCBCCFFCCBBCCBBCDCDCCCDDCCDDCDCDDDEFFGGFGDEIHIIJJKKMLNLKKKJ"data "KKHKIJKLKKKJJKJJHGGHFGGGHGFEGDDCBCBCEFFDCCBBBBDEEEDDDDCCBCCCCCDDFEEFHGFEEEGHIIJJJLMLMLKJLJ"data "KKHKKLKLKJJJIKHHHHHHGHGHHHGFDEEBBBCBCDBCBCBBBDEFFFEDDCCCCCCCCCCDDEGHHGHFDEGGHHJKILMKMLLKKJ"data "KJHJJLLLKLJKIJIHGIHHIIGIHFGFGEFDBBCCCDBBCBCCCDBCEEDCCCCCCCDCCCCCCDCDFHHHEFFGHIIJKMMKLMLLJK"data "KJIKJLKLKLKKJJJHHIHHHIHHHGGGFGFECCDCBCCCCDCBCCCCDDCBDCCCCBDCCCCCCDCDFHGHFFFGHHIJKMMKLMLKJK"data "LJJKKLKKKKKJJJIIHHIHGHHGHGGFDEFECDEDEBBBDCCDBCDDDDCCDCCCCCCCCCCCCBCDEFFGFGHFHHJJLMMLLLLKIK"data "KJJLJLLJKJKJKJIKHJHGHGHGHGGDCDBEEDCDACDCEFCDCDBDDDDDFDDEDCBCCCCCCBCDEFFGFFFGHIIKLLMLLLKJHK"data "LJKKKKLKJJJJJJJJKIIHHIGGGHHHEFEDBCDEFDBCBECCDDDDEDFFDECCCBBCCBCBBBDCFGGFFGEGIIJKLKMLKLKIHK"data "LJLKKJLLKJJKLKIJKKJIIHHIGIGHDEFDCCDEEECCBCDCDDEDEEGGDDDCBCCCCCCCBBCCFFGGEGEFIIKLMKMNKLKIHK"data "LJLMLJLLKKKKJJKIHJKHIIHIHHGGFEEEECEDEFCBCCCCDDDEDFEEEDDCDCCCBBCBBCBBDDFFEEFEHHHKMLMMKLKIHK"data "LJKMMKMLKKLKLKJKHHJKHIIHJGIFIJEDCDECCDCCCDEDDDEDFIGFEDCDCCCCCBBBCCCBDEFFGEEFIIIKLMLMLLKJIJ"data "LJKKKJMMLKLMLLKJLKJJJIJJIHHJJFEBCCCDDECCDEEDDFEEDGGFEDCCCCCCCCBCCCCDDFDGEEEEGHKKLMMMKLKJIJ"data "LJKKKKMMLKLMMMLJKKIILLJKKIJJIFEBCCDCDDDDEEEDEDDDEEFFECDCCBCCCCBCCCCCCEDHEEEFGHKKLMMMKLKJIJ"data "LJKJKLLMKLLMLNLMKLKLKJIJKJHJGGFCBCCCDDEFEEEEDCCBCEEEEDCCCCCBCCCCCCDDDFELEDEFGHJKMLMLKKJKIJ"data "LJKKLKMMLMMMKMMMJKKLLKILILJIHDDCBBCCCCDDCCDDDCCCCEEEEDCCCCDCCCCDDDDDGDGGFFEFGHJKNMNMKKJKII"data "LIKKJKMLLMMNMLNLKLKLKKKNILMLJGFCCCCCBDCCBDEECCDDDDDDDDDCCCDCCCDCDDDDDEDGGGEFHHJLMMNLLKKKII"data "MHKKKLNLKKLNNLLKJJLJMLJIKJLKJIGDCEDEBEDEDFHGECBBBCDDDDCCBDCCBCBCCDDDDECFGFEFGHKKNMNMKKKKHH"data "MKJJKMNLKMLLLMKKJIKJKKKKKLLJJIHEDDEFDDEFEFFEFCCBBBCDCEBCCEDCCBCCCDDDCEFGHGEGHIJLNONMKKJKHI"data "LJKJKMMLJLLKKJKKKJLKLLKKKLLLLJJGGGGFEFFGGFFGEDBCBCBCDEDCDEDDDCDDDDCDDGFFGEEEHIKLNOOLKKKKII"data "MKLJLMMLLLLKKJJJKJJLMKJKLKKJLGIHFHGFGGGFEGFFEDDEFEBBDFEDDEDDDCDEEDEEFHGGFEEFHILMONNMKKLJII"data "LKLKLNNLKKKKKKJJJILILKJJLKJIIIIIGGFGGGFFEFFFDCDEEECCDDFFFDEEEDEEFEDFHGGIFFFFIIMMNNNMKKJJII"data "MKLKLNNLLJJLKKIKKJLHKKJJLKJJIJHIHGFGFFEFFFGEEEEFEECCCDFFGDDEEEEEEEEHHFHGFFFFIJMMNNNLLJJJII"data "MKLLLMNMKKLLJJIIJJMKJJJJKJJJJIJIHGGGHFFFFFFFGFFFDDBCCDEEFEEFEEEDEEFFGGGDFFFGIIKKNNNMLKKJKI"data "MKLLLMNNKLLLJKJIJIKJMJJJIKIJIJIHGGGGGGFGGGHGGGFGECBBCDDDEEGDDDEEDHGIHHGFFEGHHHJLMMNMMLKJKI"data "LKKLLMOMLLJKJJKJJHIJJJIKJJHHIHIGHFFFHGFGIJHHHHFFDCBBDCCCBDDDEEFFGFGGFEFFFFGHHIJJLMMMMLKIKI"data "LIKLMMOMLMKKJJIJIIIIJJIKJIHHIHHJIGFFHGFFHIFFGGGFEDCCFCCBBCCCDEGGHFGGFEFEFFGGHIJJKMMMLLKIJH"data "KGKKMMNMKLKJJJKKIJIIIJHIJHIHHGHIHHHGJFGGFHGGGHIHEEBBECCBBBCCCCDGGGGFFFGFFGFGIHJKMLMLLLKIIH"data "LGLMMNNNMMKLKJKJIIIIIIGHIFIIIGGGHHHGGGHGFHGHGGGGFFDDBDCBBBCCCCCDGGGGFFEFFFFFIIHJKKLKLLLIIH"data "LGMMNNMNMMMLKIJJIHHIIHGIKGHHHHHFHHGGFHHIHGGGGFFFEDFFDDBBBCCCCCDCFGGHEGFEFFGGJHIIKKKKLLLIIH"data "LHMKMNOMMLKKJJIKIIHHIHGJJHJHJHHGFGGGGGGIGIHHFFEECCBADBCDDBCCCCCFFGGGFGHEFFGHIIJJJJKLLMLIII"data "LIMKNNNLMKKKIIJKIIGGHHHGHIIGJJGHFGGGHGHHHJJHGDDCBBBBDCCCDCCCCCDGFEFGFGGFFEGGIIKJJJLLLMLIII"data "LHMKMOOMKLKJJKJIIIIHHFHIIHGGHHHHGGGGHHHIIHIIFCBBBABBCBCBBCCDCCEFFEFHFFFEEEGGHHJJIJKLLMLJHI"data "LILLMNNMLLMJIJIIIJIIIHHJIHGGHGGHHGGIIKJIFFGHEBBBBAAACBBBBCCDCDEDDDFFFEEFFEHGHHIJJJKKLMLJII"data "LILLMNNLMMMLJJHJIIHHHHGGHHGHIHHHJIHHLIIJFDCECBBBBBCBABBCCCBCCCDDEDFEFGEEEEGHHHIIKIKLLMLJII"data "LILLMNNMMLKKJJIJJJIHHGHGIHGGHIHGJIHIKJHIFEDDCBBBBBCBABBCCCBBCCDEEEEFFGEEEEGHHIIIKJKKLMLJII"data "LHKLMNOMMKKJIJHIHHIHHGHHGHGGGHHGHJHHGFGFEDDDCCBBBACBBACBBCBCEDDEDDGGEFEEEEHIHJIIJJLKMMLKIH"data "LILLMMNLLLKJJJHJHHIIHIIGGHHHGHHIGHGFEDFFEFFFEBCBBBBBBCEEEEDEGFFEEFGFEFFEEEGIHIJIIIJJLMLKII"data "MILKMMNMKMKJJIIJIIIHHHIHHHIGGGHHGFEFDDDDGFFEGFCCAABABDFFFGGFFEDEFFGFGFEEEFHHIIJIIIJLLMLKHI"data "MIKKLMMMKMLJJIIJIJJIIIHHIGHGGGGGHGFCDDCDGFFEFFCCAABACCEEFGHGFEDDEEGEHGFEEFHIIHIIIIJKLMLKII"data "LIKLKMLLLLLJIIJIIKIIHJHIIHGGHHGGGIGDDEDEHHEFFCCCBABBBDDDEIHHGGDDDFFFGGGEGHGIHHHJIIKKKLLLII"data "KILLLNMLLLKKIIIHIIJIIIIJIGHHGIGFFGGDEFDGHEEEEBBCABBABCEFGGGGGFEGFFFGHHHFGGHIIIIIIIJKKLKKIH"data "LJLLJMMLMKJJJJIIGHJIIJIIHHHHHHHFHEDFGHHIEDFEDDCCCCBDEFGGGHGHHGGHGGFFGHHGHIJJIIHIIJJKKKKKIH"data "LJLKJMMLMKJJJJIHGHIIJKKIIGGHHHHHHFFFFGFHEDECCDDCCEBDFFGFFHHIIHHGGGFGHGIJIJJKIJHIJJJJKKKKII"data "LJLKLLMLLLJKJKIHIGIHIJJIIIHHGHGHGGGEEGFDFCCCCBDDDDDFFHHGEFGIHGHGFHFHIHHHIKJKIIIIJKJJKKKJII"data "LILLLKKLNKKLMJJJIIHHHHJIHHFIHHHHHFEGGFFDCCCCCCDEDEEHIKHFFGKHKHGGGHGGHHHJKKKKHJJJJJJJJJKJJH"data "LJKLKKLKLKKLLKJIJKGHGGIIIIHIIJJHHGFEFEEDCCCCCCBCEGGHHIGGGFGHGGGGGGGLJIHGJKLMJILJJJKKKKLKJH"data "LJKMJKLKKJLKLKKHIHGGGGIGIJJJMLJIIFEDEFDDCCBBBBBCFGGFEDDEFFHHHGFGGFGGGHGJJIKKMKLJKJKKKKKKJH"data "LJJNJKLLKJMKLKKIHGGHGHHGGIKJLKKJGGFCDFEDCCCBBBBDFGGEDCCEGFHGHHHGGGHGGHHKJILJNLKJKJKKKKKKJI"data "LJJOKKKLKKLLKKIJGHFKHFGFGGJKKJKJFGFDDDDDDDCCBBDFGGDCCCDDGFEJGIGHGHGGEFGFJKKLLLJKJJKKKJJKJI"data "MJJNLJJKKJLKLKIIHGGHHGFGGIIKLKHIGGHIDDEEDDDDBBFGGFCCBCDDDGFGHIJHHGHEGGIFJIJKLMKKKJKKKKJIJI"data "MIJMKJIJJJJJJKIHIHGIHGGGFKIJMJHIGHHGFFEFHEDDDCFGGGCCCCCDDFHGHHHJIFFFGHHJIIKJKMLKKKKKJJKIJH"data "MIJLKKIJJJIJJJIHIHHGHHGGGIGHJJIJHHGFEGEFHFDDDDFFFGCCCCCCDFIGGGGHHHFGGHHJIHJJKMLKKKKKJJKIJH"data "MIJKKMKKKKIKKHIJIGHGKIGFGGGGIGHIHFEEDEEGIFDEEEFFEFDBBCBCEEGGGFGFGGGIHHHHJJIKKLMLKKKKJJKIIH"data "LIIJLMKJKKKLKJJIHGEFHHGHGGHGJIHGGFFFEEHFFEFFDCEFFFGGDCCEEHHGFFGHHGCHIIIHHHHILKNLKKJKJKJJIH"data "MJIKKMLJJIIKJHHIIGGFGHHGFHIGHJJHFFFFFFFFFFEEEEEECFGGEBCDDGGHGGGGGGIIHHIKHHIJLMMLLKJKJKJJIH"data "MJJKKLKJJIJJKIHIHGHFGHHGGHIGHHIHHEFFFEFFFFEFEFEECDGEDDCFFGHHGHFHGGHHHHIJHHJJMLNLKKJKJKKJIH"data "MIKKLKJKJIJIKKIIHIFFEFIGFGGHGHGGFFFFEFFGFEEFEHFGCDGHGFFFGHHHHHGGHIHHHGHHIHJKLMNMKKKKJKLKJI"data "LJJLJJJKIIJJIKJJIGBGFFGFGGGGGGFFGGFFGGEGEFFFFFEHEGGGHHHGGHGIGHGGFKHIHHHHHJLJMLNMKKKKJLKKII"data "KJKLKKKLIJILIJHHFDEDDDEEFFGHFFFFGFGFGFFGGGGFFEGFGGFGEFHHHHHJGHHGIIIHHIHHFFJJLNNNLKLJJKKKHH"data "LJJLKKLLJIIJHHHIFDFDFEEFGFGGIGGHFGHHGGFFFGGFFFFGHGHFEFGHHIIIIHIHIGIGGHIJDEIKMNNMLLLJKKJJHI"data "LJILKKLKIIJIHHHHGDDEFFFEFDGFIGGFGFFJGFGHGFFEGGFHHGGEFFIHJIIGHHGHIHIHHHIJDFHLMNNMLLLJJKJJII"data "MKIKJMLKKJIIIIGGJGGFGGHEEEFFFGHKHHHHGGHHGHFEFFGFHFDEFFGHIHIHHHHIHIIIIJJJFFGMNNMLLLKKJKKJHI"data "MKJKKMMJJIJIGEHGIGGCFFEGDEFEFHIHGEGGGHGGGEEECCEFGEDCDDHGJJIIJGIIIHJHJJJJFFIMNNLLMKKLJKKKHI"data "NJKKKKMLIIHIFEFFGHFDEGFFEEECEHJGFFGGLGIGFDDCCDDEEDDBDDGHHHJJJGHIHIIIIJIMGGJLONMNLKKJKJKJHI"data "MJKKLKMKIIHIGEGEEFHDFFFEEEEDGIGFFGGGIIGFFDDDBCDEEECCDFGFEIIJIHHIIHIIIIILHGJMONMNLKKJKJKJHI"data "MKJLMLLIHHIHHGGFGGFFEEEEEEEEGGFFHGGIIHGGHFFFCCDEFEBCBIGHGIJJJIHIHIHJHHIIJIJMNNNKLKKJKJKKHI"data "NJKMMKKKGHGHGHHDGEFHFGDDDDDFDFGGGFGHGIHIHFFFFCDEFEDDEJGHHFGIHJGIIIHHIIIJKKKMOONKMLJJJJKJHJ"data "NJJLKJKJIGIIIGGGHGHEFFEDDEGEDFFGGHGHIHHHIGFGGFFFFEEDEHGGHEFIHGIHIHKIKJKLKLLNNNMLLLJJKKKJHI"data "MIJKJKLJIGGIJHHFGHIFFEDEFEEEEFFFGHGIIGHHIFFFGGEEFEEEFGGGHEHHHFIHHIKHKKKKKKMMNNMLLKJJKKKJHJ"data "MIJKKKLJGGHJIGGDFGFFEDEFGFEDGFGGGHHHHGGGGGGGGGGFEFFFHFGEFHGHGHGIILJKKLLLLLNMLMMLLKJKLLJJHJ"data "MJKJKJJHHGHJHHGFDJEFFFFFDEEEFFGFGHIHHFFFGGGHFHHGGGGGGGGGHFDGFILLLJIJKLNKLMNNLMLLLLKKKLJKHJ"data "MKKJJIJJIGGHKIGEFFGFGEEDEFGEFFEFGIIHGGFFGEGGFHJJHGHHGGGGFHGGGHOMKMKKLLMMKIMNMLLMLMKKJLKJIK"data "MJKJJIJJIHHIKIIFGEFFGEDEFFGEFFFEFGHHGGFFGFGGGGHIHHGGGGGHHGFGFJOOMKJJKLMONMNMMLLMLMKJJLKJIK"data "LJKJJJKJHIHIIIGEFFEGFFFEEFFFFFEDEFFGGGFFFGFGHIGGHHGFFGGGHFHFIILLLKKKIKMMMKNNMLLLLLKJJLKJIK"data "LKIJJIKKIIHJIHGEHGHEFFHEFEEFFEEEFFFFGGGGGHGGIIIJHHHHGHHJHHJGIJKKKJIKKKLKIIMOMKMLLLKJKLJIIK"data "MJIJJJJIIIIJJHHHHHFGGEFFGFHHFFEGFFFFHGHHIHGGHIIIHGGGHGFJIJIJKHKKKJJLJKJLLLMOLKMLLKKJLLJIIL"data "MJIKJIKJIHIJIJHJIFGHFFGGFHGIHEEEFFFFFFGHHGFFHHGGGHGHGHIHIHIIJJMKKJKJLJMKKKKLLKLLLKJKJLKJIL"data "MKIKJIJJIHIIIIHIJHGGFFHGHHHIIEDFHGFFFFFGHGGFFHFGGHIHHIHHIHIIJJMKJJKKNLKLLJJLLKLKKKKKKLKIIL"data "MKJJJIJJIIIIIHIHHGHGGGGHIHIHHGGGFGGGFFFGEGGGHIIJHIKJJIIHHIIJJKJJIIJKMLIMJIKKKJLKKJKKKLLIIM"data "NJJJKJKIJJILIIHJJIFGGGGIHGHHGHHFFHIKHGFFEGGGJMKKLMKKJJHIIHKKKKJIHIJKJKJJJJKJJJLKKJKKKLLIIL"data "NJIJKKMJJKHJIHJLKJIGIGFFHHHGHHHFGGHHHGFEIIKJMLLMHIJIIJGHHIJJJJIJIIJIJLIIJJJKKKKJKKKLJJKJIL"data "NJIJKJMJIKJIJIJMJJIGKGGGHGGGGHHFGGHGGHGHILLLMMLLJKJJJJHIHIJJJJJJIIJJJKJIJJJJJJLKKKKKKJKJIL"data "MJIJJKLKHJJJKKIOIIHGIGHGGGGGGHGGFHGIGGGHIMMLLLKKJIHIIIHHHIMJJJJJIHKKJKJIHJJIJJKKMKKKKKKJIL"data "KIHIIKKKIJHJMKILIGHGGHFFGFGGFHGGHGIIGHIIJJLLKJJJJJHIIIHGHHHHHHJIHKLKJJIHHIJJJJKJKLKLKKKJIL"data "KIHIIKJKJHIMKMJJIIGEGGGHHGGHGGGGHIGEHHHIHIKKJJJJIJJKIHIHIHHGIIIHKJJLKJHIIHJKJJJIJKLLLKJJIL"data "KIIJJLJLKHKOKLIJHFGEIHGHGJGGHGGGGFAGIGIIIIIIIJJIIIHIJIIIIHHHHIHJJIIKKJIGHHJIJIJKKKKLLJJJJK"data "LJIKKKJKKJKMJJHHGIHFFGGHFGGFHFGHIKFFHHGHHHIHIIIHIKHIIHIHHHHHHIHIHGIJJJIIGHIIKIILKKKLLJJJIL"data "LIIJLJKILJJIIIGHGHGGFFGGGGGGFGHHGHIGHHGGGGIHIJHHJIHIHHIIHHHIHIHHHHIJKIJGHGIHIJJKKJKMMKJJIK"data "MIIKMJKILKIIHHJGFGGHFGHGEGGFGGHHGGGGHGGGGHHIIHIIHGHHGIIHHHHIIIIIHGIIIHJJHHHIIILKKKLMMKKJJK"data "NIJJMKKGJJIKHIHGHHHGFGFFFFFGGHIGIHHGGGHGGGIHIIHIIHHIIHIIKIHHIJHIHHIIHHHKIHHHIHKJJKMMMKKJJK"data "NIIJLKKHKKJJHJGHGHHIIIHFGFGGFGIHHHHHGIGGHHIIJIIIGHHHGIIIIIIIIMIHHHIIIHGIIIGIJIKKJJMMLKKJJJ"data "NIIKKJKIJJLJHIGJHGHIHGHIGHGGGHHGGHHGGGFGGGHIIGIIGGHGJHMGHJHHJIIGIIIIHHHIIHIIJJKKKKMMLKJJIJ"data "OIJJKIKJJJKJIGIIGHGFFHILGGGGHIGHHGFGHGGGGGHIHKIIJHGFHIIGHGHJJNGHHHIIHHHGHHIIIJJKJJLMLKJJIJ"data "OILIJJKJJJIIHHGIHGIGGFIJHEGDELJGGHHGGHHIHGIIHGIHHIHGJGIHGDDGHIHHIIHHGHGHIIIIJKIJHJJMKJKKJJ"data "LIJJJJJKJJIJHHGHLHHFHFGIHHFCFIIGFGGHFHGGHHHHIIHHHIHHGGHGFDDFGIGIHIIHGGGGHJIHJLJKIJILKKJKJI"data "LIJJJJJJJJIHHHIHHGFFGGGFIGFEFGGGGHHGGGGHGHGIHHHIHHIIGHIHGCCDEIHIIJJGHGHGIIHJIKKJIJJLKLJKIJ"data "LIJKKJJKIJHHFGHHFFGFEFJGIGGFEFGIHGHIHFGHHIIIIHHIHHHHJJHHFDCDEHIIIJHEHGHHGIHJIJKJIJKLKLJJIJ"data "LIJKKKJKKJIHHHHHHFHGFFFJHGIFFFHGGGGGFGHHHGHHIHHHHHIHHHGHGGFHHHHIIJHGHHHHHIGIIJJJJJJLKLJJII"data "LIJKLJJKLKIJHIGGIGHFFGFGGIHEGFHFGGFGFGHHHGHHIHIHGHIGGHGHGIGHGHIIIJGHGHHGHHHIIJIJJKJLKKJJII"data "LIKKLKJKKIHLGHFFHHGFGFGFGFFGHJIHGGGGGHHGHJIIIHIIHHIHIHGFHHIJIHHIIIGIGIHIIHIKIIJJJJJLKLLKII"data "MJLKLJKKJIIKGFGGEFGGEIFFGFGGGGFFGGGFGHHGGIJJJIIJHIJJJJHHHIIIHHHIIHGHIKIIHHHJJIJJJIJKKLLKIJ"data "MKMKKKJKKLKJIHGDEEHGFIFEFFGGEFFFFFEGGHIIHIHHKJIIIJJJKJHGGGHGHHIIIGHHIIHHHJGHIIJJJKJKKKKKII"data "MKMKKKKKKMLIIGFDFFFFGEDDEEFFCFEHGFFGHHJIJIJIHJIIIMLJJJHGFHHHHHJIIHHHHHHHHIHHHIKIJKKKKKKKII"data "MKLLKKLKLLKGIHFEDEGGFEDEEFEEDGFGGFFFHHHILIHHHHIKIIJKKIHIHGHJIIKJIHHGHGIIIIIJIHJILKKKKKKIII"data "MJLLLKLLLKJHFGGFFGFFGGFFEFFEDEEFGGIGGIIHIHHGFIJKIKKKKJJHIHHIIKJIHHHHIHIHHHIIHHJIJKKJLKKIII"data "NKKLLKMKJJIGGGGEEEFFFFGDFEFFFGGEFGHIHGHIHHGGGIJIKKJKKKIIIIGIJJIGFIHHHHIHHHIIIIJIKLKKJKKJII"data "MLJLKJLKJIHHGHGGEHEEEEFFFFDFFHFGGFHJGJHGHIHIIIJJJLJJKMJIIIGIIIIHHHHIHJHHHGIIJJJIJLKLJKKJII"data "MLJLKJKLKIGHGHGGFFEFEEFFGGFEFEEHFFHIDJJIHIHIIIJIKKIJKMHJIJHIIIIGGHIKIKIHHHHHIKIIILKLJKKJII"data "MLKJKKKJIJHHFIGGHFFFEFDGEEEEFEFFFFGHHJIHIIHHHIIJJKKLLLGKJJHJIIHHIHIJJJHHHIILJJJJJJLKJKJJJI"data "LKMKKKKJJJGHHHHHGFFFFGEFEEDEFEEHFEFGFGIHHHJIHIIJJJKKNNIJIJKKJJJIIIIIIJHGGHIJKJJJKJLKJLJJII"data "MLKKKKKJJIHGHGFGGFFFFGEFEFDEEFFFEFGFGGHHJJKKJIKLJJIJJIKIJJIHJIJHIHHIHIHGHGIHKJJIKJLKJKJIJI"`
Last edited by BasicCoder2 on Oct 02, 2017 8:43, edited 1 time in total.
BasicCoder2
Posts: 3351
Joined: Jan 01, 2009 7:03

### Re: Making pixel based 3D objects - MARS

This is mars added to the mix. It uses a palette of colors and the palette number of each pixel is in the DATA statements.

How to make a 3D models for its irregular shaped moons Phobos and Deimos is something of a challenge.

Code: Select all

`'some useful definesConst Pi = 4 * Atn(1)Dim Shared As single TwoPi = 8 * Atn(1)Dim Shared As single RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As single DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 1280,600,32'data statements hold palette numbersdim as ulong colors( 15)colors(0)=RGB(202,176,175)colors(1)=RGB(193,174,170)colors(2)=RGB(84,68,55)colors(3)=RGB(114,83,54)colors(4)=RGB(136,97,58)colors(5)=RGB(145,103,61)colors(6)=RGB(90,61,47)colors(7)=RGB(100,76,64)colors(8)=RGB(154,111,60)colors(9)=RGB(186,127,59)colors(10)=RGB(145,106,73)colors(11)=RGB(224,150,65)colors(12)=RGB(68,40,19)colors(13)=RGB(207,140,59)colors(14)=RGB(218,142,54)dim shared as any ptr marsMap2marsMap2 = imagecreate (90,180)dim as string datum,chardim as integer palNumfor j as integer = 0 to 180    read datum    for i as integer = 0 to 90        char = mid(datum,i+1,1)        palNum = asc(char)-65        pset marsMap2,(i,j),colors(palNum)    next inext jput (0,0),marsMap2,translocate 240,2print "Tap space bar"sleepdim shared as integer posx,posy,invposx = 640  'position of iso display on screenposy = 300type POINT3D    as integer x    as integer y    as integer z    as ulong   cend type'make eight points of a absPt'compute max dots to display and total dots to rotatedim shared as integer MAX_DOTS'=============   THESE LOOPS COMPUTE MAX_DOTS AND TOT_DOTS ==============for angle1 as single = 0 to 179    for angle2 as single = 0 to 359        MAX_DOTS = MAX_DOTS + 1    next angle2next angle1'create axis pointsfor x as single = -250 to 250    MAX_DOTS = MAX_DOTS + 1next xfor y as single = -250 to 250    MAX_DOTS = MAX_DOTS + 1next yfor z as single = -250 to 250    MAX_DOTS = MAX_DOTS + 1next z'==========================================================================dim shared as Point3D abs3D(0 to MAX_DOTS)  'absolute positionsdim shared as Point3D rel3D(0 to MAX_DOTS)  'relative positions after any rotationdim shared as single angle,x,y,z,rx,ry,rz,px,pydim shared as single RotX,RotY,RotZdim shared as single ratioX,ratioY,ratioZRotX = 71RotY = 19RotZ = 336'now give values to dots on sphere surface'creates pointsdim as integer iidim as single radiusradius = 80for angle1 as single = 0 to 179    for angle2 as single = 0 to 359        abs3D(ii).c = point(angle1\2,angle2\2,marsMap2)        abs3D(ii).x = radius * sin((angle1)*DtoR) * cos((angle2)*DtoR)        abs3D(ii).y = radius * sin((angle1)*DtoR) * sin((angle2)*DtoR)        abs3D(ii).z = radius * cos((angle1)*DtoR)        ii = ii + 1    next angle2next angle1'create axis pointsfor x as single = -250 to 250    abs3D(ii).x = x    abs3D(ii).y = 0    abs3D(ii).z = 0    abs3D(ii).c = rgb(255,0,0)    ii = ii + 1next xfor y as single = -250 to 250    abs3D(ii).x = 0    abs3D(ii).y = y    abs3D(ii).z = 0    abs3D(ii).c = rgb(0,255,0)    ii = ii + 1next yfor z as single = -250 to 250    abs3D(ii).x = 0    abs3D(ii).y = 0    abs3D(ii).z = z    abs3D(ii).c = rgb(0,0,255)    ii = ii + 1next z' sub coded by dodicatSub QsortZ(array() As Point3D,begin As Long,Finish As Ulong)    Dim As Long i=begin,j=finish    Dim As Point3D x =array(((I+J)\2))    While I <= J        While array(I).z > X .z:I+=1:Wend        While array(J).z < X .z:J-=1:Wend        If I<=J Then Swap array(I),array(J): I+=1:J-=1    Wend    If J >begin Then QsortZ(array(),begin,J)    If I <Finish Then QsortZ(array(),I,Finish)End Sub'rotate points up to TOT_DOTS and copy the result to relative list'also copy non rotated points to relative list as well for display routinesub rotatePoints()        dim as single cosAngleX,sinAngleX,angleX    dim as single cosAngleY,sinAngleY,angleY    dim as single cosAngleZ,sinAngleZ,angleZ        angleX    = RotX*DtoR        cosAngleX = cos(angleX)    sinAngleX = sin(angleX)        angleY    = RotY*DtoR        cosAngleY = cos(angleY)    sinAngleY = sin(angleY)        angleZ    = RotZ*DtoR        cosAngleZ = cos(angleZ)    sinAngleZ = sin(angleZ)        '=========================================    dim as single x2,y2,z2,x3,y3,z3    for i as integer = 0 to MAX_DOTS - 1        x2 = (abs3D(i).x * cosAngleZ) - (abs3D(i).y * sinAngleZ)        y2 = (abs3D(i).x * sinAngleZ) + (abs3D(i).y * cosAngleZ)        x3 = (x2 * cosAngleY) - (abs3D(i).z * sinAngleY)        z2 = (x2 * sinAngleY) + (abs3D(i).z * cosAngleY)        y3 = (y2 * cosAngleX) - (z2 * sinAngleX)        z3 = (y2 * sinAngleX) + (z2 * cosAngleX)        rel3D(i).x = x3        rel3D(i).y = y3        rel3D(i).z = z3        rel3D(i).c = abs3D(i).c            next i        'sort by distance along z axis    Qsortz(rel3D(),Lbound(rel3D),Ubound(rel3D)) '***dodisort code ***    end subsub update()        screenlock    cls    'draw points in rel3D list    for i as integer = 0 to MAX_DOTS-1        'circle (rel3D(i).x + rel3D(i).z + posx, rel3D(i).x + rel3D(i).y - rel3D(i).z + posy),1,rel3D(i).c,,,,f        circle (rel3D(i).x - (-rel3D(i).z) + posx,((rel3D(i).x + (-rel3D(i).z) ) / 2) + posy + rel3D(i).y),1,rel3D(i).c,,,,f    next i        locate 4,1    print " X or Z key rotates pixels around blue z axis"    print    print " Left/right arrow keys rotates pixels around red x axis"    print " Up/down arrow keys rotates pixels around green y axis"    print " Space bar resets all degrees start positions"    print    print " rotX ";RotX;"  rotY =";RotY;"  rotZ =";RotZ    screenunlock    end subupdate()dim as single now1now1 = timerdo   ' if timer - now1 > 0.01 then   '     now1 = timer        rotatePoints()                if multikey(&H39) then  'space key to reset all angles of rotation to zero            RotX = 71            RotY = 19            RotZ = 336            while multikey(&H39):wend        end if                'rotate around x axis        if multikey(&H48) then            RotX = RotX + 1            if RotX = 360 then RotX = 0        end if        if multikey(&H50) then            RotX = RotX - 1            if RotX < 0 then RotX = 359        end if                'rotate around y axis        if multikey(&H4B) then            RotY = RotY + 1            if RotY = 360 then RotY = 0        end if        if multikey(&H4D) then            RotY = RotY - 1            if RotY < 0 then RotY = 359        end if                'rotate around z axis        if multikey(&H2C) then   'Z KEY            RotZ = RotZ + 1            if RotZ = 360 then RotZ = 0        end if        if multikey(&H2D) then   'X KEY            RotZ = RotZ - 1            if RotZ < 0 then RotZ = 359        end if            'end if        update()        sleep 2loop until multikey(&H01)DATA "AAABACDAAEFEEEDGCCCHDDEEEEDDDDEFFFFFFIIIIIIIIIIIIIIIJIEFIFEEFFIFFFFIIIIIIIIFIIIIIIFIFIIEEF"DATA "AAAAACDAAEFFEEDHCCCDDDEEEEDDDEEIFFFFFFIIIIIIIIIIIIJJIFIFFFEEFFIFFFFIIIIIIJIIIIFJIIIIEIIEEE"DATA "AAAAACDAAEFFEEDHCCCDDDEEEEDDDEEIFFFFFFIIIIIIIIIIIIJJIFIFFFEEFFIFFFFIIIIIIJIIIIFJIIIIEIIEEE"DATA "AAABACDAAEFFFEDHGCCDEEEEEEDDEEFIIFFFEFFIIIIIIIIIIIIFEEFFIIFFFIFIFFFIIIIIIJIIIIIIIJIIFIIEEE"DATA "AAABAHKAAEIFFEDDHHCDEEEEEEDDEEFFIIFFEFFFIIIIFFIIIIIIIIFFIIIFFIFIEEFIIIIIIJIIIIFJJJJIIIIFEE"DATA "AAABBHGAAKFFFKDDHCCDEEEEEEEDEEFFFFFFFFIFIIIFIIIIIIJJFEEEEIFFIIIFEFFIIIIIJJIIIIJIJLJIIIIEFE"DATA "AAABBHGAAKFDEFDDHCCDDEEEFFEEEEFFFFFFFFFFFIIFIIIIIIJIEDDEEIFFFFEEEEFIIIIIJJIIJEIJJJJJIIIEFE"DATA "AAAAKHGABKFEEEDDHCCHDEFEFFEEEEFFFFFFFFEIIIIFIIIIIIFEEEFEEIFFFFEEEEFIIIIIJIIEFIIIJIJJIIIEFE"DATA "AAAAKHEAAAEFKKDHCCCHDEFFIIFEEFIFFFFFFEEEFFFFIIIIIIIIIFFEEIFFFFFFEEFIIIIIIFJIEIJFJIJJIIFEFE"DATA "AAAABCMAKJEKKEDHCCCHDEEFIIFEFFIFFFFFFIFDEFFFIIIIIIJIIFEEEKEFEEEEDEFIIIIIIJIIEEIIJJIJFIEEFE"DATA "AAAABHHAKEKFEEDDHCGDDEEFIIFFFFFFFFFFFEDGDKIIIIIIIIIIIIFFGGKKDDDEEEEIIIJJIJIIIIJIJJJIFFFEFF"DATA "AAAAAHGABEKFEEDDHCGDDEEFIIFIFFFFFFFFFEDMDKIIIIIIIIIIIIFEGGDDDDDDEEFIIIJIIIIIIIJINJJIFEIEFF"DATA "AAAAACAAAKFEEEDDDHGHEEEIIIFIIIFFIIIIFIKDDKIIIIIIIIIIIFFDDGGGGDDDEEIIIJJIIIIFIFEJJJJIFEIEFF"DATA "AAAAACBAAKFEEEEDDHGGEKFIIIIIIIIFIIIIIFEDDKIIIIIIIJIIIFFKDGCGHDDDEFIIIIJJJIJIJIEJJIIIIFIEFF"DATA "AAABACMAKEEEEEDDDHHHEFFIIIJIIIIIIIIIIIIEDEIIIFIIIIIIFFEKHHGGHHDEFIIJJIJJJJIIJJJJJIIIIIIEEE"DATA "AAAAACGABEFFEEEEDHHDEFFIIIIIIIIIIIIIIIIKEDFIIIIIIIIIIEDGDMHKGDEEFIIJJJJJJJIIJIJIJJIFIFIEEE"DATA "AAAAACGBAKIFEEEEDHHDEFIIIIIIIIIIIJJIIIFKEDFIIIIIIIIIIEDGDGCHGDEEIIIJJJJIJJIJJIJIJJIFIFIEEE"DATA "AAAAACHBJEIFEEEEDHHEFFIIIIIIIIIIIIIIIIIKEDFIIIIIIIIIIEDDGHCHGDKKIIIJJJIJIIIIJFIJJJIEFEIEEE"DATA "AAAAAHHAKEIEEDDDDGHEFFIIIIIIIIIIIIIIIIIKDEIIIFIIIIIFFEEGHHHHDDKKJIJJIJIJIJIIJIIJJJFEIEFEEE"DATA "AAAABCKAAFIFEEDDDCHEKFIIIIIIIIIIIIIIIIIFFFFIIFIIFEDDEEHHCCHHDDEKIIIJJIJJJJIIJJJINJIFFFKEEF"DATA "AAAABGAAAKIFEEDDDCHEFFIIIIIIIIIIIIIIIIIFFFFIIFIIIEDEEDGHCGCGDDEEIIIJJJJJJIJIJJJIJJIEEEEEEF"DATA "AAAAKCABAKIFEEDDDCGEFFIIIIIIIIIIIIIIIIIFFFFFFFIFEGDEDGGCCGCHDDDEIIIJJJJJJIJIIJIIJJIIFFEFEF"DATA "AAAAKCBEKKIFEEDDDCGEFFFIIIIIIIIIIIIIIIIFFFFEFFFKEEEKKDGGHHHHDDEEIIIJJJJJJJIIFJJJJIIIFIFFEI"DATA "AAABBCBGKKFFEEDDDGHEEFFIIIIEFFIIIIIIIIIIIFFFFFKFEEDKEDDGCGHHEEEEFIJJJJJJJJIJIJJJJJFIEEFFFI"DATA "AAABBGBGJKFFEEDDDCGDEFFIIIIEFIIIIIIIIIIIFFFFFFFDDDDDGHDGCHGGDEEEFIJJJJJJJFIJJJJJJIIIFEEEFF"DATA "AAABKMBGAEFFEEDDHCGDEFFFIIIEEFIIIIIIIIIFFFFFFFFDEDDGKGCHGHDDEEEEIIJJJJJJJJJJJIJIJIFIIFEEFF"DATA "AAAABCAGAEFEEEDDDGHDEEEFFFIFEEEIFIIIIIIFFIIIIIEFFKDGHGCCCGDDDEEFIIJJJJJJIIJIJJJJJJIIIIEEEF"DATA "AAAABCAMEKFEEDDHHCGDEEEFFFIFEEEEFFFFFIIFFIIIIIIFKKKGCCCCHHHEEEEEFIJJJJIIIIJIJIIJJJIIFFEEEF"DATA "AAAAKMAMKEFEEDDDHGGHEEEFIIIFFFEEDEFKFIIIFIIIFFIFFEKGCGCCHHHCDDDEIIJJJJJJJEIJJIJJJJIEIFEDEE"DATA "AAAAKHAMEEEEEDDDHCGHEEEFFIFFFFFFEDDKFIIIFIIIFFFFFFKHCGCCCHHHDDDEIIJJJJJJJIJJIIJJIJIEFFDEFE"DATA "AAAAEMBKKEEEEEDDDCGGDEFFIIFFIIIFFEDDEFFFFIIIIIFIIFKDCCCGCCHDDDEEIIJJJJJJJIJJIIJLJJIEEFDEFF"DATA "AAAAKHAAEKEEEEDDDHCGDEFIIIIIIIFFFFFEEDEFIIIIIIIIFDDGDDHHCCHDDDFEIJJJJJJJJIFIJJIJJJIFFIDEFF"DATA "AAAAKDAAKEEEEDDDDHHGDKFIIIIIIIFFFFFFFDDEEFIIIIIIFDDDDDDGHHHDDEFFIIJJJJJJIIIIIIIIJJIIFEEEFF"DATA "AAAAKKAKKEEEEDDDDHHGEFFIIIIIIIFFFFFFFDDEEFFFIIEFFDDDEDGHHHHHDEFFIIJJJJJJJIIIIIIIJIIIFFEEFF"DATA "AAAABKAMEEEEEDDDDHCGKKFIIIIIIIIFFFFFFEEEEFFIIFKDEDDDDDDDDDDDDEFFIIJJJJJJIJIIIJJIJIEIEFEEFI"DATA "AAAABBHGKEEDEEDDHHCGEKIIIIIIIIIIFFFFFFEEEEFIKFEDDDDDEDDDDDHHDEFFIIIJJJJJJJIIFIIIIIFFEEEEFI"DATA "AAAAABGGDEEDDEDDHCGGEEFIIIIIIIIIFFFFFFEEEFFFEDDDEEEEDDEDDHHHDEFFIIIJJJJJIIIIFFEIEIIEFDEEFI"DATA "AAAAAKMDEKFDDDDDHHGGEKFIIIIIIIIIFFFEEEEEFFFEDDGDEEEEEDDDDDDDDDEFIIIJJJJJJIIFEEDIIIFFFFEFFI"DATA "AAAAAGKEKKEDDDDGGGGGEKFFIIIIIIIIFFEEEEEEFEEEDDDEEEEEEDDDHHDDDDEFIIIJJJJIIIEIIFEFFEFFFFEFFI"DATA "AAAAAHDEKDEDDDDDDHHGDEFFFFIIIIFFEEEEEEEFFFFFEEEKEEDDDDDHCHDDDEEEIIIJJJJIIIFDIFFFIIFFEFFFII"DATA "AAAAAKGGKDEDDDDDHHHHDDFFFFFFKFFEEEEEEEEFFFFFFFEKEDDDDHHCCCHHDEEEFIIJJJJJJJIIIEFIEIEEDFFFII"DATA "AAAAAKGGKEEDDDDDHHHHGGFFFFFFKKFEEEEEEEFFFEEEFFEFDDDHHHHCCCHHDEEEFIIIJJJJJIIJFIEIEIEEDFFFII"DATA "AAAAAKDMDKEDDDDHHHHHHDFFFFFFEDDEEEEEFFFFFFFFFFFEDDHCCCCCCCHHDDEEFIIIIIJIIFIFIEEFFFDFEEFIII"DATA "AAAAABHGDDEDDDHHHHCHGGEFIIIFDGGEEEEFFFFFFFFFFFEFEHGCCCCCCCCCHDDEEFIIIJIIJIIIJEEFFEEFEEFIII"DATA "AAAAABGBKDEDDDHHHCCHHGDEIIIEEEEFFFFFFFFFFFFFFFFFEHCCCCCCCCCCHDDEEFFIIJJIIIEIJDFFEEEFEFFFII"DATA "AAAAAAMBKEEDDDHHHCCHHGDEFFFEFFFEFIFFFFFFFFFFFFIEDHCCCMCCCCCCHDDEFFIIIIJIIJIEIEFEEEEFFFFFII"DATA "AAAAABGBDEEDDHCHCCCHHDGEKKIEFFFFFIIIEFFFEFFFEEFFEHCCCCCMCCCGHDEEEEIIIIJJJIIIIIFFDEEIEIFIII"DATA "AAAAAAKGEEDDDDHHGCCCDDEEEKEEFFFFIIIIIFFFFEEFDFFEDHCCCCCCCCCCDDEFIIJJJJJJIIIIIIFEEKFFFFFIII"DATA "AAAAAAKDKKDDDDHHCCCHGDDKEEEEFFFIIIIIIFFFFEKEDEEEDCCCCCCCCCHHDEFFIIJJJJJJIIIIIIEFEKEFEIEIII"DATA "AAAAAAKKKEDDDDHCCCCHGDEFEDDEFFFFFFFFIIFEEKEDEKEDHGCCCCCCCCHDDEFIIJJJJJJJJIIIIIFEDEEEFEFIII"DATA "AAAAABKKKDDDDDDGGGHGGDKKEDDEEEFFFFEKKIIEDDGGDDEDCGCCCCCCCCHDDEFIIJJJNJJJJIIIIIEEDEEFFFEIII"DATA "AAAAABBKKFEDDDHHHCCHDEIFEEEDEFFEEFKDDEEDGGMGHHDDCCCCCCCCHHHDDEIIJJJNNNJJJJIJIIFEDEFFIIIFII"DATA "AAAAABBGEEEDEDDHHHCDEFIIEEDDFFEFEEKDGDEGCCCHCCGHCCCCCCCGHHDDDEIJJJNNNNJJJJIJIIEDEEFFIFFIII"DATA "AAAAABADKKEEEDDHHHHDKIFIEEGEKEEEFKKGHCHMCCCHCCGCCCCCCCCGHHHDDFJJNNNNNNJJJJIJIIFDFFFIIIIIII"DATA "AAAAABBGKEEEEDDHHHHDKIFFEEGKEEEEFKKGCGCCCCCCCCMCCCCCCCGCHCHHDFJJNNNNNNNJJJIJIIIEFKFIIIIIII"DATA "AAAAAABMKEEEDDGDDHDDIIIEEEDKEEFFEKDHCMMMCCCCCCMCCCCMCCMGHHHDEIJJNNNNNNJJJJJIIIJEIIFFIIJIII"DATA "AAAABABGKFEEDDHDDDDEIIIKEDDEEEFFFEDGCCMMCCCCMMMCCCGHCHHCHHDDEIJNNNNNNNJJJJJIIIJIIIIIJIJIII"DATA "AAAAAAADKEEEDDHDDDDFIIFEDDEFEEEEIEGDCCMMMMMCCCCCCCCCCCHDDGDEEIJNNNNNNNJJJJIIIFIIIIIFJJJIII"DATA "AAAAAAAGEFEEDDDDDDDFFIEDDEEEEEEEDKEDGCCMMCCCCCCCCCHCCGHDDDDDDINNNNNNNNJJJJIIFEIIIFIFJJJIII"DATA "AAAAAAAGKEEDDDDDDDDFFIEDDDEEEEEEDIKMGCCCCCCCCCCCGCCHGGDDDDDDDINNNNNNNNJJJJIIFEIIIFJIJJJIII"DATA "AAAAAABGEEEEDDDDDDDDEEEDDDKGFFEEIIFEDDHGCCCHMCHGGHHHDDEEEDHGEINNNNNNNNJJJJIIEEIIIIIIJIJJII"DATA "AAAAAAKDEEEEDDDDDDDDEEEDDDDEFFFFFIIJIKKKKKKGGGCHHDDDDMGEEDHGDFNNNNNNNNJJJJIIEFIIIIIIJJJJII"DATA "AAAAAABKKEEEDDDDDDDDEEEDEEEEIIFFEIEIJIIIIEIKDEDGHGMDEMGEEEHHDEJNNNNNNJJJJJIIIIIIIIIIJIJJII"DATA "AAAAAABDDEEEEDHDDDDDEEEKEEKFIIFFFIEIIIIIIEEIEDDGEDGKEGGEEEHHDEJNNNNNNJJJJJIIFIIIIIIIJIIJII"DATA "AAAAAAKGEFEEDDDDDDDDEEEEEEFIIIIFFFFIIIIIJIIIIIEEDEEEFKEKEDDDDEIJNNJJJJJJJJJIFEIIIIIIJJJJII"DATA "AAAAAAJDKEEEDDDDDDDDEEEEFFIIIIIFIIIIIJJJJJJJJJIFEFFFFEEDEDDGDDEEJJNJJJJJJJJIIIIIIIJIJJJJII"DATA "AAAAAAKGEEEEDDDDDDDEFFFFFFIIIIIIIIJJJJJJJJJJJJJIIIIIFEEEEDDHHDFFIIJJJJJJJIJIIIIIIIJIIJIJII"DATA "AAAAAAKDDEEEDDDDDDDFIFFFFFIIIIIIIJJJJJJJJJJJJJJIIIIIFEEKEDHHGDKIFIIJJJJJJIJIIIIIIIJJIJIJII"DATA "AAAAAAKDEEEEDDDDDDDFIIIFEEFIIIIIJIIJJJJJJJJIJJJJIIIIFFFDEDGGGDFFFEEIIIJJJJJIIIIIIIJJIJIJIF"DATA "AAAAAAKGEEDDDDDDDEFIIIIIEEIIIIIIJJJJJJJJJJJJJJIIIJIIFEEFEDDHHHEEFFFIIIIIJJIIIIIIIIJIIJJJII"DATA "AAAAAABDEEDDDDDEEEIIIIIIEEIIIIIIJJJJJJJJJJJJJJIIJIJIEEEFFEDDHGDEFFIIIIIIIJIIIIFIIIJJIJJJII"DATA "AAAAAABDDFDDEDDEEEIIIIIFEEIIIIIIJJJJJJJJJJJJJJIIJIIFDEEFFEDDHGDEFIIIIIIIIJIIIIFIIIJJIJJJII"DATA "AAAAAABEEDEDEDDEEEIIIIIEDDFIIIIIJJJJJJJJJJJJJJJJJJFEDFKFFEEDHHDEFIIIIIIIIJIIIFFIIIJIIJJJJI"DATA "AAAAAABKEDEEEEEEEFKFIIIFGDFDIIIIIIJJJJJJJJJJJNJJJIDDDEEFFEEEDDDEFIIIIJIIIIIIIIEIJJJIIJJJIF"DATA "AAAAAAAKDEEEEEEEEEKFFEIFGEKIIIIIIIJJJJJJJJJJJJJJJIDDDEIFFFEEDGDEFIIIIJIIFIIIIIIIJJJIJJJJIF"DATA "AAAAAAAKEDEEEEEEEEEFEEIKGEEIIIIIIIJJJJJJJJJJJJIJIIGGDFFIFFFEDDDEFIIIIIFIEIIIFIIIJJJJJJJJIE"DATA "AAAAAAAEDEEEEEEEEEEFEEJKDEDFIIIIIIJJJJJJJJJJJJJJIFGGDFFIIFFFEDDEFIIIIIIIEFIIFIIJJJJJJJIJIE"DATA "AAAAAABEEEEEEEEEEEEFFEJKDDDFIIIIIJJJJJJJJJJJJJJIIEGHDKIIIFFFDDDDFIIIIIIJIFIFFIIIFIJJJJIJJE"DATA "AAAAABBKEFFEEEKEDDEFIIIKDGDDFIIIJJIJJJJJJJJJJJJIEDHGKFIIIFFFEDDDFFIIIIIIEFFEEIIIIIJJJJIJIE"DATA "AAAAAAAKEFFFEEFEDDEFIIIKDDDDFIIIIIJJJJJJJJJJJJJJEEHGDIIIIFFFEEDEFFIIIIIFEEFFFIIIIIJJJJIJIF"DATA "AAAAAAAKEIFFFEFEDDEFIIIKDDEEFIIIJJJJJJJJJJJJJJIIDKGHDIIIIFFFEEEEFFFIIIFFFEFFEIIIIIJJIIJJIF"DATA "AAAAAAAEDIFFFFFEDDEFIIIKKEEFFFIIIJJJJJJJJJJJJIIJIDGDEIIIFFEEEEEEEFFIIFFFFFFEEFFIFIJJIIJIII"DATA "AAAAAAAGDFEFFFKEDDEFIIFIKEDEEFIIJJJJJJJJJJJJJIIIJEGGEEIEEEEEEDDEFFEEEFFFFFFDEEFIIIIJIIJIII"DATA "AAAAAAADKEEFFFFEDEEIIIIIIFDEEFFIIIJJJJJJJJJIIJJIKDGHDKFEEEEEEDEEFFFEEFFFFEFEFIFIIIIJJIJIIB"DATA "AAAAAAADKEEFFFFEEEEIIIIIIFDDEEFIIIJJJJJJJIIIIJJIKHGHDKFEEEEEEDEEFFFFFFFFFDEEFIFIIIIJJJIIFA"DATA "AAAAAAADFEEFFFFEEEFIIIIFIFDDDEFIIIIJJJJIIIIIIIEEDHGCDKFEEEEEEDEEEFFFFFFFFDEDEFIIIIIIJJJJIA"DATA "AAAAAABKEDEFFFEEEEFFIIFFKKDDDEEFIIIIJJIIIIIIFEDMCMCCDEIEEEEEEEEEEFFFIFFFFFKEFFIIIIJIJJJJIA"DATA "AAAAAABEFFFFFEEEEEFIIFFFEKFDDDFIIIIJJIIIEEEEEDDGCCCCDEEEEEEEEEDEEFIFFFEFFFFDFIIIIIIJIJJJIA"DATA "AAAAAABDDFFFFFEEEEFIFEEEEKFEDDDEEEEFIFEFDFEEDKDHCCCCHEFEEEEEEDDDEFIIIFFFFKEDIEIIIIIJJJJJIA"DATA "AAAAAABEEIFFFFEEEEFIEDDDEFFDDDDEFEEEFEEEEEEDDEEHCCCCDKEEEEEEEDDDEEFIIFFFFKEDFEIIIIIJJJJJIA"DATA "AAAAAAADDIFFFFEEEEFIEDDDEEIEEEEEFFIFFEFKEEKEDDDHCCHGHEDEEEEEEDDDDEFIIIFFIKEEDIIIIIIJJJJIIA"DATA "AAAAAAADEEFFFFFEEEEFDDDDDDIEEEDDFIFFFDEEIEEDDDDGCCCCDEDDEDDEDDDDDEFIIFIIIIFFDIFIIIIJJJJJIA"DATA "AAAAAABDDDFFFFFEEEEEDDHDDDKEEEEKEFFIFIFJEFFEEDHGCGCGDDDKDDDDDDDDDEFIIIIIIIEEEIFIIIIJJJIJIA"DATA "AAAAAABEDEFFFFFEEEEEDDHDDDKEEEEKEFFIFFEEFEEFKKEGHGGHDEDEEEDDDDDDDEEIIIIIFFEEFIIIIIIJIJIJIA"DATA "AAAAAAADDGEEEEFEEEEDDDHHDDFEFFEEEFFIIEEFIFFEEKKEDHDHDDDHHEKDDDDDDDEFFIIIIFFFIEIIIIIJJIJJIA"DATA "AAAAAAADDEEEEEFEEEEDDDHGDDKKFIFEEFFIIIIIIFFFEDEEDEDDDKDHDGDDDDDDDDEFFIIIIFEFIFIIIIIJJIJIIA"DATA "AAAAAABDDKFEEEEEDDDHHHHCHDEKFFEEEEFIIJIFFKIFIIFIIFEEDEDDDGDDDDDDDDEFFIIIIFEFIIFIIEIJJIJJIA"DATA "AAAAAAADDEKEEEEDDDHHHHCCCHDEIIEEFFFIIIDEKKKEFIIIIFEEDEDDDGDDDDDDDDDFFIIIIIFFEEFIFEIJJIIJJA"DATA "AAAAAAAEEMFEEEDDDHCCCCCCCCHDEFFFFFIIIJIDEDDDDDKKEDEDGEDGDDEDDDDDDDDFFFIIIIEFEFIIFFIJJJJJJA"DATA "AAAABABDDGEEEEDDDCCCCCCCCCHHDDFEFFIIIIIIKDDDEEDGGGGHHDDDDEEEDDDDDDDEFFIIIIDFEEFIFFIJJIJJJA"DATA "AAAAAAKDEDKEEDDDHCCCCCCCCCCHDDDDDDEIIIIJIDEIDDKGDHGGDDDEEEEEDDDDDDDEFFIIIFFEEDIIIJJJJJJJLJ"DATA "AAAAAAKDDKDDDDDDHCCCCCCCCCCHDDDDDDEIIIIJJEEIDDFDEDGGDDEFEEEDDDDHDDDEFFIIIFEEEFKIIIJJJIIJLN"DATA "AAAAAAKEDKDDDDDDHCCCCCCCCCCHDDDDDDEIIJIJJJIIJEEDEEEEDEFFFEDEDDDHDDDEEFFIIFEEEKKFJJJJJJJIBA"DATA "AAABBAGDDGDDDDDHCCCCCCCCCCCHDDDDDDEFIJJJJIIJIEEFDDEKFKEFEEDDDHHHHDDEEEFFFIKEEDKIIIJJJIIJLA"DATA "AAABAAHDEDDDDDDHCCCCCCCCCCCHDDDDDDEFIJJJIJJJJFFIIEDEEFEDEDDDDHHHHHDEEEFFFEFFEEFIFIJJJJJIJA"DATA "AAABBADDDDDDDDDGCCCCCCCCCCHHDDDDDDDEIJJIJNJJIFJIIFDEEFEDDDHHHHHHCHDDDFFIIEFFEEKIIIJJJIJIBA"DATA "AAAABAEDGDDDDDDGGCCCCCCCCCCHDDDDDDDEIJJIJJJIIIIIIFDEEFEEDDGHHHHHCHDDDFFIIFEKEEFFIINJIIJIBA"DATA "AAAABBKEDEDDDDDGGCCCCCCCCCCHHDDDDDDEIIJJJJJJIFEEEKDDEKKKDDHHHHCCHHDDEEFIIIEKEFEIIIIJJJJJJA"DATA "AAAAKAEGDDDDDDDCCCCCCCCCCCCCHDDDDDDEIJJIJJJJJJIIEFDDEKKDDHGCHCCCHHDDEFIIIFEEEFEIIIFJJJJIJA"DATA "AAAAHBKDDGDDDDDGGCCCCCCCCCHGDDDDDDFIJJJIJJJJJJIIFKDDKEEEGGGCCCHHCHDEFIIIIIJKDKIIFIIJJIJFJB"DATA "AAAAGAKGDDDDDDDGGCCCCCCCCCHGDDDDDDFIJJJIJJJJJNIEEEGGDKKEDHCCCCHHCHDEFIJJJIIFDFJJJJIJJIJIBN"DATA "AAAAGAKDDDDDDDDGGCCCCCCHCCHHDDDDEEIIJJJIJJJJJJJJFKGDGEGDHHCCCCCHCHDFIIJJJIIEEDIJIIIJJJJIBB"DATA "AAAAKBKDGDDDDDDGCCCCCCHHHHDDDDDKKIIJJJJIJJJJJJNJIKDDGHHHHCHHCCGCHDDEFIIIIIIDEFIIJIJIJJJJBA"DATA "AAAABAKDDEDDDDDGCHCCHHHHDDDDDDDEIIIJJJJIJJIJJJJJIKGHCCCGHHHCCCGCHDDEEIIIIIIDIIIFIJJIJJIJAA"DATA "AAAABADGKDHDDDDDHCCCCCHDDDEEFEDFIIJJJJJJJJJIJJJEIFDGHCCGCHCCGCCHDDDDEFFIIJIFIJIEJIJJJIIJAA"DATA "AAAAAGMGGGHDDDDDHCCGHDDEDEEIIIEFJJJJJJJJJJNJIJJJEEGDHCCCHHCCCHHHDDDDDEEIIIFJJEJJJIJJJIIIAA"DATA "AAAAAEDDKDHDDDDHHCCDDEEIEFEFFIFIEEEIJJJJJJJINNJIEDDDCHHHHCCCCHHHDDDDDDDIIIFJIFFJJIJJJIIJAA"DATA "AAAAADDKGGHDDDDHHCCDEKFEIJJEDEFEDDDFJJJJJJJIJIEFDDDDDGHHCCCCGCHHDDDDDEEIIIIFIFFJJIJJJIIIAA"DATA "AAAKAKDKDHHHHDDDHGGEFFIIJJJIDIKDGEEEIJJJNJJJIJDIDIEEDCGGGHGGMGDDEDEEEEEFIIFIIJIIJJJJJIIIAA"DATA "AAADAKDDCHHHHDDDDGGEFIIIJJJIEFKDDEJIJJJJJNNJIIJIIIEFKGGKEKDDGDDDEDEEEEEFFIIFIIIIJJJJJJIINB"DATA "AAAHBBDHGCHDDDEDDGDFIIIIJJJJIEJFKKJIJJJIIIIJJJJNEIFFKDKKKEDHHDDEEDEEEEFEFIIEIEIIJJJJJJJEJB"DATA "AAAKBBDDGHHDDDEDDHDFIIIIJJJJJIIIFFJIIIIIJJJIIJJJDIJIIFDGKEDGHDDDEDEEDFFEFFFEIEIFJJIJJJJJBA"DATA "AAABKJDDGGDDDDKDDDEEIIIJJJJJJJLDJJJIIFFIIIIJJJIJJJJNIIIEEDDGHDDDEDEEEFFEEFEFFIFIJJJJJJJIAA"DATA "AAAABKDDGDDDDEEDDGEEFIIJJJNNNJNEJJFJIIIIIJJJJJJJJJINIIIIFEHGGDGGDDEEEFDDEEEFKFFIIJJJJJJIAA"DATA "AAAADJEDGEDDDFEDDDKEFIJJJNNNJNJNJJIJFIIIJJJJJNNNJJJNIJJJIEDHGDDDDDEEEFEDEFEEKIFIIJJJJNJIBA"DATA "AAAAEJEEGEDDDEEDDEKEDEJJNNNNNNJJJJJJIIIIJJJJNLNNNNJIJIJJIFDDGDEDDDEEEEEEEEEEKFEIJJJJJNJIAA"DATA "AAAAKAKDDDEKKKKEDEEFEIJJNNNNNNNNJJJJJJJJJNNNOOONNJJJIJJIIEDDGHDDDDEEEFEKFDEEKEEIJJJJJJJIAA"DATA "AAAAJAKDDEFKIFIEDEEFIIJJNNNJJJNNNJJJJJJJJNNOONNNJIJJINJIFEDDHHDEDDEFFFEKKDEKKEEIJJNNJJNJAA"DATA "AAAABAKDDDIIIIFEEEEFIIJJNNNNNNNNNNNNJJJNNNNOONLJJIJJJJIIIEDHGGDEEDDEEEFDDDDKEEEIIIJJJJJJBA"DATA "AAAAAJKDDFIIIIFEEEFFIIJJJJJNNNNNNNNNNNNNNNNOONJIJIIJJIJIFEDHHGDDEEDDDEDDEDEEEEFIIIJJNJJIBA"DATA "AAAAAEDDDIJJIIFFEEFFIIJJJJJJNNNNNNNNNNNNOLOOOOJNNJJNNJJIFDDHHDDDDEEEEDDDDDEEKFEIIIJJJJJIBA"DATA "AAAAAEDDDIJJJIIFEEFFIIJJJJJJNNNNNNNNNNNNLOOOOOJNNNNNJJJIFDDHHDDGDEEDDDDDDEFEKEFIIIJJJJJJLA"DATA "AAAAAJDDEJJJJIIFEEFFIIJNJJJNNNNNNNNNOOOOLLOOOJJNNNJJJJIIFDHHHDDDDEEEDEDDDEKEIFIIIFJJNJJJJA"DATA "AAAAABDDKIJJJIIFFEFFIIJNJJJNNNNNOOOOOLLOLLOLLOJNNJJJIIIIFDGHDDDDEEFEDEDEEEFFIFIIIJJJNJJIIA"DATA "AAAAABEEIIJJIIIFFFFIIJJNJJJNNNNNNOLOOLLOLOOOLONNNJJJIJJIIEDDDEEEEEFEEEDFFEFFIIIIIJJJNNJIIA"DATA "AAAAAAKKIJJIIIIFFFFIIJJNJJJNNNNNNOLLOLLOLOOOLONNJJJJJJJJIFDDEEEEEEFEEEFFFFFIIIIIIIIJJJJJIA"DATA "AAAAABFKIJJIIIIFFFFIIJJNJJJNNNNNNOLLNLLOLLLLLONLNNIJJJJJJFDDEFEEEEKEEEIFFFFIIIIIIIJJNNNJIA"DATA "AABAAADJJIJIIIFFFEEIIJJJJJJJNNNNOONOONOOLLLLOOOOLJJJJJJJJIEEFFEEDEIFEFIIIIEFFFIIIIJJNNJIFA"DATA "AAAAABEIIJIIIIFFFEEIIJJJJJJJNNNNOONOOOOOOOOOOLLLNNJJJJJNJJFFIIEEEEFFIIIIIFFFFIIIIIJJJNNIEB"DATA "AAAAAJIIIJIIIIFFFFFIIJJJJJJNNNNNOONOOOOOLOOOOOLOLNNNNJJNJJIIIEEFEEFIIIIIIIEIIFIJJJJNJNNIEA"DATA "AAAAABIIIIIIIIFFFFFIIJJJJJJNNNNNOONOONOOLLLLOOLOOJNNNJJNJJIIIFEEEEFFIIIIIFFIIIIJJJJNJNJIEA"DATA "AAAABAEIIIJIIIFIIFEFIIJJJJNJNNNNNNLLLNNLLLLLOOLONNJNNNJJJJIIIFFFKDFFEEIFEFIIEIIIJJJNNNJJFB"DATA "AAAABBEJFIJIIIFIIIFFIIJJNNJNNNNNLLLONOOONLLOLLLOONNNNNJJJIFFEEEEEEFEEIEDDIFIIFIIJJJJNNJIFJ"DATA "AAAAABJIJIJIIIFFFIFFIIJNJJJNNNNNNNNOLLLNNOOOLLLOOLNJNJNJIFDDDDDEEEDEEIFDDFFIIFIIJJJJNNJFFK"DATA "AAAAAAKINIJIIIFFFIIFIIJNJNNJNNNNNNNOLOONNOOOLLLOONNJJJNNIIEDDDDDDEDEFIKDDEFIIFIIJJJJNNJEIK"DATA "AAAAABDIJJJIIIFFFIIFIIJJNNJNNNNNNNNNNOLNOLOOOLLONNJJJNNNIIEDEGGHHDEEEEFDDDFEFFFIIJJNNNJEIF"DATA "AAAAAKDKIJJJIIFFFIIIIIJJNNJJNNNNNNNNNOOOOLLLLOOOLNNNNJJJIFEEHCCCCDDKFFKEDEEDFFFIIIJJNNJIIF"DATA "AAAABBDEIJJJIIFFFIIIIIJJNNJNNNNNNNNNNOOOOLONLNNNNNJJNNNJIEDDCGCCHHDKEEKEDFFEDKIIIIJJNNJIIE"DATA "AAAAABDEIIJJJIIFFFIIIIIJJJJNNNNNNNNNNNOOOJNOOOONNLNNNJJJIEDDGHCCCDDEEFEDDEKDGKIFFIJJNLJIEI"DATA "AAAAABDEJIJJJIIFFFIIIIIJJJJNJNNNNNNNNNOONNNNNLNNNNNNNNNJJEDDCCCHHDDDEFDEEEEDDKIFEIJJNNJIEF"DATA "AAAAAAEGAIJJJIFFFFFIIIIJJJJJJJJJJJJNNNNNNNNNNNNNNNNNNNJJIFDDHCHHMCDFKFFKEEEEDKIFFIIJNNJIEF"DATA "AAAABBKJDIIJJJIFFFFIIIIIIIJJJJJJJJJNNNNNNNNNNNNNNNJJNJJJIEDDCCCCCCGDEEEEEEEEEDEFFFIJNJJIEI"DATA "AAABKBDAJFIJJJIIFEFFIIIEIIJJJJJJJJJNNNNNNNNNNNNNNJJJJJJIIDDDHCCGCHDDEFFEFEDDFEDFFFIJJJJIFI"DATA "AAABKBKKAFIIJJIIFEFFIIIFIJJJJJJJJJJNNNNNNNNNNNNNNJJJJJJIFDDDHCCCCCHEFIIFEEDDEEDEFIIJJJJIFI"DATA "AAABKKDBKIIIJJJIFEFFFFIIJJJJJJJJJJJJJNNNNNNNNLNNNJJJJJIIFDDDHHHCCCGDEFIFDEEDDDEEIIJIJJIIII"DATA "AAAAKDDKDFIIIJJIFEEKFFIJJJJJJJNNJJJJJJNNNNNNNNNNNNJJJIIIFDHHHHCCCCGEFFFFFFKKDDDEIIJJJJJIFF"DATA "AAAACHDDKKIIIIJIFDEEFIJJJJJJJJJJJJJJJJJNNNNJNNNJJJJJJJIIFDHHHCCCCCGEFFFFFFFKEDDKIIJJJJJIFF"DATA "AAAACGDKKKIIIIJIFDEEIIJJJJJJJJJJJJJJJJJNNNNJJNJJJJJJJJJIIDHHHCCCCCGEFFIFFFEDDDDKIIJJJJJIFF"DATA "AAAAAHDKKKFIIIIFEDFFIIJJJJJJJJJJJJJJJJNNNNNJJNJJJJJJJJJIIDGGCCCCCCGEFFIFFEDDEDEFIIJIJJJIFF"DATA "AAAAAHGBKFFFIIIIFEEIIJJJJJJJJJJJJJJJNNNLNJJJJNJJJJJJJJJJIEDDDGHHCCGEFIIFFKEEEKEIFFJJJJJJIF"DATA "AAAAAGDBDEFFFIIFEEEIIJJJJJJJJJJJJJJJJNNNNJJNNJJJJJJJJJJJIFEDDHGCCCDEFFFEEEDFKFIIEEJJJJJJIF"DATA "AAAAAGDBKEFFFIIFEDEIIJIIIJJJJJJJJJJJJJNNNJJNNJJJJJJJJJJIIFFEDGCCCCDFIFFEEEEFFFJFIEIJJJJJIF"DATA "AAAAAHDJNKFFFFFEEDFIIIIIIIJJJJJJJJJJJJJJJNNNJJJJJJJJJJJJIFFEFDHHHGDKIIIFFFEIIEEJFIIJJJIJIF"DATA "AAAAAGDAEKFFFFIFEEKIIIIIFFIIJJJJJJJJJJJJJNNJJJJJJJJJJJNJIIFEDDHCHGDKIFFEEEEFIIIJFEEJJIIJIF"DATA "AAAAAHHKEFFFFIIFEEIIIIIFFFIIIIJJJJJJJJJJJJJJJJJJJJJJJJJIIEEEEHCCGDKKIIFFFEEFIIIIIIDIJIIIIF"DATA "AAAAAHGEFEIFIIIFEEIIIIIIIFFIIIIJIJJJJJJJJJJJJJJJJJJJJJJJIFFFDHCCHDFIIIIIIEIIIEFIIIEIJIJIIF"DATA "AAAAAHGKKFIFIIIFEEIIIIIIIIFIIIIJIIIJJJJJJJNJJJJJJJJJJJJJIFFFEHCCDDEIIIIIIFEEFIFIIIIJIIIIIF"DATA "AAAAAHGKKIFFFIIFEEIIIIIFIIEIIIIJIIIJJJJJJJNNJJIIIJJJJJJIIEEEEGCCDEEIIIIIIIIEEDIIIIJJIIEIFE"DATA "AAAAACGKKEFEEFFEDEIIIIFIIFDIIIIIIIIIIJJJJJJJJJJJIIIIJIIIIIFFDHGGDDDFFIIIIIIEFFFIIJEIJIFIIE"DATA "AAAAACGKFIFEEFFEDDKIIIIIIFEEIIIIIIIIIJJJJJJJIIIIIIIIJJJJIIIKDGGCHGGFFIIIIIIEFFIEIIJFIEIIIE"DATA "AAAAAHMKKFFFEEEEDDKIIIIIIFFEIIIIIIIIIIIJJJJJJJIIIIIJJJJJJIIKDGGGCGGFFIIIIIIEFFIJIJIFJFIIIE"DATA "AAAAACGKEIFFFEEDDDEIIIIIIIFEIIIIIIIIIIIJJJIIIIIIIJJJJJJJIIFFDGGHHDEIIIIIIIIFIFJIJIJIFIEIFE"DATA "AABAAHMJFFKKFEDDDDEIIIIFIFFIIIIIIIIIIIIJJJJJJJIJJJJJJJIJIFEEEKDDDEEIIIIIIIIFIFIJJJIIIIEIFE"DATA "AAAAAGDKKEFEEDDDDDDFIIIIFFFEIIIIIIIIIIIIIIIIIIJIIJIIIIIFEIKFEEEEEEFIIIIIIIIEIIIJJJJIIIFFEF"DATA "AAAAAHKDEKFEEDDDDDEFIIIIFFFFFIIIIIFIIIIIIIIIIIIIIJJJJIIIEIKFEEEEFFFIIIJIIJIFFIIJJJJIIIFFEF"DATA "AAAAAKKEEEEEEDDDDDDEIIIIFFIEFFFFFFFFIIIIIIIIIIIIIIIIIIIIIIIFFFFFEEFIIIJJIIIIIIIIIIJIIIFFEE"DATA "AAAAADKJDFEEDDDDDHDEIIIIFFIFFFFFFFEFIIIIIIIIIIIIIIIIIIFIIIFFFFFFFFFIIIIJIIIEIIIIJJJJJJFFEE"DATA "AAAAAGKBMEEEDDDDHHDEKIIIFFFEEEFEEEEFFIIIIIIIIIIIIIIIIIFIIIFEFIIFFFFIIIIIIIFEFIJIIJJIFIFEEE"DATA "AAAAACKAKEEDDDDHCCHDEFFFEEEEEEFFEEEFFIIIIIIIIIIIIIIIIIFFIFEEEFIFFFFIIIIIIIJIIFIJJJJIIIFEEE"DATA "AAABACKABDEEDDDHGCCDEEEEEEEDDEFFEEEFFIIIIIIIIIIIIIIIIIIFFFEEFFIIFFFIIIIIIIIIJIIJJJIEFFEEEE"`
h4tt3n
Posts: 678
Joined: Oct 22, 2005 21:12
Location: Denmark

### Re: Making pixel based 3D objects - VASE

This is really cool BasicCoder2!

I think I have a fix for the blank spots that allow you to see through the models. Rather than moving each pixel to it's right place (which tend to leave empty spots here and there), you go backwards and find the right pixel for each point on the model surface. I made a texture scale & rotate function doing exactly that a while back. Throw in any .bmp image as long as it is square.

Cheers, Mike

Code: Select all

`''                      roto-zooming algorithm''                    coded by Michael S. Nissen''                        jernmager@yahoo.dk'' ==============================================================='' Recoded to run on FBC 32/64 bit WIN, Version 1.05.0, 2017, by MrSwiss'' ===============================================================Type Pixel  As Single   X, Y  As ULong    CEnd Type ''  dim varsDim shared as Any Ptr Img_Buffer''  write the name of the .bmp image you want to rotozoom here:''  (it has to be sqare ie. 100x100 pixels, 760x760 pixels or whatever)Dim As String Img_Name = "phobos.bmp"Dim shared as Integer X_Mid, Y_Mid, scrn_wid, scrn_hgt, P1, P2, P3, P4, CDim shared as Short Img_Hgt, Img_Wid, Img_Lft, Img_Rgt, Img_Top, Img_Btm, X, YDim Shared As Single Cos_Ang, Sin_Ang, Rot_Fac_X, Rot_Fac_Y, Angle = 0, Scale = 1'' changed Function to Sub (+ recoded arguments list)Sub Calc_rotozoom ( ByRef Cos_Ang As Single, _               ByRef Sin_Ang As Single, _               ByVal S_Fact  As Single, _               ByVal NewAng  As Single )  Cos_Ang = Cos(NewAng)*S_Fact  Sin_Ang = Sin(NewAng)*S_FactEnd Sub''  full screenScreenInfo scrn_wid, scrn_hgtscreenRes scrn_wid, scrn_hgt, 32, 2, 1ScreenSet( 0, 1 )''  dim screenpointer (has to be done after screenres)Dim As ULong Ptr Scrn_Ptr = Screenptr''  place image in center of screenX_Mid = scrn_wid\2Y_Mid = scrn_hgt\2Calc_rotozoom(Cos_Ang, Sin_Ang, Scale, Angle)''  find image dimensionsOpen Img_Name For Binary As #1Get #1, 19, Img_WidGet #1, 23, Img_HgtClose #1''  prepare to dim the array that will hold the image.Img_Rgt = (Img_Wid-1)\2Img_Lft = -Img_RgtImg_Btm = (Img_Hgt-1)\2Img_Top = -Img_Btm''  dim array to hold image. Note: pixel (0, 0) is in the center.Dim As Pixel Pixel(Img_Lft to Img_Rgt, Img_Top to Img_Btm)''  imagecreate sprite and load image to spriteImg_Buffer = ImageCreate (Img_Wid, Img_Hgt)Bload (Img_Name, Img_Buffer)''  load image from sprite to array with point command For Y = Img_Top to Img_Btm  For X = Img_Lft to Img_Rgt    With Pixel(X, Y)      .X = X_Mid+X      .Y = Y_Mid+Y      C = Point (X-Img_Top, Y-Img_Lft, Img_buffer)      If C <> RGB(255, 0, 255) Then         .C = C      Else        .C = RGB(0, 0, 0)      End If    End With  Next XNext Y''  we don't need the sprite anymore, kill it ImageDestroy Img_BufferImg_Buffer = 0''  main program loopDo    ''  scale in/out with uparrow/downarrow  If Multikey(80) Then     Scale *= 1.03    Calc_rotozoom(Cos_Ang, Sin_Ang, Scale, Angle)  ElseIf Multikey(72) Then     Scale *= 0.97    Calc_rotozoom(Cos_Ang, Sin_Ang, Scale, Angle)  End If    ''  rotate left/right with leftarrow/rightarrow  If Multikey(77) Then     Angle -= 0.03    Calc_rotozoom(Cos_Ang, Sin_Ang, Scale, Angle)  ElseIf Multikey(75) Then     Angle += 0.03    Calc_rotozoom(Cos_Ang, Sin_Ang, Scale, Angle)  End If    ''  lock screen in order to use screen pointers  'ScreenLock        ''  draw pixel in center of image    Scrn_Ptr[ X_Mid + Y_Mid * scrn_wid ] = Pixel(0, 0).C    ''  draw all other pixels - 4 at a time    For Y = Img_Top to 0      For X = Img_Lft to -1        ''  find pixel positions        P1 = (X_Mid+X) + (Y_Mid+Y) * scrn_wid        P2 = (X_Mid-X) + (Y_Mid-Y) * scrn_wid        P3 = (X_Mid+Y) + (Y_Mid-X) * scrn_wid        P4 = (X_Mid-Y) + (Y_Mid+X) * scrn_wid        ''  erase old pixels (paint them black)        Scrn_Ptr[P1] = 0        Scrn_Ptr[P2] = 0        Scrn_Ptr[P3] = 0        Scrn_Ptr[P4] = 0        ''  rotate and zoom        Rot_Fac_X = X*Cos_Ang - Y*Sin_Ang        Rot_Fac_Y = X*Sin_Ang + Y*Cos_Ang        If Rot_Fac_X < Img_Lft Or Rot_Fac_X > Img_Rgt Then Continue For        If Rot_Fac_Y < Img_Top Or Rot_Fac_Y > Img_Btm Then Continue For        ''  draw new pixels        Scrn_Ptr[P1] = Pixel(Rot_Fac_X, Rot_Fac_Y).C        Scrn_Ptr[P2] = Pixel(-Rot_Fac_X, -Rot_Fac_Y).C        Scrn_Ptr[P3] = Pixel(Rot_Fac_Y, -Rot_Fac_X).C        Scrn_Ptr[P4] = Pixel(-Rot_Fac_Y, Rot_Fac_X).C      Next X    Next Y      'ScreenUnLock    ScreenCopy()    'Sleep 10, 1Loop Until InKey() = Chr(27)`
BasicCoder2
Posts: 3351
Joined: Jan 01, 2009 7:03

### Re: Making pixel based 3D objects - VASE

Your scale and rotate image routine is very good I will add it to my game folder.

With the 3D stuff I usually use circle instead of pset to fill in the gaps but if you can do better?

At the moment I am working on having more than one object in the scene each with their own positions, rotations and velocities.

One issue is generating just the right amount of pixels to cover a surface.

The example below shows how the pixels are generated for a sphere. Starting at a pole it makes ever larger circles until it reaches the equator at which point it makes ever smaller circles. You can end up using more pixels than required or more than is required. In the case of the sphere one solution I had was to compute the chord of the circle and adjust the steps which adjusted the number of pixels for each circle which is shown in the code below.

You can wobble the sphere about by holding down the up/left or the down/right arrow keys at the same time.
Sometimes the direction of rotation will seem to reverse because of the Knecker wire frame cube effect when the dots on the other side of the sphere show through.

The programs below also adds perspective so you will notice the circle around the closest pole to the observer is larger than the circle around the other pole.

Code: Select all

`'some useful definesConst Pi = 4 * Atn(1)Dim Shared As single TwoPi = 8 * Atn(1)Dim Shared As single RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As single DtoR = Pi / 180   ' degrees * DtoR = radianstype Point3D    x as single    y as single    z as single    c as ulongend typedim shared as Point3D ee.x = 0e.y = 0e.z = 900Sub QsortZ(array() As Point3D,begin As Long,Finish As Ulong)    Dim As Long i=begin,j=finish    Dim As Point3D x =array(((I+J)\2))    While I <= J        While array(I).z > X .z:I+=1:Wend        While array(J).z < X .z:J-=1:Wend        If I<=J Then Swap array(I),array(J): I+=1:J-=1    Wend    If J >begin Then QsortZ(array(),begin,J)    If I <Finish Then QsortZ(array(),I,Finish)End Subdim shared as integer MAX_DOTSconst ScrW = 640const ScrH = 480screenres ScrW,ScrH,32Clsdim as single chord,radiusradius = 100'get number of points neededfor angle2 as single = 0 to 179 step 15    chord = (2 * radius * sin( (angle2*DtoR) ))    if chord = 0 then chord = 1  'avoid divide by zero error    for angle1 as single = 0 to 359 step (360/chord)/2        MAX_DOTS = MAX_DOTS + 1            next angle1next angle2dim shared as Point3D abs3DA(MAX_DOTS)  'absolute positionsdim shared as Point3D rel3DA(MAX_DOTS)  'relative positions after any rotationdim shared as integer direction         'direction of rotation'creates pointsdim as integer iifor angle2 as single = 0 to 179 step 15    chord = (2 * radius * sin( (angle2*DtoR) ))    if chord=0 then chord = 1    for angle1 as single = 0 to 359 step (360/chord)/2        abs3DA(ii).x = radius * sin(angle2*DtoR) * cos(angle1*DtoR)        abs3DA(ii).y = radius * sin(angle2*DtoR) * sin(angle1*DtoR)        abs3DA(ii).z = radius * cos(angle2*DtoR)                'color the segments        if angle1>=0 and angle1<90 then            abs3DA(ii).c = rgb(255,0,0)        elseif angle1>=90 and angle1<180 then            abs3DA(ii).c = rgb(0,255,0)        elseif angle1>=180 and angle1<270 then            abs3DA(ii).c = rgb(0,0,255)        elseif angle1>=270 then            abs3DA(ii).c = rgb(200,100,0)        end if        ii = ii + 1    next angle1next angle2dim shared as single angle,x,y,z,rx,ry,rz,px,pydim shared as single aRotX,aRotY,aRotZaRotX = 0 '322aRotY = 0 '56aRotZ = 0dim shared as single magX,magYmagX = 3000magY = 3000sub update()    dim as single cosAngleX,sinAngleX,angleX    dim as single cosAngleY,sinAngleY,angleY    dim as single cosAngleZ,sinAngleZ,angleZ        angleX = aRotX*DtoR        cosAngleX = cos(angleX)    sinAngleX = sin(angleX)        angleY = aRotY*DtoR        cosAngleY = cos(angleY)    sinAngleY = sin(angleY)        angleZ = aRotZ*DtoR        cosAngleZ = cos(angleZ)    sinAngleZ = sin(angleZ)        for i as integer = 0 to MAX_DOTS - 1                'rotate x axis        x = abs3DA(i).x        y = abs3DA(i).y        z = abs3DA(i).z                        rel3DA(i).x = (cosAngleX * x) - (sinAngleX * z)        rel3DA(i).y = y        rel3DA(i).z = (sinAngleX * x) + (cosAngleX * z)                'rotate Y axis        x = rel3DA(i).x        y = rel3DA(i).y        z = rel3DA(i).z                        rel3DA(i).x = x        rel3DA(i).y = (cosAngleY * y) - (sinAngleY * z)        rel3DA(i).z = (sinAngleY * y) + (cosAngleY * z)            'rotate Z axis        x = rel3DA(i).x        y = rel3DA(i).y        z = rel3DA(i).z                rel3DA(i).x = (cosAngleZ * x) - (sinAngleZ * y)        rel3DA(i).y = (sinAngleZ * x) + (cosAngleZ * y)        rel3DA(i).z = z                rel3DA(i).c = abs3DA(i).c                    rel3DA(i).x = rel3DA(i).x - e.x        rel3DA(i).y = rel3DA(i).y - e.y        rel3DA(i).z = rel3DA(i).z - e.z            next i        'sort by distance along z axis    '***dodisort***    Qsortz(rel3DA(),Lbound(rel3DA),Ubound(rel3DA))    end subsub drawPoints()    'draw points    screenlock    cls        for i as integer = 0 to MAX_DOTS - 1                 'this bit is purely to add perspective        dim as single w        w = 1 + (rel3DA(i).z/e.z)        rel3DA(i).x = (rel3DA(i).x-e.x)/w+e.x        rel3DA(i).y = (rel3DA(i).y-e.y)/w+e.y        rel3DA(i).z = (rel3DA(i).z-e.z)/w+e.z                'convert 3d to 2d coordinates        px = (rel3DA(i).x/rel3DA(i).z) * magX        py = (rel3DA(i).y/rel3DA(i).z) * magY        'pset (px+scrW/2,py+scrH/2),rel3DA(i).c        circle (px+scrW/2,py+scrH/2),1,rel3DA(i).c,,,,f        'line (px+scrW/2-1,py+scrH/2-1)-(px+scrW/2+1,py+scrH/2+1),rel3DA(i).c,bf            next i        locate 2,1    print " aRotX =";aRotX    print " aRotY =";aRotY    print " aRotZ =";aRotZ    print " MAX_DOTS =";MAX_DOTS    screenunlock()end subdim as single now1now1 = timerdo        if timer - now1 > 0.01 then        now1 = timer        update()        drawPoints()                if inkey = " " then            aRotX = 0            aRotY = 0            aRotZ = 0            while inkey<>"":Wend        end if                            'rotate around x axis        if multikey(&H48) then            aRotX = aRotX + 1            if aRotX = 360 then aRotX = 0        end if        if multikey(&H50) then            aRotX = aRotX - 1            if aRotX < 0 then aRotX = 359        end if                'rotate around y axis        if multikey(&H4B) then            aRotY = aRotY + 1            if aRotY = 360 then aRotY = 0        end if        if multikey(&H4D) then            aRotY = aRotY - 1            if aRotY < 0 then aRotY = 359        end if                'rotate around z axis        if multikey(&H2C) then   'Z KEY            aRotZ = aRotZ + 1            if aRotZ = 360 then aRotZ = 0        end if        if multikey(&H2D) then   'X KEY            aRotZ = aRotZ - 1            if aRotZ < 0 then aRotZ = 359        end if            end if        sleep 2     loop until multikey(&H01)sleep`

To make it clear how the chord is being used run this demo.
The chord is the red line at angle2 (blue line) and corresponds to the diameter of the circle being drawn by the angle1 loop.

Code: Select all

`screenres 640,480,32circle (300,225),150,rgb(255,255,255)line (300-150,225)-(300+150,225),rgb(255,0,255)line (300,225-150)-(300,225+150),rgb(255,255,255)line (300,225)-(407,119),rgb(0,0,255)line (407,119)-(195,119),rgb(255,0,0)sleep`