home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / FAQSYS18.ZIP / FAQS.DAT / LENS.TXT < prev    next >
Text File  |  1993-07-22  |  11KB  |  244 lines

  1. This is some info on how one could implement a lens.
  2. You should also have the file lens.gif, which contains some pictures to
  3. clarify this text.
  4. The first part is some stuff in general, the real explanation of the lens
  5. transformation is in the second part.
  6.  
  7.  
  8. How to implement the transformation
  9. -----------------------------------
  10.  
  11. The main idea is: I want to transform a fraction of a picture.
  12. Consider the smallest square possible, that contains all pixels affected by the
  13. transformation. That is the 'blue' part of the picture.
  14. I'm considering a precalculated transformation, so the dimensions of the
  15. blue square are know (and constant). Therefore, I also know the total amount of
  16. pixels involved in the transformation. Lets say NPI is a constant, representing
  17. the 'N'umber of 'P'ixels 'I'nvolved. (That is the number of 'blue' pixels)
  18. My program then requires 3 arrays: ORG[NPI], TFM[NPI] and DEST[NPI].
  19.  
  20. I first copy all 'blue' pixels to the array, called ORG. 
  21. [  Suppose the blue square is 10 by 10 pixel, than ORG[0..9] contain the      ]
  22. [  value of the pixels on the first line, ORG[10..11] contain the value of    ]
  23. [  the pixels on the second line, and so on...                                ]
  24. So ORG is an array with the original values of the pixels. The copying-routine
  25. depends on the resolution (and the video mode) I'm working in.
  26.  
  27. I now want to transform the 'blue' picture, that is: I want to transform
  28. the array ORG. For each pixel, I'm gonna  determine its new value, and store it
  29. in DEST. To know what its new value is, I use the third array TFM. This array
  30. is a constant, and can therefore by calculated in advance. (You'll see how that
  31. is done for the lens in the second part of this text)
  32.  
  33. This array says for each pixel: the pixel at position i in the result, should
  34. be the same as the pixel at position TFM[i] in the original.
  35. [ So the formula is DEST[i] = ORG[TMF[i]] for all elements from 0 till NPI-1. ]
  36. The transformation is fast, and does not depend on the resolution/video-mode.
  37.  
  38. We now copy the array DEST to the blue rectangle on the image, and the
  39. transformation is complete.
  40.  
  41.  
  42. If the transformed region is to be connect to the position of the mouse,
  43. then every time the mouse is moved you have to:
  44. 1. Copy the original (array ORG) back to the old position,
  45. 2. Get the 'blue' region at the new position in the array ORG,
  46. 3. Do the transformation from ORG to DEST,
  47. 4. Copy the transformed region (DEST) onto the picture.
  48.  
  49.  
  50. [  Here are some simple transformations:                                      ]
  51. [  ( suppose the blue region has dimensions dX by dY, thus NPI = dX*dY )      ]
  52. [                                                                             ]
  53. [  for i:=0 to dX*dY-1 do                                                     ]
  54. [      TFM[i]:=i;                                                             ]
  55. [  Defines no change at all !                                                 ]
  56. [  (that is: the transformed picture is the same as the original)             ]
  57. [                                                                             ]
  58. [  for i:=0 to dX*dY-1 do                                                     ]
  59. [      TMF[i]:=(dX*dY-1) -i;                                                  ]
  60. [  This flips the original round both axis (X and Y)                          ]
  61. [                                                                             ]
  62. [  for i:=0 to dY-1 do                                                        ]
  63. [      for j:=0 to dX-1 do                                                    ]
  64. [          TFM[i*dX+j] := i*dX + dX-1 - j;                                    ]
  65. [  This flips the original round the X-axis only                              ]
  66. [                                                                             ]
  67. [  const M=2;                                                                 ]
  68. [  for i:=0 to dY-1 do                                                        ]
  69. [      for j:=0 to dX-1 do                                                    ]
  70. [          TFM[i*dX+j] := (i div M)*dX + (j div M);                           ]
  71. [  This magnifies the upper left corner by a factor of M                      ]
  72.  
  73. [  Mind you:                                                                  ]
  74. [  if you do the copying directly on the screen, you'll get some flickering.  ]
  75. [  One way to avoid that is using a virtual screen.                           ]
  76. [  That means you use an array, say VirtScr, wich represents the real screen. ]
  77. [  You then perform all action where the screen is involed (loading the image,]
  78. [  getting ORG and writing DEST) on the VirtScr, and than copy that VirtScr   ]
  79. [  on the real screen. However, that has 2 disadvantages:                     ]
  80. [  1. You'll use more memory (for the VirtScr)                                ]
  81. [  2. The result will be slower (because you have to copy the VirtScr to the  ]
  82. [     real screen)                                                            ]
  83.  
  84.  
  85. How to make the lens transformation
  86. -----------------------------------
  87.  
  88. Okay. So now the question is how to make the transformation array for the lens.
  89. Consider a sphere S, intersecting with a plane α. This defines a circle C in
  90. the plane. Define Rc as the ray of the circle C, Rs as the ray of the sphere S,
  91. and d as the distance from the centre of the sphere to the plane α.
  92. We know then that: 
  93.                              Rc² + d² = Rs²           (1)
  94.  
  95. If you want several lenses with the same radius, but different lens-strength,
  96. then you must preserve the same value for Rc. If the size of the transformed
  97. area is L by L pixels (the lens is circular, so the involved area is a square)
  98. then Rc should be ½L. The distance d determines the strength of the lens.
  99. So, knowing Rc and d, we can determine Rs.
  100.  
  101. Suppose we're given L (so Rc = ½L), we made a choice for d, and we calculated
  102. the value of Rs. We now want to transform each pixel in the square (LxL).
  103. We simply check all pixels [2 loops: one for the X-axis and one for the Y-axis]
  104. We call the point we're transforming p. If p lies outside or on C, then the
  105. point isn't transformed. That is: TFM(p)=p; if (x,y) are the coordinates of
  106. p than TFM[x+y*L] := x+y*L.
  107.  
  108. If p lies within the C, then the point will be transformed:
  109. the effect should be as if all points within the circle were projected from
  110. the centre of the sphere onto the sphere. Hence, for a given point p,
  111. we determine the point q (see picture). That point q is the projection of some
  112. point i within the circle C, so from the point q, we draw a line to the centre
  113. of the sphere, thus defining the point i, which is the intersection of that
  114. line whith the plane. That is the transformation of the point p: TFM(p)=i,
  115. because: if the point i was to be projected on the sphere, it would end up at
  116. the point q. Since we're looking straight onto the plane, the points q and p
  117. are the same. (that is: they end up at the same point on your screen).
  118.  
  119.  
  120.  
  121. When implementing, you can use some shortcuts:
  122. Lets say L and d are given. Then Rc=½L;
  123. Consider the origin of a rectangular system in the centre of the circle C.
  124. The X-axis and the Y-axis are parrallel to the plane α, in such a way that
  125. the square that is to be transformed, is defined as:
  126.  
  127.                    [-Rc,Rc] x [-Rc,Rc]
  128.  
  129. The orientation of the Z-axis is such that the coordinates of the centre of the
  130. sphere are (0,0,-d). The sphere is given by:
  131.  
  132.                  x² + y² + (z+d)² = Rs²                   (2)
  133.  
  134. hence:  [ (1) ]
  135.  
  136.                  x² + y² + (z+d)² = Rc² + d²              (3)
  137.  
  138. Consider the point P within the circle C. Thus, its coordinates are:
  139.  
  140.            (Px,Py,0)     and       Px² + Py² < Rc²        (4)
  141.  
  142.  
  143. The coordinates of the point Q can be found through this system:
  144.  
  145.         |   x = Px            ┬- defines the line, parrallel to the Z-axis
  146.         |   y = Py            ┘  through the point P.
  147.         |   x² + y² + (z+d)² = Rc² + d²
  148.  
  149. We immediatly find Qx and Qy (Qx=Px; Qy=Py), and for Qz we find:
  150.  
  151.         Px² + Py² + Qz² + 2*d*Qz + d² = Rc² + d²
  152.  
  153.         Qz² + 2*d*Qz - Rc² + Px² + Py² = 0
  154.  
  155.         D = d² -  (Px² + Py² - Rc²)                       (5)
  156.  
  157.         since  Rc² > Px² + Py²    [ (4) ],  we find D>0, and
  158.  
  159.         Qz = 1 ± √D.
  160.  
  161. We find 2 solutions (the line intersects the sphere twice !), but consider
  162. only the one with Qz>0. We find coordinates for Q:
  163.  
  164.         (Qx,Qy,Qz) ≡ (Px,Py,1+√D)    <see (5) for D>      (6)
  165.  
  166. Finally, we find the coordinates of the point I through :
  167. [ (Sx,Sy,Sz) are the coordinates of the centre of the sphere ]
  168. [ (Sx,Sy,Sz) ≡ (0,0,-d)                                      ]
  169.  
  170.          |      ( z - Sz)  
  171.          |  x = --------- * (Qx-Sx) + Sx        ┐
  172.          |      (Qz - Sz)                       ├ defines the line through
  173.          |                                      │ the centre of the sphere
  174.          |      ( z - Sz)                       │ and the point Q
  175.          |  y = --------- * (Qy-Sy) + Sy        ┘
  176.          |      (Qz - Sz)
  177.          |
  178.          |  z = 0                               -- defines the plane α
  179.  
  180. We find:
  181.  
  182.                   ( 0 - (-d) )
  183.            Ix  =  ------------ * (Qx-0) + 0
  184.                   ( Qz - (-d))
  185.  
  186.                   ( 0 - (-d) )
  187.            Iy  =  ------------ * (Qy-0) + 0
  188.                   ( Qz - (-d))
  189.  
  190.            Iz  =  0
  191.  
  192.  
  193. hence:                d
  194.            Ix  =  --------- Qx
  195.                    Qz + d
  196.  
  197.                       d
  198.            Iy  =  --------- Qy
  199.                    Qz + d
  200.  
  201.            Iz  =  0
  202.  
  203.  
  204. We know the coordinates of Q   (they can be fully determined if the coordinates
  205. of P are known), and we know d, so I can be calculated.
  206. We could than say:
  207.  
  208.     TFM[ (½L+Px) + (½L+Py) * L ] := (½L+Ix) + (½L+Iy) * L;
  209.  
  210. ( Remember:  Px,Py,Ix and Iy all are  ε [-Rc,Rc] and  Rc ≡ ½L )
  211.  
  212. Now, you can see (by just observing the drawing, or by checking the formulas)
  213. that if we find
  214.  
  215.      TFM[ p( Px, Py) ] = i( Ix, Iy)
  216.  
  217. then also
  218.  
  219.      TFM[ p( Px,-Py) ] = i( Ix,-Iy)
  220.      TFM[ p(-Px, Py) ] = i(-Ix, Iy)
  221.      TFM[ p(-Px,-Py) ] = i(-Ix,-Iy)
  222.  
  223. so that the entire transformation can be defined be calculating ¼ of the
  224. transformed area.
  225.  
  226.  
  227.  
  228. That's about it. I ain't too good in explaining, I know, so if things
  229. still aren't entirely clear to you, don't hesitate to ask me: I'll try
  230. to rephrase.
  231.  
  232. [ you can contact me through                                                  ]
  233. [                                                                             ]
  234. [  Internet     :        Joey@toeg.rug.ac.be                                  ]
  235. [                                                                             ]
  236. [  Buster BBS   :        write to our PR:       RETARD ED                     ]
  237. [  (+32-53-77.23.85)     or myself              JOEY                          ]
  238. [                                                                             ]
  239. [  Mail         :        Joey                                                 ]
  240. [                        Ottogracht 46                                        ]
  241. [                        B-9000 Gent                                          ]
  242. [                        (Belgium)                                            ]
  243.  
  244. Joey/SD