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