home *** CD-ROM | disk | FTP | other *** search
- (*-------------------------------------------------------------*)
- (* CPLINE3D.PAS *)
- (* Clipping einer dreidimensionale Linie im Blickvolumem. *)
-
- PROCEDURE Clip3DLine(VAR P1, P2 : tVektor; MinDist : REAL;
- VAR Zeichnen : BOOLEAN (* Linie zeichnen ? *) );
-
- LABEL 9999;
-
- TYPE direction = SET OF (left,right,top,bottom,front,back);
-
- VAR P : tVektor;
- VAR t : REAL; (* Faktor fuer Liniensegment *)
- dir, dir1, dir2 : direction;
-
- PROCEDURE Region(P : tVektor;
- VAR Endpunkt : direction);
- BEGIN
- Endpunkt := [];
- IF P[1] < -P[3] THEN Endpunkt := [left]
- ELSE IF P[1] > P[3] THEN Endpunkt := [right];
- IF P[2] < -P[3] THEN Endpunkt := Endpunkt + [bottom]
- ELSE IF P[2] > P[3] THEN Endpunkt := Endpunkt + [top];
- IF P[3] < MinDist THEN Endpunkt := Endpunkt + [front]
- ELSE IF P[3] > 1 THEN Endpunkt := Endpunkt + [back];
- END; (* Region *)
-
- PROCEDURE NewPoint(VAR P : tVektor);
- BEGIN
- P[1] := (P2[1] - P1[1])*t + P1[1];
- P[2] := (P2[2] - P1[2])*t + P1[2];
- P[3] := (P2[3] - P1[3])*t + P1[3];
- END;
-
- PROCEDURE clip_left(VAR P : tVektor); (* Links abschneiden *)
- BEGIN
- t := -(P1[3] - P1[1]) / ((P2[1] - P1[1]) - (P2[3] - P1[3]));
- NewPoint(P);
- END;
-
- PROCEDURE clip_right(VAR P : tVektor); (* Rechts abschneiden *)
- BEGIN
- t := (P1[3] - P1[1]) / ((P2[1] - P1[1]) - (P2[3] - P1[3]));
- NewPoint(P);
- END;
-
- PROCEDURE clip_top(VAR P : tVektor); (* Oben abschneiden *)
- BEGIN
- t := (P1[3] - P1[2]) / ((P2[2] - P1[2]) - (P2[3] - P1[3]));
- NewPoint(P);
- END;
-
- PROCEDURE clip_bottom(VAR P : tVektor); (* Unten abschneiden *)
- BEGIN
- t := -(P1[3] - P1[2]) / ((P2[2] - P1[2]) - (P2[3] - P1[3]));
- NewPoint(P);
- END;
-
- PROCEDURE clip_front(VAR P : tVektor); (* Vorne abschneiden *)
- BEGIN
- t := (MinDist - P1[3]) / (P2[3] - P1[3]);
- NewPoint(P);
- END;
-
- PROCEDURE clip_back(VAR P : tVektor); (* Hinten abschneiden *)
- BEGIN
- t := (1 - P1[3]) / (P2[3] - P1[3]);
- NewPoint(P);
- END;
-
- BEGIN (* Line-Draw mit Clipping *)
- Zeichnen := TRUE;
- Region(P1,dir1); (* Endpunkts-Bereich bestimmen *)
- Region(P2,dir2);
- WHILE (dir1 <> []) OR (dir2 <> []) DO BEGIN
- IF dir1*dir2 <> [] THEN BEGIN (* Linie ausserhalb Volumen *)
- Zeichnen := FALSE;
- GOTO 9999; (* ---> Ausgang *)
- END;
- IF dir1 = [] THEN BEGIN (* P1 innerhalb Volumen, P2 clippen *)
- dir := dir2; P := P2;
- END
- ELSE BEGIN
- dir := dir1; P := P1; (* P1 clippen *)
- END;
- IF left IN dir THEN clip_left(P)
- ELSE IF right IN dir THEN clip_right(P)
- ELSE IF bottom IN dir THEN clip_bottom(P)
- ELSE IF top IN dir THEN clip_top(P)
- ELSE IF front IN dir THEN clip_front(P)
- ELSE IF back IN dir THEN clip_back(P);
- IF dir = dir1 THEN BEGIN
- P1 := P; Region(P1,dir1)
- END
- ELSE BEGIN
- P2 := P; Region(P2,dir2)
- END
- END;
- 9999:; (* Ausgangslabel *)
- END;
- (*-------------------------------------------------------------*)
- (* Ende CLIPLINE.PAS *)
-