home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / w3dvb5 / supernas.bas < prev    next >
Encoding:
BASIC Source File  |  1997-12-22  |  20.3 KB  |  909 lines

  1. Attribute VB_Name = "SUPERNAS1"
  2. ' Modulo per l'algoritmo del Pittore.
  3. ' Routine di entrata: Pittore
  4.  
  5.  
  6. Type Vec_Int
  7.    x As Integer
  8.    Y As Integer
  9. End Type
  10.  
  11. Type Vertex
  12.    x As Integer
  13.    Y As Integer
  14.    Z As Integer
  15.    Used As Integer
  16. End Type
  17. Public v() As Vertex
  18.  
  19.  
  20. Type triadata
  21.    Normal As Vec3
  22.    h As Single
  23.    Color As Integer
  24. End Type
  25.  
  26.  
  27. Type Tria
  28.     Anr As Integer
  29.     Bnr As Integer
  30.     Cnr As Integer
  31.     Z As Integer
  32.     PTria As triadata ' Valore Triadata
  33. End Type
  34.  
  35. Public Triangles() As Tria
  36. Public Ptriangles As Integer
  37.  
  38. Type TriaNode
  39.     trnr As Integer
  40.     NextNodo As Integer
  41. End Type
  42.  
  43.  
  44. Public Const LARGE = 32000 ' // Non maggiore di sqrt(LONG_MAX)
  45. Public Const LARGE1 = 32001 ' Usato solo da LineaNas
  46. Public Const PIdiv180 = 0.0174532
  47. Public Const BIG = 1E+30
  48.  
  49. Public X__max As Integer ' Coordinate reali della finestra
  50. Public Y__max As Integer ' Coordinate reali della finestra
  51.  
  52. Public f As Double
  53. Public zfactor As Double
  54. Public rcolormin As Double
  55. Public rcolormax As Double
  56. Public delta As Double
  57. Public zemin As Double
  58. Public zemax As Double
  59. Public xsC As Double
  60. Public ysC As Double
  61. Public XLCreal As Double
  62. Public YLCreal As Double
  63.  
  64. Public kEye As Integer
  65. Public hK As Integer
  66. Public XLC As Integer
  67. Public YLC As Integer
  68.  
  69.  
  70. Public Vt() As Vec3
  71. Public lightvector As Vec3
  72.  
  73.  
  74.  
  75. Public TriaNodeNext() As TriaNode
  76.  
  77. Public PStart As Integer
  78. Public PEnd As Integer
  79.  
  80.  
  81. Sub Complete_Triangles(n As Integer, offset As Integer, nrs_tr() As Trianrs)
  82.  
  83. '// Completa triangles[offset],..., triangles[offset+n-1].
  84. '// Numeri di vertice: nrs_tr[0],..., nrs_tr[n-1].
  85. '// Questi triangoli appartengono allo stesso poligono. L'equazione
  86. '// del loro piano Φ nx . x + ny . y + nz . z = h.
  87.   
  88.   
  89.   Dim i As Integer
  90.   Dim Anr As Integer
  91.   Dim Bnr As Integer
  92.   Dim Cnr As Integer
  93.   Dim ZA As Integer
  94.   Dim ZB As Integer
  95.   Dim ZC As Integer
  96.   Dim zmin As Single
  97.   Dim zmax As Single
  98.  
  99.   Dim nx As Double
  100.   Dim ny As Double
  101.   Dim nz As Double
  102.   Dim ux As Double
  103.   Dim uy As Double
  104.   Dim uz As Double
  105.   Dim vx As Double
  106.   Dim vy As Double
  107.   Dim vz As Double
  108.   Dim factor As Double
  109.   Dim h As Double
  110.   Dim Ax As Double
  111.   Dim Ay As Double
  112.   Dim Az As Double
  113.   Dim Bx As Double
  114.   Dim By As Double
  115.   Dim Bz As Double
  116.   Dim Cx As Double
  117.   Dim Cy As Double
  118.   Dim Cz As Double
  119.   
  120.   Dim p As Integer
  121.   Dim q As triadata
  122.   
  123. '   // Se il poligono Φ un'approssimazione di una circonferenza, i
  124. '   // primi tre vertici possono giacere quasi sulla stessa linea,
  125. '   // da cui n/2 invece di 0 nell'istruzione for che segue:
  126.   
  127.   For i = n \ 2 To n
  128.      Anr = nrs_tr(i).a
  129.      Bnr = nrs_tr(i).b
  130.      Cnr = nrs_tr(i).C
  131.      If (orienta(Anr, Bnr, Cnr) > 0) Then Exit For
  132.    Next
  133.  
  134.    ZA = v(Anr).Z
  135.    ZB = v(Bnr).Z
  136.    ZC = v(Cnr).Z
  137.  
  138.    Az = zEye(ZA)
  139.    Bz = zEye(ZB)
  140.    Cz = zEye(ZC)
  141.    Ax = xScreen(v(Anr).x) * Az
  142.    Ay = yScreen(v(Anr).Y) * Az
  143.    Bx = xScreen(v(Bnr).x) * Bz
  144.    By = yScreen(v(Bnr).Y) * Bz
  145.    Cx = xScreen(v(Cnr).x) * Cz
  146.    Cy = yScreen(v(Cnr).Y) * Cz
  147.    ux = Bx - Ax
  148.    uy = By - Ay
  149.    uz = Bz - Az
  150.    vx = Cx - Ax
  151.    vy = Cy - Ay
  152.    vz = Cz - Az
  153.    nx = uy * vz - uz * vy
  154.    ny = uz * vx - ux * vz
  155.    nz = ux * vy - uy * vx
  156.    h = nx * Ax + ny * Ay + nz * Az
  157.    factor = 1 / Sqr(nx * nx + ny * ny + nz * nz)
  158.    q.Normal.x = nx * factor
  159.    q.Normal.Y = ny * factor
  160.    q.Normal.Z = nz * factor
  161.    q.h = h * factor
  162.    For i = 0 To n - 1
  163.       p = offset + i
  164.       Triangles(p).Anr = nrs_tr(i).a
  165.       Triangles(p).Bnr = nrs_tr(i).b
  166.       Triangles(p).Cnr = nrs_tr(i).C
  167.       Triangles(p).PTria = q
  168.    '   // Sceglie il lato del triangolo per cui Z varia maggiormente;
  169.    '   // Triangles(p).Z si baserα sul punto medio di questo lato:
  170.       zmin = v(Triangles(p).Anr).Z
  171.       zmax = zmin
  172.       ZB = v(Triangles(p).Bnr).Z
  173.       ZC = v(Triangles(p).Cnr).Z
  174.       If (ZB < zmin) Then
  175.          zmin = ZB
  176.       ElseIf (ZB > zmax) Then
  177.          zmax = ZB
  178.       End If
  179.       If (ZC < zmin) Then
  180.          zmin = ZC
  181.       ElseIf (ZC > zmax) Then
  182.          zmax = ZC
  183.       End If
  184.       Triangles(p).Z = (zmin + zmax) / 2
  185.   
  186.    Next
  187.  
  188. End Sub
  189.  
  190. Sub DeleteList(Start() As TriaNode)
  191.  
  192.    Dim p As TriaNode
  193. '   Do While (Start <> Null)
  194. '     p = start;
  195. '     start = start->next;
  196.  
  197. End Sub
  198.  
  199. Function Distance(ITria As Integer, x As Integer, Y As Integer) As Double
  200.  
  201.  
  202. '// Si considera la linea passante per il punto di osservazione E
  203. '// e il punto (X, Y) del video. Interessa il punto in cui questa
  204. '// linea interseca il triangolo itria. Sarα restituita la
  205. '// coordinata ze di questo punto.
  206.  
  207.   Static Dist0 As Double
  208.   Static X0 As Integer
  209.   Static Y0 As Integer
  210.   Static PTria0 As Integer
  211.    
  212.   Dim a As Double
  213.   Dim b As Double
  214.   Dim C As Double
  215.   Dim h As Double
  216.   Dim xs As Double
  217.   Dim ys As Double
  218.   
  219. '  Dist0 = 0: X0 = 0: Y0 = 0
  220.    
  221.  ' // Variabili statiche, qualora lo stesso punto (X, Y) sia usato
  222.  ' // per due triangoli consecutivi appartenenti allo stesso
  223.  ' // poligono (e quindi con lo stesso puntatore ptria).
  224.   
  225.   Dim TriaPtr As Integer
  226.   Dim PTria As Integer
  227.   
  228.   TriaPtr = ITria
  229. '  PTria = Triangles(TriaPtr).PTria
  230.   
  231.  '  tria huge* triaptr = triangles + itria; // = &triangles[itria]
  232.  '  triadata huge*ptria=triaptr->ptria;
  233.    
  234.    If (PTria0 <> TriaPtr Or x <> X0 Or Y <> Y0) Then
  235.       a = Triangles(TriaPtr).PTria.Normal.x
  236.       b = Triangles(TriaPtr).PTria.Normal.Y
  237.       C = Triangles(TriaPtr).PTria.Normal.Z
  238.       h = Triangles(TriaPtr).PTria.h
  239.       xs = xScreen(x)
  240.       ys = yScreen(Y)
  241.       Dist0 = h * Sqr(xs * xs + ys * ys + 1) / (a * xs + b * ys + C)
  242.       X0 = x
  243.       Y0 = Y
  244.       PTria0 = TriaPtr
  245.    End If
  246.    
  247.    Distance = Dist0
  248.  
  249. End Function
  250.  
  251.  
  252.  
  253. Sub DrawWireFrame(Pic As PictureBox)
  254.  
  255. Dim i As Integer, k As Integer, j As Integer
  256.   
  257. For k = 1 To UBound(FileVertex)
  258.  i = Abs(FileVertex(k).Vert(1))
  259.  If i > 0 Then
  260.     Xl = to_pix(v(i).x)
  261.     Yl = to_pix(v(i).Y)
  262.     x1 = Xl
  263.     y1 = Yl
  264.     For j = 1 To FileVertex(k).Count
  265.         i = FileVertex(k).Vert(j)
  266.         If i > 0 Then
  267.            x = to_pix(v(i).x)
  268.            Y = to_pix(v(i).Y)
  269.            Pic.Line (x1, y1)-(x, Y)
  270.            x1 = x: y1 = Y
  271.         End If
  272.     Next j
  273.  End If
  274.           
  275. Next
  276.  
  277.    
  278. End Sub
  279.  
  280. Sub Fill_Triangle(Pic As PictureBox, i As Integer)
  281.  
  282. ' // Riempie il triangolo i
  283.  
  284.  Dim Triangle(2) As CornerRec
  285.  Dim Anr As Integer
  286.  Dim Bnr As Integer
  287.  Dim Cnr As Integer
  288.  
  289.  Anr = Triangles(i).Anr
  290.  Bnr = Triangles(i).Bnr
  291.  Cnr = Triangles(i).Cnr
  292.  
  293.  Triangle(0).x = to_pix(v(Anr).x)
  294.  Triangle(0).Y = to_pix(v(Anr).Y)
  295.  
  296.  Triangle(1).x = to_pix(v(Bnr).x)
  297.  Triangle(1).Y = to_pix(v(Bnr).Y)
  298.  
  299.  Triangle(2).x = to_pix(v(Cnr).x)
  300.  Triangle(2).Y = to_pix(v(Cnr).Y)
  301.  
  302.  Shade% = Triangles(i).PTria.Color
  303.  
  304.  Call DrawTriangle(Pic, Triangle(), Shade%)
  305.  
  306. End Sub
  307.  
  308. Sub FindRange(i As Integer)
  309.    Dim Normal As Vec3
  310.    Normal.x = Triangles(i).PTria.Normal.x
  311.    Normal.Y = Triangles(i).PTria.Normal.Y
  312.    Normal.Z = Triangles(i).PTria.Normal.Z
  313.    Dim rcolor As Single
  314.    rcolor = DotProduct(Normal, lightvector)
  315.    If (rcolor < rcolormin) Then rcolormin = rcolor
  316.    If (rcolor > rcolormax) Then rcolormax = rcolor
  317. End Sub
  318.  
  319.  
  320. Function Inside_Triangle(x As Integer, Y As Integer, XA As Integer, YA As Integer, XB As Integer, YB As Integer, xC As Integer, yC As Integer) As Integer
  321.  
  322.  
  323. '  // (X, Y) giace sopra o dentro il triangolo ABC?
  324.    
  325.  Inside_Triangle = Orientation(XB - XA, YB - YA, x - XA, Y - YA) >= 0 And _
  326.                   Orientation(xC - XB, yC - YB, x - XB, Y - YB) >= 0 And _
  327.                   Orientation(XA - xC, YA - yC, x - xC, Y - yC) >= 0
  328.    
  329. End Function
  330.  
  331.  
  332. Function Int_To_Pix(x As Double)
  333.   Int_To_Pix = (x + hK) / k
  334. End Function
  335.  
  336. Function IntersectOrizontal(a As Vec_Int, b As Vec_Int, Y As Integer, xxMin As Integer, xxmax As Integer) As Integer
  337.  
  338.  
  339. ' // Il segmento AB ha dei punti in comune con il
  340. ' // segmento orizzontale {(Xmin, Y), (Xmax, Y)}?
  341.  
  342.  
  343. Dim XA As Integer
  344. Dim YA As Integer
  345. Dim XB As Integer
  346. Dim YB As Integer
  347. Dim dx As Long
  348. Dim dy As Long
  349. Dim yDx As Long
  350.  
  351.    XA = a.x
  352.    YA = a.Y
  353.    XB = b.x
  354.    YB = b.Y
  355.  
  356.  
  357.    If (YA < Y And YB < Y Or YA > Y And YB > Y) Then
  358.       IntersectOrizontal = 0
  359.       Exit Function
  360.    End If
  361.    
  362.    If (YA = Y And XA >= xxMin And XA <= xxmax Or _
  363.        YB = Y And XB >= xxMin And XB <= xxmax) Then
  364.        IntersectOrizontal = 1
  365.       Exit Function
  366.    End If
  367.    
  368.    If (YA = YB) Then
  369.       IntersectOrizontal = YA = Y And (CLng(XA - xxmax) * (XB - xxmax) < 0 Or CLng(XA - xxMin) * (XB - xxMin) < 0)
  370.       Exit Function
  371.    End If
  372.       
  373.    If (YA > YB) Then
  374.       Swap XA, XB
  375.       Swap YA, YB
  376.    End If
  377.    
  378.    dx = XB - XA
  379.    dy = YB - YA
  380.    XdY = XA * dy + (Y - YA) * dx
  381.    
  382.    IntersectOrizontal = XdY >= xmin * dy And XdY <= xmax * dy
  383.  
  384. End Function
  385.  
  386.  
  387.  
  388.  
  389.  
  390. Function IntersectVertical(a As Vec_Int, b As Vec_Int, x As Integer, yyMin As Integer, yymax As Integer) As Integer
  391.  
  392. ' // Il segmento AB ha dei punti in comune con il
  393. ' // segmento verticale {(X, Ymin), (X, Ymax)}?
  394.  
  395. Dim XA As Integer
  396. Dim YA As Integer
  397. Dim XB As Integer
  398. Dim YB As Integer
  399. Dim dx As Long
  400. Dim dy As Long
  401. Dim yDx As Long
  402.  
  403.    XA = a.x
  404.    YA = a.Y
  405.    XB = b.x
  406.    YB = b.Y
  407.    
  408.    If (XA < x And XB < x Or XA > x And XB > x) Then
  409.       IntersectVertical = 0
  410.       Exit Function
  411.    End If
  412.  
  413.    If (XA = x And YA >= yyMin And YA <= yymax Or _
  414.        XB = x And YB >= yyMin And YB <= yymax) Then
  415.       IntersectVertical = 1
  416.       Exit Function
  417.    End If
  418.    
  419.    If (XA = XB) Then
  420.       IntersectVertical = XA = x And (CLng(YA - yymax) * (YB - yymax) < 0 Or CLng(YA - yyMin) * (YB - yyMin) < 0)
  421.       Exit Function
  422.    End If
  423.        
  424.    If (XA > XB) Then
  425.       Swap XA, XB
  426.       Swap YA, YB
  427.    End If
  428.    
  429.    dx = XB - XA
  430.    dy = YB - YA
  431.    yDx = YA * dx + (x - XA) * dy
  432.    IntersectVertical = yDx >= yyMin * dx And yDx <= yymax * dx
  433.  
  434. End Function
  435. Sub LoadVec3(Vettore() As Vec3, i As Integer, x As Double, Y As Double, Z As Double)
  436.     Vettore(i).x = x
  437.     Vettore(i).Y = Y
  438.     Vettore(i).Z = Z
  439. End Sub
  440.  
  441. Sub Pittore(Pic As PictureBox, Come As Integer)
  442.  
  443. Dim i As Integer
  444. Dim k As Integer
  445. Dim vertexnr As Integer
  446. Dim maxnpoly As Integer
  447. Dim totntria As Integer
  448. Dim code As Integer
  449. Dim ntr As Integer
  450. Dim Poly() As Integer
  451. Dim nPoly As Integer
  452. Dim k1 As Integer
  453. Dim k2 As Integer
  454. Dim XLMax As Integer
  455. Dim YLMax As Integer
  456. Dim nvertex As Integer
  457. Dim Pnr As Integer
  458. Dim Qnr As Integer
  459. Dim Orient As Integer
  460. Dim testtria(3) As Integer
  461.  
  462. Dim nrs_tr() As Trianrs ' // Il tipo trianrs Φ dichiarato in triangol.h
  463. Dim t1 As Single
  464. Dim t2 As Single
  465.  
  466. Dim fx As Double
  467. Dim fy As Double
  468. Dim rho As Double
  469. Dim Theta As Double
  470. Dim Phi As Double
  471. Dim xs As Double
  472. Dim ys As Double
  473. Dim xe As Double
  474. Dim ye As Double
  475. Dim ze As Double
  476. Dim xsRange As Double
  477. Dim ysRange As Double
  478. Dim xsmin As Double
  479. Dim xsmax As Double
  480. Dim ysmin As Double
  481. Dim ysmax As Double
  482.  
  483.  
  484. Dim x As Double
  485. Dim Y As Double
  486. Dim Z As Double
  487.  
  488. Dim Ch As String
  489. Dim method As String
  490. Dim St As String
  491.  
  492.  
  493. rcolormin = BIG
  494. rcolormax = -BIG
  495.  
  496. AlgoritmoAttivo = 0 ' per Orienta
  497.    
  498.    
  499.    nvertex = MaxVertNr + 1
  500.    ReDim Vt(nvertex)
  501.    
  502.    SetVista rho, Theta, Phi
  503.    lightvector = AssignVec3(-1, 1, 0)
  504.    SetLimitiVista xsmin, xsmax, ysmin, ysmax, nvertex, Vt()
  505.    
  506. '   // Calcola le costanti del video:
  507.   
  508.   xsRange = xsmax - xsmin
  509.   ysRange = ysmax - ysmin
  510.  
  511.   xsC = 0.5 * (xsmin + xsmax)
  512.   ysC = 0.5 * (ysmin + ysmax)
  513.   k1 = LARGE / (X__max + 1)
  514.   k2 = LARGE / (Y__max + 1)
  515.   kEye = Min2(k1, k2)
  516.   hK = kEye / 2             '  // k = 50, hk = 25 con VGA
  517.   XLMax = kEye * (X__max + 1)
  518.   YLMax = kEye * (Y__max + 1)
  519.   
  520.   ' // Coordinate dei pixel: Xpix = to_pix(X) and Ypix = to_pix(Y)
  521.   
  522.   XLC = XLMax / 2
  523.   YLC = YLMax / 2
  524.   XLCreal = XLC + 0.5
  525.   YLCreal = YLC + 0.5
  526.   fx = XLMax / xsRange
  527.   fy = YLMax / ysRange
  528.   If fx < fy Then
  529.      f = 0.95 * fx
  530.   Else
  531.      f = 0.95 * fy
  532.   End If
  533.   zfactor = LARGE / (zemax - zemin)
  534.    
  535.   ReDim v(nvertex)
  536.   
  537.  '  // Inizializza l'array dei vertici:
  538.    For i = 0 To nvertex - 1
  539.       If (Vt(i).Z < -100000#) Then
  540.          v(i).Used = False        ' V[i] non in uso
  541.       Else
  542.          v(i).Used = True
  543.             
  544.          xs = Vt(i).x / Vt(i).Z
  545.          ys = Vt(i).Y / Vt(i).Z
  546.          
  547.          v(i).x = XLarge(xs)
  548.          v(i).Y = YLarge(ys)
  549.          v(i).Z = ZLarge(Vt(i).Z)
  550.       End If
  551.    Next
  552.    
  553.    If Come = 0 Then
  554.       DrawWireFrame Pic
  555.       Exit Sub
  556.    End If
  557.    
  558.    Erase Vt
  559.    
  560. '   // Trova il numero massimo di vertici in un solo poligono
  561. '   // e il numero totale dei triangoli che non sono
  562. '   // retrosuperfici:
  563.    
  564. maxnpoly = 0
  565. totntria = 0
  566.  
  567. nPoly = 0
  568. For k = 1 To UBound(FileVertex)
  569.  nPoly = 0
  570.  i = Abs(FileVertex(k).Vert(1))
  571.  If i > 0 Then
  572.     For j = 1 To FileVertex(k).Count
  573.         i = Abs(FileVertex(k).Vert(j))
  574.               
  575.         If i >= nvertex Or Not v(i).Used Then
  576.            MsgBox "Vertice nr." & CStr(i) & " indefinito"
  577.            End
  578.         End If
  579.         If nPoly < 3 Then testtria(nPoly) = i
  580.     
  581.         nPoly = nPoly + 1
  582.     Next j
  583.          
  584.          If (nPoly > maxnpoly) Then maxnpoly = nPoly
  585.          If Not (nPoly < 3) Then  '  // Ignora il segmento 'libero'
  586.             If (orienta(testtria(0), testtria(1), testtria(2)) >= 0) Then totntria = totntria + nPoly - 2
  587.          End If
  588.          
  589.  End If
  590.           
  591. Next
  592.          
  593.          
  594. ' =========
  595.  
  596.   ReDim Triangles(totntria)
  597.   ReDim Poly(maxnpoly)
  598.   ReDim nrs_tr(maxnpoly - 2)
  599.  
  600.  
  601. '   // Lettura delle facce dell'oggetto e memorizzazione dei
  602. '   // triangoli:
  603.    
  604.    
  605. For k = 1 To UBound(FileVertex)
  606.          
  607.     nPoly = 0
  608.     For j = 1 To FileVertex(k).Count
  609.         
  610.         i = Abs(FileVertex(k).Vert(j))
  611.         If nPoly = maxnpoly Then
  612.            MsgBox "Errore di programmazione maxnpoly"
  613.            End
  614.         End If
  615.         Poly(nPoly) = i
  616.         nPoly = nPoly + 1
  617.     
  618.     Next j
  619.     
  620.    
  621.     If (nPoly >= 3) Then
  622.     
  623.     Pnr = Abs(Poly(0))
  624.     Qnr = Abs(Poly(1))
  625.     For i = 2 To nPoly - 1
  626.       Orient = orienta(Pnr, Qnr, Abs(Poly(i)))
  627.       If (Orient <> 0) Then Exit For ' // Normalmente, i = 2
  628.     Next
  629.    
  630.    End If
  631.    
  632.     If (Orient >= 0) Then   ' ; // Non Retrosuperficie
  633.    
  634. '      // Suddivisione di un poligono in triangoli:
  635.       
  636.       code = Triangul(Poly(), nPoly, nrs_tr(), Orient)
  637.       If (code > 0) Then
  638.         If (ntr + code > totntria) Then
  639.              MsgBox "Errore di programmazione: totntria"
  640.              End
  641.         End If
  642.         Call Complete_Triangles(code, ntr, nrs_tr())
  643.         ntr = ntr + code
  644.       End If
  645.       
  646.    End If
  647.       
  648. Next k
  649.    
  650. Erase Poly
  651. Erase nrs_tr
  652.  
  653.    
  654.    For i = ntr - 1 To 0 Step -1
  655.        FindRange i
  656.    Next
  657.    
  658.    ncolors = 12
  659.    delta = 0.999 * (ncolors - 1) / (rcolormax - rcolormin + 0.001)
  660.    
  661.    For i = ntr - 1 To 0 Step -1
  662.      Call Set_Tr_Color(i)
  663.    Next
  664.    
  665.   
  666.      ntr_b% = ntr
  667.      Call Q_Sort(Triangles(), 0, ntr_b%)   '  triangles[0] Φ il triangolo pi∙ vicino
  668.    
  669.      For i = ntr - 1 To 0 Step -1
  670.        Fill_Triangle Pic, i
  671.      Next
  672.  
  673. End Sub
  674.  
  675. Function Max2(i As Integer, j As Integer) As Integer
  676.      If i > j Then Max2 = i Else Max2 = j
  677. End Function
  678.  
  679. Function Max3(i As Integer, j As Integer, k As Integer) As Integer
  680.     Max3 = Max2(i, Max2(j, k))
  681. End Function
  682.  
  683.  
  684. Function Min2(i As Integer, j As Integer) As Integer
  685.      If i < j Then Min2 = i Else Min2 = j
  686. End Function
  687.  
  688. Function Min3(i As Integer, j As Integer, k As Integer) As Integer
  689.         Min3 = Min2(i, Min2(j, k))
  690. End Function
  691.  
  692. Function orienta(Pnr As Integer, Qnr As Integer, Rnr As Integer) As Integer
  693.   If AlgoritmoAttivo = 0 Then ' Pittore
  694.      orienta = Orientation(v(Qnr).x - v(Pnr).x, v(Qnr).Y - v(Pnr).Y, v(Rnr).x - v(Pnr).x, v(Rnr).Y - v(Pnr).Y)
  695.   Else
  696.      orienta = LOrienta(Pnr, Qnr, Rnr)
  697.   End If
  698. End Function
  699.  
  700. Function Orientation(u1 As Integer, U2 As Integer, v1 As Integer, v2 As Integer) As Long
  701.    Dim Det As Long
  702.  
  703.    Det = CLng(u1) * v2 - CLng(U2) * v1
  704.    If Det < -250 Then
  705.       Det = -1
  706.    ElseIf Det > 250 Then
  707.       Det = 1
  708.    End If
  709.  
  710.    Orientation = Det
  711.  
  712. End Function
  713.  
  714. Sub Q_Sort(a() As Tria, Ptr As Integer, n As Integer)
  715.     
  716.  ' Quick Sort
  717.  ' a = Triangles()
  718.  ' Ptr = Puntatore ad a()
  719.  ' n = Num. elemento corrente per il sort
  720.  
  721.  
  722.     Dim i As Integer, j As Integer
  723.     Dim x As Tria
  724.     Dim w As Tria
  725.  
  726.    Do
  727.       i = Ptr
  728.       j = n - 1
  729.       x = a(j / 2)
  730.       Do
  731.          Do While (a(i).Z < x.Z): i = i + 1: Loop
  732.          Do While (a(j).Z > x.Z): j = j - 1: Loop
  733.  
  734.          If (i < j) Then
  735.               w = a(i)
  736.               a(i) = a(j)
  737.               a(j) = w
  738.           End If
  739.           i = i + 1
  740.           j = j - 1
  741.       Loop While i <= j
  742.           
  743.       If i = j + 3 Then
  744.          i = i - 1
  745.          j = j + 1
  746.       End If
  747.  
  748.       If j + 1 < n - i Then
  749.          If j > 0 Then Q_Sort a(), 0, j + 1
  750.         ' Ptr = Ptr + i
  751.          n = n - i
  752.        Else
  753.          Pt% = i
  754.          If i < n - 1 Then Q_Sort a(), Pt%, n - i
  755.          n = j + 1
  756.        End If
  757.   
  758.   Loop While n > 1
  759.  
  760. End Sub
  761.  
  762. Sub Set_Tr_Color(i As Integer)
  763.    Dim Color As Integer
  764.    Dim rcolor As Double
  765.    Dim Normal As Vec3
  766.    
  767.    Normal.x = Triangles(i).PTria.Normal.x
  768.    Normal.Y = Triangles(i).PTria.Normal.Y
  769.    Normal.Z = Triangles(i).PTria.Normal.Z
  770.    rcolor = DotProduct(Normal, lightvector)
  771.    Color = 1 + (rcolor - rcolormin) * delta
  772.    If (Color < 0) Then MsgBox ("Codice colore negativo")
  773.    If (Color >= 16) Then MsgBox ("Codice colore troppo grande")
  774. '  // (in caso di un errore di programma)
  775.    Triangles(i).PTria.Color = Color
  776.   ' MsgBox Color
  777. End Sub
  778.  
  779. Sub SetLimitiVista(xsmin As Double, xsmax As Double, ysmin As Double, ysmax As Double, nvertex As Integer, Vt() As Vec3)
  780.  
  781.  Dim PNew As Vec3
  782.  Dim Ve As Vec3
  783.  Dim Vi As Vec3
  784.  Dim Va As Vec3
  785.  
  786.  Dim i As Integer
  787.  Dim k As Integer
  788.    
  789.    For i = 0 To nvertex
  790.       Vt(i).Z = -1000000# ' Non usato
  791.    Next
  792.    
  793.    
  794.    xsmin = BIG
  795.    ysmin = BIG
  796.    zemin = BIG
  797.    xsmax = -BIG
  798.    ysmax = -BIG
  799.    zemax = -BIG
  800.       
  801.  
  802. For k = 1 To UBound(FileCoord)
  803.       
  804.       i = FileCoord(k).i
  805.       Vi.x = FileCoord(k).x
  806.       Vi.Y = FileCoord(k).Y
  807.       Vi.Z = FileCoord(k).Z
  808.       
  809.   If i > 0 Then
  810.       
  811.       If (i >= nvertex) Then
  812.          MsgBox "Troppi vertici o numero di vertice non legale"
  813.          End
  814.       End If
  815.       
  816.       PNew.x = Vi.x - ObjPoint.x
  817.       PNew.Y = Vi.Y - ObjPoint.Y
  818.       PNew.Z = Vi.Z - ObjPoint.Z
  819.       
  820.       Call Eyecoord(PNew, Ve)
  821.       Va.x = Ve.x
  822.       Va.Y = Ve.Y
  823.       Va.Z = Ve.Z
  824.  
  825.       If (Va.Z < 0) Then
  826.          MsgBox "Il punto 0 dell'oggetto e un vertice " & Chr(10) & "su lati diversi del punto di osservazione E." & Chr(10) & "Provare con un valore maggiore per rho."
  827.          Exit Sub
  828.       End If
  829.  
  830.       xs = Va.x / Va.Z
  831.       ys = Va.Y / Va.Z
  832.  
  833.       If (xs < xsmin) Then xsmin = xs
  834.       If (xs > xsmax) Then xsmax = xs
  835.       If (ys < ysmin) Then ysmin = ys
  836.       If (ys > ysmax) Then ysmax = ys
  837.       If (Va.Z < zemin) Then zemin = Va.Z
  838.       If (Va.Z > zemax) Then zemax = Va.Z
  839.       Vt(i) = Ve
  840.   
  841.   End If
  842.  
  843. Next k
  844.       
  845. If (xsmin = BIG) Then
  846.  MsgBox "File di input non corretto"
  847.  End
  848. End If
  849.  
  850.  
  851. End Sub
  852.  
  853. Sub SetVista(rho As Double, Theta As Double, Phi As Double)
  854.    
  855.    ObjPoint = AssignVec3(0.5 * (xmin + xmax), 0.5 * (ymin + ymax), 0.5 * (zmin + zmax))
  856.    rho = xmax - xmin
  857.    If (ymax - ymin > rho) Then rho = ymax - ymin
  858.    If (zmax - zmin > rho) Then rho = zmax - zmin
  859.    rho = rho * 3
  860.    Theta = 20
  861.    Phi = -65
  862.  
  863.    Call Coeff(rho, Theta * PIdiv180, Phi * PIdiv180)
  864.  
  865. End Sub
  866.  
  867. Sub Swap(x As Integer, Y As Integer)
  868.  
  869.    Dim t As Integer
  870.    t = x
  871.    x = Y
  872.    Y = t
  873.    
  874. End Sub
  875.  
  876. Function to_pix(x As Integer) As Integer
  877.  
  878. '  // Arrotondamento e conversione
  879.  to_pix = (x + hK) / kEye
  880.  
  881.  
  882. End Function
  883.  
  884.  
  885. Function XLarge(xs As Double) As Integer
  886.     XLarge = Int(XLCreal + f * (xs - xsC))
  887. End Function
  888.  
  889. Function xScreen(x As Integer) As Double
  890.    xScreen = xsC + (x - XLC) / f
  891. End Function
  892.  
  893. Function YLarge(ys As Double) As Integer
  894.      YLarge = Int(YLCreal + f * (ys - ysC))
  895. End Function
  896.  
  897. Function yScreen(Y As Integer) As Double
  898.      yScreen = ysC + (Y - YLC) / f
  899. End Function
  900.  
  901. Function zEye(Z As Integer) As Double
  902.        zEye = Z / zfactor + zemin
  903. End Function
  904.  
  905. Function ZLarge(ze As Single) As Integer
  906.    ZLarge = Int((ze - zemin) * zfactor + 0.5)
  907. End Function
  908.  
  909.