graphic/GRAPHIK.Transform

Raw file
Back to index

PACKET transformation DEFINES transform,      (* Autor: Heiko Indenbirken*)
                              diagonal,       (* Stand: 12.04.85         *)
                              height, width,  (*Änderung: 05.08.86/13:14 *)
                              set values,     (*Änderung: 17.09.86/19:57 *)
                              get values,
                              new values,
                              projektion,
                              window,
                              viewport,
                              view,
                              oblique,
                              orthographic,
                              perspective:
(* *******************  Hardwareunabhängiger Teil  ********************* *)
(*     transform:   Die Prozedur projeziert einen 3-dimensionalen Vektor *)
(*     ----------   (x, y, z) auf einen 2-dimensionalen (h, v)           *)
(*     diagonal     Die Prozedur berechnet die Pixel als Prozent der     *)
(*     ----------   Diagonalen der Zeichenfläche                         *)
(*     height       Die Prozedur berechnet die Pixel als Prozent der     *)
(*     ----------   Höhe der Zeichenfläche                               *)
(*     width        Die Prozedur berechnet die Pixel als Prozent der     *)
(*     ----------   Breite der Zeichenfläche                             *)
(*                                                                       *)
(*     set values:  Mit dieser Prozedur werden die Projektionsparameter  *)
(*     -----------  gesetzt.                                             *)
(*                  size:          Weltkoordinatenbereich                *)
(*                           ((xmin,xmax),(ymin,ymax),(zmin,zmax))       *)
(*                  limits:  Zeichenfläche                               *)
(*                           ((h min, h max), (v min, v max))            *)
(*                           Bei Werten < 2.0 werden die Werte als       *)
(*                           Prozente interpretiert, ansonsten als       *)
(*                           cm-Grössen.                                 *)
(*     get values:  Übergibt die aktuellen Werte                         *)
(*     -----------                                                       *)
(*     new values:  Berechnet die neue Projektionsmatrix                 *)
(*     -----------                                                       *)
(*=======================================================================*)

BOOL VAR perspective projektion :: FALSE;
INT VAR hor pixel, vert pixel, i;
REAL VAR  hor cm, vert cm,
          h min limit, h max limit, v min limit, v max limit;
ROW 5 ROW 5 REAL VAR p;
ROW 3 ROW 2 REAL VAR size;
ROW 2 ROW 2 REAL VAR limits;
ROW 4 REAL VAR angles;
ROW 2 REAL VAR obliques;
ROW 3 REAL VAR perspectives;

(*                 Initialisieren der Projektionsmatrizen                *)
INT VAR d;
window (0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
viewport (0.0, 0.0, 0.0, 0.0);
view (0.0, 0.0, 1.0);
view (0.0);
orthographic;
new values  (27.46, 19.21, 274, 192, d, d, d, d);

PROC projektion (ROW 5 ROW 5 REAL VAR matrix):
  matrix := p
END PROC projektion;

PROC oblique (REAL CONST a, b) :
  set values (size, limits, angles, ROW 2 REAL : (a, b), ROW 3 REAL : (0.0, 0.0, 0.0)) 
END PROC oblique;

PROC orthographic :
  set values (size, limits, angles, ROW 2 REAL : (0.0, 0.0), ROW 3 REAL : (0.0, 0.0, 0.0))
END PROC orthographic;

PROC perspective (REAL CONST cx, cy, cz) :
  set values (size, limits, angles, ROW 2 REAL : (0.0, 0.0), ROW 3 REAL : (cx, cy, cz))
END PROC perspective;

PROC window (REAL CONST x min, x max, y min, y max) :
  window (x min, x max, y min, y max, 0.0, 1.0)
END PROC window;

PROC window (REAL CONST x min, x max, y min, y max, z min, z max) :
  set values (ROW 3 ROW 2 REAL : (ROW 2 REAL : (x min, x max),
                                  ROW 2 REAL : (y min, y max),
                                  ROW 2 REAL : (z min, z max)),
              limits, angles, obliques, perspectives)
END PROC window;

PROC viewport (REAL CONST h min, h max, v min, v max) :
  set values (size, ROW 2 ROW 2 REAL : (ROW 2 REAL : (h min, h max), 
                                        ROW 2 REAL : (v min, v max)),
              angles, obliques, perspectives)
END PROC view port;

PROC view (REAL CONST alpha) :
  set values (size, limits, ROW 4 REAL : (alpha, angles(2), angles (3), angles (4)),
              obliques, perspectives)
END PROC view;

PROC view (REAL CONST phi, theta):
  set values (size, limits, ROW 4 REAL : (angles (1), sind (theta) * cosd (phi),
                                          sind (theta) * sind (phi), cosd (theta)),
              obliques, perspectives)
END PROC view;

PROC view (REAL CONST x, y, z) :
  set values (size, limits, ROW 4 REAL : (angles (1), x, y, z), obliques, perspectives)
END PROC view;

PROC get values (ROW 3 ROW 2 REAL VAR act size, 
                 ROW 2 ROW 2 REAL VAR act limits,
                 ROW 4 REAL VAR act angles,
                 ROW 2 REAL VAR act obliques,
                 ROW 3 REAL VAR act perspectives) : 
  act size        := size;
  act limits      := limits;
  act angles      := angles;
  act obliques     := obliques;
  act perspectives := perspectives;

END PROC get values;

PROC set values (ROW 3 ROW 2 REAL CONST new size, 
                 ROW 2 ROW 2 REAL CONST new limits,
                 ROW 4 REAL CONST new angles,
                 ROW 2 REAL CONST new obliques,
                 ROW 3 REAL CONST new perspectives) : 
  size        := new size;
  limits      := new limits;
  angles      := new angles;
  obliques     := new obliques;
  perspectives := new perspectives

END PROC set values;

PROC new values (INT VAR h min range, h max range, v min range, v max range):
  new values (hor cm, vert cm, hor pixel, vert pixel, 
              h min range, h max range, v min range, v max range)
END PROC new values;

PROC new values (REAL CONST size hor, size vert,
                 INT CONST pixel hor, pixel vert,
                 INT VAR h min range, h max range,
                         v min range, v max range):
   remember screensize;
   calc views;
   calc projektion; 
   calc limits;
   calc projection frame;
   normalize projektion;
   set picture range;
   set perspective mark  .

remember screensize:
  hor cm     := size hor;
  vert cm    := size vert;
  hor pixel  := pixel hor;
  vert pixel := pixel vert  .

calc views :
  calc diagonale;
  calc projektion;
  calc angles;
  calc normale;
  calc matrix;
  calc alpha angle  .

calc diagonale:
  REAL VAR diagonale := sqrt (angles [2] * angles [2] +
                              angles [3] * angles [3] +
                              angles [4] * angles [4])  .

calc projektion:
  REAL VAR projektion := sqrt (angles [2] * angles [2] +
                               angles [4] * angles [4])  .

calc angles:
  REAL VAR sin p, cos p, sin t, cos t, sin a, cos a;

  IF diagonale = 0.0
  THEN sin p :=  0.0;  cos p :=  1.0;
       sin t :=  0.0;  cos t :=  1.0
  ELIF projektion = 0.0
  THEN sin p :=  angles [3] / diagonale;
       cos p :=  projektion / diagonale;
       sin t :=  0.0;  cos t :=  1.0
  ELSE sin p :=  angles [3] / diagonale;
       cos p :=  projektion / diagonale;
       sin t :=  angles [2] / projektion;
       cos t :=  angles [4] / projektion
  FI  .

calc normale:
  REAL VAR   sin p sin t := sin p * sin t,
             sin p cos t := sin p * cos t,
             cos p sin t := cos p * sin t,
             cos p cos t := cos p * cos t,

             dx          := size [1][2] - size [1][1],
             dy          := size [2][2] - size [2][1],
             dz          := size [3][2] - size [3][1],
             norm az     := obliques [1] ,
             norm bz     := obliques [2] ,
             norm cx     := perspectives [1] / dx,
             norm cy     := perspectives [2] / dy,
             norm cz     := perspectives [3] / dz  .

calc matrix:
p :=  ROW 5 ROW 5 REAL :
      (ROW 5 REAL : (  cos t       / dx - cos p sin t / dx * norm az ,
                     - sin p sin t / dx - cos p sin t / dx * norm bz,
                       0.0,
                                        - cos p sin t / dx * norm cz,
                       0.0 ),
       ROW 5 REAL : (                   - sin p       / dy * norm az,
                       cos p       / dy - sin p       / dy * norm bz,
                       0.0, 
                                        - sin p       / dy * norm cz,
                       0.0 ),
       ROW 5 REAL : (  sin t       / dz + cos p cos t / dz * norm az,
                     + sin p cos t / dz + cos p cos t / dz * norm bz,
                       0.0,
                                        cos p cos t / dz * norm cz,
                       0.0 ),
       ROW 5 REAL : (- norm cx, - norm cy, 0.0, 1.0, 0.0 ),
       ROW 5 REAL : (0.0, 0.0, 0.0, 0.0, 1.0))  .

calc alpha angle:
  IF angles (1) = 0.0
  THEN set alpha as y vertical
  ELSE sin a := sind (angles (1));
       cos a := cosd (angles (1))
  FI  .
 
set alpha as y vertical :
  REAL VAR r := sqrt (p(2)(1)**2 + p(2)(2)**2);
  IF r = 0.0
  THEN sin a := 0.0;
       cos a := 1.0
  ELSE sin a :=-p(2)(1)/r;
       cos a := p(2)(2)/r
  FI  .

calc limits :
  IF limits as percent
  THEN calc percent limits
  ELSE calc centimeter limits FI  .

limits as percent:
  limits [1][2] < 2.0 AND limits [2][2] < 2.0  .

max limits:
  h min limit := 0.0;

  v min limit := 0.0;
  v max limit := real (pixel vert)  .

calc percent limits:
  h min limit := real (pixel hor) * limits (1)(1)*size vert / size hor;
  v min limit := limits (2)(1) * real (pixel vert);

  IF limits [1][2] = 0.0
  THEN h max limit := real (pixel hor)
  ELSE h max limit := real (pixel hor) * limits [1][2]*size vert / size hor FI;

  IF limits [2][2] = 0.0
  THEN v max limit := real (pixel vert)
  ELSE v max limit := limits (2)(2) * real (pixel vert)  FI  .

calc centimeter limits:
  h min limit := real (pixel hor) * (limits (1)(1)/size hor);
  v min limit := real (pixel vert) * (limits (2)(1)/size vert);

  IF limits [1][2] = 0.0
  THEN h max limit := real (pixel hor)
  ELSE h max limit := real (pixel hor) * (limits (1)(2)/size hor) FI;
 
  IF limits [2][2] = 0.0
  THEN v max limit := real (pixel vert)
  ELSE v max limit := real (pixel vert) * (limits (2)(2)/size vert) FI  .

calc projection frame:
  REAL VAR h min := max real,  h max :=-max real,
           v min := max real,  v max :=-max real;
 
  extrema (size [1][1], size [2][1], size [3][1], h min, h max, v min, v max); 
  extrema (size [1][2], size [2][1], size [3][1], h min, h max, v min, v max);
  extrema (size [1][2], size [2][2], size [3][1], h min, h max, v min, v max); 
  extrema (size [1][1], size [2][2], size [3][1], h min, h max, v min, v max);
  extrema (size [1][1], size [2][1], size [3][2], h min, h max, v min, v max); 
  extrema (size [1][2], size [2][1], size [3][2], h min, h max, v min, v max);
  extrema (size [1][2], size [2][2], size [3][2], h min, h max, v min, v max); 
  extrema (size [1][1], size [2][2], size [3][2], h min, h max, v min, v max)  .

normalize projektion :
  REAL VAR sh := (h max limit - h min limit) / (h max - h min),
           sv := (v max limit - v min limit) / (v max - v min),
           dh := h min limit - h min*sh,
           dv := v min limit - v min*sv;

  FOR i FROM 1 UPTO 5
  REP REAL CONST p  i 1 := p (i)(1);
      p (i)(1) :=  (p  i  1  * cos a - p (i)(2) * sin a) * sh;
      p (i)(2) :=  (p  i  1  * sin a + p (i)(2) * cos a) * sv
  PER;
  p (5)(1) := dh;
  p (5)(2) := dv  .

set picture range:
  h min range := int (h min limit-0.5);
  h max range := int (h max limit+0.5);
  v min range := int (v min limit-0.5);
  v max range := int (v max limit+0.5)  .

set perspective mark:
  perspective projektion := perspectives [3] <> 0.0  .

END PROC new values;
 
PROC transform (REAL CONST x, y, z, INT VAR h, v) :
  IF perspective projektion
  THEN REAL CONST w :: 1.0/(x*p (1)(4) + y*p (2)(4) + z*p (3)(4) + 1.0);
       h := int ((x*p (1)(1)+y*p (2)(1)+z*p (3)(1) + p (4)(1))*w + p (5)(1));
       v := int ((x*p (1)(2)+y*p (2)(2)+z*p (3)(2) + p (4)(2))*w + p (5)(2))
  ELSE h := int (x*p (1)(1)+y*p (2)(1)+z*p (3)(1) + p (5)(1));
       v := int (x*p (1)(2)+y*p (2)(2)+z*p (3)(2) + p (5)(2));
  FI;
END PROC transform;

PROC extrema (REAL CONST x, y, z, REAL VAR h min, h max, v min, v max):
  REAL VAR h, v;
  IF perspective projektion
  THEN REAL CONST w :: 1.0/(x*p (1)(4) + y*p (2)(4) + z*p (3)(4) + 1.0);
       h := (x*p (1)(1)+y*p (2)(1)+z*p (3)(1) +p (4)(1))*w;
       v := (x*p (1)(2)+y*p (2)(2)+z*p (3)(2) +p (4)(2))*w
  ELSE h := (x*p (1)(1)+y*p (2)(1)+z*p (3)(1));
       v := (x*p (1)(2)+y*p (2)(2)+z*p (3)(2))
  FI;
 
 IF h < h min
 THEN h min := h
 ELIF h > h max
 THEN h max := h FI;

 IF v < v min
 THEN v min := v
 ELIF v > v max
 THEN v max := v FI

END PROC extrema;

INT PROC diagonal (REAL CONST percent):
  int (percent * 0.01 * diagonale + 0.5)  .

diagonale:
  sqrt ((h max limit-h min limit) ** 2 + (v max limit-v min limit) ** 2) .

END PROC diagonal;

INT PROC height (REAL CONST percent):
  int (percent * 0.01 * (v max limit-v min limit) + 0.5)
END PROC height;

INT PROC width (REAL CONST percent):
  int (percent * 0.01 * (h max limit-h min limit) + 0.5)
END PROC width;

END PACKET transformation