home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
progjorn
/
pj_7_5.arc
/
GRAPHWLD.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1989-06-08
|
7KB
|
256 lines
{GraphWld.tpu Copyright (C) 1989 by Gene Fowler
GraphWld.tpu extends Graph.tpu to handle world co-
ordinates by providing parallel drawing procedures
that translate world to viewpoint coordinates and
call the original procedures from Graph. There are
also two standalone translators (one for x,y co-
ordinates and one for dx,dy relative coordinates
or distances) when one translation yields variables
for repeated calls or a parallel procedure would
have to relay extra params.
The "central" procedure is CreateWorld(ULx,ULr,LRx,
LRy). The params define your world. This procedure
is called AFTER any defining of a viewport in which
the world will exist and BEFORE any use of the
translating procedures.
}
unit GraphWld; {world coordinates ext. to Graph.tpu}
interface
uses crt, graph;
procedure CreateWorld(ULx, ULy, LRx, LRy : real);
procedure w2vp(Var wx, wy : real; var vpx, vpy : integer);
procedure w2vpRel(Var wdx, wdy : real; var vpdx, vpdy : integer);
procedure w2vpRadius(var wRadius : real; var vpRadius : word; wAspRatio : real);
procedure WPutPixel(wx, wy : real);
function WGetPixel(wx, wy : real) : word;
procedure WLine(wx1, wy1, wx2, wy2 : real);
procedure WRectangle(wx1, wy1, wx2, wy2 : real);
procedure WLineTo(wx, wy : real);
procedure WMoveTo(wx, wy : real);
procedure WLineRel(wdx, wdy : real);
procedure WMoveRel(wdx, wdy : real);
implementation
var
xv,yv, x1v,y1v,x2v,y2v : integer;
MaxColor : word;
RatioX, RatioY : real;
VPMaxX, VPMaxY : integer;
ViewP : ViewPortType;
WXTotal, WXNegAdj, WYTotal, WYNegAdj,
FTemp : real;
FlipYFlag : boolean;
ivpdx, ivpdy : real;
xAsp, yAsp : word;
vpAspRatio : real;
procedure CreateWorld{(ULx, ULy, LRx, LRy : real)};
begin
GetViewSettings(ViewP); {Viewport must be set before world}
with ViewP do
begin
VPMaxX := x2-x1;
VPMaxY := y2-y1;
end;
if ULy > LRy then { for Cartesian flip; corresponding vpy adjust. in
the procedures. }
begin
FlipYFlag := true;
FTemp := ULy;
ULy := LRy;
LRy := FTemp;
end
else FlipYFlag := false;
WXTotal := LRx - ULx + 1;
if ULx < 0 then WXNegAdj := Abs(ULx) else WXNegAdj := 0;
WYTotal := abs(LRy - ULy) + 1;
if ULy < 0 then WYNegAdj := Abs(ULy) else WYNegAdj := 0;
end;
procedure w2vp{(Var wx, wy : real; var vpx, vpy : integer)};
begin
RatioX := (VPMaxX + 1) / WXTotal; RatioY := (VPMaxY + 1) / WYTotal;
wx := wx + WXNegAdj;
wy := wy + WYNegAdj;
vpx := round(wx * RatioX); vpy := round(wy * RatioY);
if FlipYFlag then vpy := VPMaxY - vpy;
end;
procedure w2vpRel{(Var wdx, wdy : real; var vpdx, vpdy : integer)};
var
NFlagX : boolean;
NFlagY : boolean;
begin
RatioX := (VPMaxX + 1) / WXTotal; RatioY := (VPMaxY + 1) / WYTotal;
if wdx < 0 then NFlagX := True else NFlagX := False;
if not FlipYFlag then
if wdy < 0 then NFlagY := True else NFlagY := False
else
if wdy < 0 then NFlagY := False else NFlagY := True;
wdx := abs(wdx); wdy := abs(wdy);
vpdx := round(wdx * RatioX); vpdy := round(wdy * RatioY);
if NFlagX then vpdx := -vpdx;
if NFlagY then vpdy := -vpdy;
end;
procedure w2vpRadius{(var wRadius : real; var vpRadius : word; wAspRatio : real)};
var
wdx, wdy : real;
begin
RatioX := (VPMaxX + 1) / WXTotal; RatioY := (VPMaxY + 1) / WYTotal;
wdx := sqrt(sqr(wRadius) / (1 + (sqr(wAspRatio))));
wdy := wAspRatio * wdx;
ivpdx := (wdx * RatioX);
GetAspectRatio(xAsp, yAsp);
vpAspRatio := xAsp / yAsp;
ivpdy := (wdy * RatioY) * (wAspRatio / vpAspRatio);
vpRadius := round(sqrt(sqr(ivpdx) + sqr(ivpdy)));
end;
procedure WPutPixel{(wx, wy : real)};
begin
wx := wx + WXNegAdj;
wy := wy + WYNegAdj;
RatioX := (VPMaxX + 1) / WXTotal; RatioY := (VPMaxY + 1) / WYTotal;
xv := round(wx * RatioX); yv := round(wy * RatioY);
if FlipYFlag then yv := VPMaxY - yv;
MaxColor := GetMaxColor;
PutPixel(xv, yv, MaxColor);
end;
function WGetPixel{(wx, wy : real) : word};
begin
wx := wx + WXNegAdj;
wy := wy + WYNegAdj;
RatioX := (VPMaxX + 1) / WXTotal; RatioY := (VPMaxY + 1) / WYTotal;
xv := round(wx * RatioX); yv := round(wy * RatioY);
if FlipYFlag then yv := VPMaxY - yv;
WGetPixel := GetPixel(xv, yv);
end;
procedure WLine{(wx1, wy1, wx2, wy2 : real)};
begin
RatioX := (VPMaxX + 1) / WXTotal; RatioY := (VPMaxY + 1) / WYTotal;
wx1 := wx1 + WXNegAdj;
wy1 := wy1 + WYNegAdj;
wx2 := wx2 + WXNegAdj;
wy2 := wy2 + WYNegAdj;
x1v := round(wx1 * RatioX); y1v := round(wy1 * RatioY);
x2v := round(wx2 * RatioX); y2v := round(wy2 * RatioY);
if FlipYFlag then
begin
y1v := VPMaxY - y1v;
y2v := VPMaxY - y2v;
end;
Line(x1v,y1v,x2v,y2v);
end; {WLine}
procedure WRectangle{(wx1, wy1, wx2, wy2 : real)};
begin
RatioX := (VPMaxX + 1) / WXTotal; RatioY := (VPMaxY + 1) / WYTotal;
wx1 := wx1 + WXNegAdj;
wy1 := wy1 + WYNegAdj;
wx2 := wx2 + WXNegAdj;
wy2 := wy2 + WYNegAdj;
x1v := round(wx1 * RatioX); y1v := round(wy1 * RatioY);
x2v := round(wx2 * RatioX); y2v := round(wy2 * RatioY);
if FlipYFlag then
begin
y1v := VPMaxY - y1v;
y2v := VPMaxY - y2v;
end;
Rectangle(x1v,y1v,x2v,y2v);
end; {WRectangle}
procedure WLineTo{(wx, wy : real)};
begin
RatioX := (VPMaxX + 1) / WXTotal; RatioY := (VPMaxY + 1) / WYTotal;
wx := wx + WXNegAdj;
wy := wy + WYNegAdj;
xv := round(wx * RatioX); yv := round(wy * RatioY);
if FlipYFlag then yv := VPMaxY - yv;
LineTo(xv,yv);
end; {WLineTo}
procedure WMoveTo{(wx, wy : real)};
begin
RatioX := (VPMaxX + 1) / WXTotal; RatioY := (VPMaxY + 1) / WYTotal;
wx := wx + WXNegAdj;
wy := wy + WYNegAdj;
xv := round(wx * RatioX); yv := round(wy * RatioY);
if FlipYFlag then yv := VPMaxY - yv;
MoveTo(xv,yv);
end; {WMoveTo}
procedure WLineRel{(wdx, wdy : real)};
var
NFlagX : boolean;
NFlagY : boolean;
begin
RatioX := (VPMaxX + 1) / WXTotal; RatioY := (VPMaxY + 1) / WYTotal;
if wdx < 0 then NFlagX := True else NFlagX := False;
if not FlipYFlag then
if wdy < 0 then NFlagY := True else NFlagY := False
else
if wdy < 0 then NFlagY := False else NFlagY := True;
wdx := abs(wdx); wdy := abs(wdy);
xv := round(wdx * RatioX); yv := round(wdy * RatioY);
if NFlagX then xv := -xv;
if NFlagY then yv := -yv;
LineRel(xv,yv);
end; {WLineRel}
procedure WMoveRel{(wdx, wdy : real)};
var
NFlagX : boolean;
NFlagY : boolean;
begin
RatioX := (VPMaxX + 1) / WXTotal; RatioY := (VPMaxY + 1) / WYTotal;
if wdx < 0 then NFlagX := True else NFlagX := False;
if not FlipYFlag then
if wdy < 0 then NFlagY := True else NFlagY := False
else
if wdy < 0 then NFlagY := False else NFlagY := True;
wdx := abs(wdx); wdy := abs(wdy);
xv := round(wdx * RatioX); yv := round(wdy * RatioY);
if NFlagX then xv := -xv;
if NFlagY then yv := -yv;
MoveRel(xv,yv);
end; {WMoveRel}
end.