home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.ncsa.uiuc.edu
/
ftp.ncsa.uiuc.edu.zip
/
ftp.ncsa.uiuc.edu
/
Contour
/
routines.p
< prev
next >
Wrap
Text File
|
2017-03-03
|
19KB
|
586 lines
{$U-}
{$R-}
unit Routines(30);
interface
uses
MemTypes, Quickdraw, OSIntf, ToolIntf,MacPrint,FixMath,Graf3D,
Globals, Utilities;
procedure InitTables;
procedure contourPlot(UpdateRect:rect);
procedure CalculateLevels;
procedure DrawGrid(xlow,xhigh,ylow,yhigh : integer);
implementation
const
minY = 0;
minX = 0;
var
divisor : integer;
function cancelOp : boolean;
var
myEvent : EventRecord;
begin
if GetNextEvent(everyEvent,myEvent) then
cancelOp := (myEvent.what = keyDown) and
(BitAnd(myEvent.message, charCodeMask) = 46) and
(BitAnd(myEvent.modifiers,cmdKey) <> 0 )
else
cancelOp := false;
end;
procedure CalculateLevels;
var
i : integer;
begin
for i := 1 to NoOfLevels[windowIndex] do
ContourLevel[windowIndex][i] := minData[windowIndex] +
(maxData[windowIndex]-minData[windowIndex])
div NoOfLevels[windowIndex] * i;
end;
procedure InitTables;
var
y : integer;
begin
setPort(ContourWindow[windowIndex]);
CalculateLevels;
end; {InitTables}
procedure SwapPtr(var x,y : ArrayPtr);
var
temptr : ArrayPtr;
begin
temptr := y;
y := x;
x := temptr;
end;
procedure DrawGrid;{xlow,xhigh,ylow,yhigh : integer}
var
x,y : integer;
begin
y := ylow+1;
while y < yhigh do begin
MoveTo(Xlow*currentGridSize,y*currentGridSize);
LineTo(Xhigh*currentGridSize,y*currentGridSize);
y := y + 5;
end;
x := xlow+1;
while x < xhigh do begin
MoveTo(x*currentGridSize,Ylow*currentGridSize);
LineTo(x*currentGridSize,Yhigh*currentGridSize);
x := x + 5;
end;
end;
procedure contourPlot;
var
x,y,
level,
segment : integer;
Xlow,Xhigh,
Ylow,Yhigh : integer;
NoOfSegments : integer;
remainingRows : integer;
DataMin,DataMax : integer;
RealY : longint;
NoOfRows : integer;
d0,d1,d2,d3,
h0,h1,h2,h3 : longint;
posOff : longint;
jump : integer;
PState : PenState;
procedure minMaxVertex;
begin
d0 := ord(data[y]^[x]); d1 := ord(data[y]^[x+1]);
d2 := ord(data[y+1]^[x]); d3 := ord(data[y+1]^[x+1]);
DataMin := d0; DataMax := d0;
if (d1<DataMin) then DataMin := d1;
if (d2<DataMin) then DataMin := d2;
if (d3<DataMin) then DataMin := d3;
if (d1>DataMax) then DataMax := d1;
if (d2>DataMax) then DataMax := d2;
if (d3>DataMax) then DataMax := d3;
end;
procedure ProcessVertices;
begin
h0 := d0 - ContourLevel[windowIndex][level];
h1 := d1 - ContourLevel[windowIndex][level];
h2 := d2 - ContourLevel[windowIndex][level];
h3 := d3 - ContourLevel[windowIndex][level];
jump := 0;
if (h0 >= 0) then jump := 8;
if (h1 >= 0) then jump := jump + 4;
if (h2 >= 0) then jump := jump + 2;
if (h3 >= 0) then jump := jump + 1;
end; {ProcessVertices}
Procedure ProcessTriangles;
var
x1,x2,
y1,y2 : longint;
procedure vecout(x1,y1,x2,y2 : longint);
begin
MoveTo(x1,y1);
LineTo(x2,y2);
end;
begin
x1 := -1;
case jump of
1,14 :
if h3 <> 0 then begin
x1 := currentGridSize*(x+1);
y1 := currentGridSize*(h3*RealY - h1*(RealY+1)) div (h3-h1);
x2 := currentGridSize*(h3*x - h2*(x+1)) div(h3-h2);
y2 := currentGridSize*(RealY+1);
upHill^[x] := true;
end;
2,13 :
if h2 <> 0 then begin
x1 := currentGridSize*x;
y1 := currentGridSize*(h2*RealY - h0*(RealY+1)) div(h2-h0);
x2 := currentGridSize*(h3*x - h2*(x+1)) div(h3-h2);
y2 := currentGridSize*(RealY+1);
upHill^[x] := false;
end;
3,12 : begin
x1 := x*currentGridSize;
y1 := (h2*RealY - h0*(RealY+1))*currentGridSize div(h2-h0);
x2 := (x+1)*currentGridSize;
y2 := (h3*RealY - h1*(RealY+1))*currentGridSize div(h3-h1);
end;
4,11 :
if h1 <> 0 then begin
x1 := currentGridSize*(h1*x - h0*(x+1)) div(h1-h0);
y1 := currentGridSize*RealY;
x2 := currentGridSize*(x+1);
y2 := currentGridSize*(h3*RealY - h1*(RealY+1)) div(h3-h1);
end;
5,10 : begin
x1 := currentGridSize*(h1*x - h0*(x+1)) div(h1-h0);
y1 := currentGridSize*RealY;
x2 := currentGridSize*(h3*x - h2*(x+1)) div(h3-h2);
y2 := currentGridSize*(RealY+1);
upHill^[x] := x1 > x2;
end;
6,9 :
if upHill^[x] then begin
x1 := currentGridSize*(h1*x - h0*(x+1)) div(h1-h0);
y1 := currentGridSize*RealY;
x2 := currentGridSize*x;
y2 := currentGridSize*(h2*RealY - h0*(RealY+1)) div(h2-h0);
vecout(x1,y1,x2,y2);
x1 := currentGridSize*(x+1);
y1 := currentGridSize*(h3*RealY - h1*(RealY+1)) div(h3-h1);
x2 := currentGridSize*(h3*x - h2*(x+1)) div(h3-h2);
y2 := currentGridSize*(RealY+1);
upHill^[x] := true;
end
else begin
x1 := currentGridSize*(h1*x - h0*(x+1)) div(h1-h0);
y1 := currentGridSize*RealY;
x2 := currentGridSize*(x+1);
y2 := currentGridSize*(h3*RealY - h1*(RealY+1)) div(h3-h1);
vecout(x1,y1,x2,y2);
x1 := currentGridSize*x;
y1 := currentGridSize*(h2*RealY - h0*(RealY+1)) div(h2-h0);
x2 := currentGridSize*(h3*x - h2*(x+1)) div(h3-h2);
y2 := currentGridSize*(RealY+1);
upHill^[x] := false;
end;
7,8 :
if h0 <> 0 then begin
x1 := currentGridSize*(h1*x - h0*(x+1)) div(h1-h0);
y1 := currentGridSize*RealY;
x2 := currentGridSize*x;
y2 := currentGridSize*(h2*RealY - h0*(RealY+1)) div (h2-h0);
end;
otherwise;
end; {case}
if x1 <> -1 then
vecout(x1,y1,x2,y2);
end; {ProcessTriangles}
procedure InitShade;
const
numPatterns = 10;
UpperLeft = 1;
UpperRight = 2;
LowerLeft = 3;
LowerRight = 4;
NullBox = -1;
type
PatNum = -1..numPatterns;
var
divisor : longint;
PatList : array[1..numPatterns] of Pattern; { selected standard patterns }
pState : PenState;
myPat : PatNum;
myRect : rect;
function ShadeSquare(x,y, xSize,ySize,
ul,ll,lr,ur : integer) : PatNum;
var
centre,top,left,bottom,right : longint;
centrePat : longint;
leftWidth,rightWidth,
upperHeight,lowerHeight : integer;
recurse : boolean;
smallerBox : array [UpperLeft..LowerRight] of PatNum;
uniform : boolean;
i : integer;
drawingPat : PatNum;
procedure paintArea;
var
tempRect : rect;
begin
PenPat(PatList[smallerBox[i]]);
with tempRect do
case i of
UpperLeft : begin
left := x;
top := y;
right := x+leftWidth;
bottom := y+upperHeight;
end;
UpperRight : begin
left := x+leftWidth;
top := y;
right := x+leftWidth+rightWidth;
bottom := y+upperHeight;
end;
LowerLeft : begin
left := x;
top := y+upperHeight;
right := x+leftWidth;
bottom := y+upperHeight+lowerHeight;
end;
LowerRight : begin
left := x+leftWidth;
top := y+upperHeight;
right := x+leftWidth+rightWidth;
bottom := y+upperHeight+lowerHeight;
end;
end;
PaintRect(tempRect);
PenNormal;
end;
begin
centre := (ul+ll+lr+ur) div 4;
centrePat := centre div divisor;
{find out if recursion is needed}
recurse := ((xSize > 8) or (ySize > 8)) and
(((ul div divisor) <> centrePat) or
((ll div divisor) <> centrePat) or
((lr div divisor) <> centrePat) or
((ur div divisor) <> centrePat));
if not recurse then
shadeSquare := 1+centrePat
else begin
top := (ul+ur) div 2;
left := (ul+ll) div 2;
bottom := (ll+lr) div 2;
right := (lr+ur) div 2;
rightWidth := (xSize+1) div 2;
leftWidth := xSize div 2;
lowerHeight := (ySize+1) div 2;
upperHeight := ySize div 2;
smallerBox[UpperLeft] := ShadeSquare(x,y,leftWidth,upperHeight,ul,left,centre,top); {upper left rect}
smallerBox[LowerLeft] := ShadeSquare(x,y+upperHeight,leftWidth,lowerHeight,left,ll,bottom,centre); {lower left}
smallerBox[LowerRight] := ShadeSquare(x+leftWidth,y+upperHeight,rightWidth,
lowerHeight,centre,bottom,lr,right);
smallerBox[UpperRight] := ShadeSquare(x+leftWidth,y,rightWidth,upperHeight,top,centre,right,ur); {upper right}
uniform := true;
drawingPat := smallerBox[LowerRight];
for i := UpperLeft to LowerLeft do
uniform := uniform and ((smallerBox[i] = NullBox) or (smallerBox[i] = drawingPat));
if uniform then
shadeSquare := drawingPat
else begin
for i := UpperLeft to LowerRight do
if smallerBox[i] > 0 then
paintArea;
shadeSquare := 0;
end;
end;
end;
function shadePlot(x,y,width,height : integer) : PatNum;
var
i,
leftWidth,rightWidth,
upperHeight,lowerHeight : integer;
smallerBox : array[1..4] of PatNum;
uniform : boolean;
drawingPat : PatNum;
realY : longint;
procedure paintArea;
var
tempRect : rect;
begin
PenPat(PatList[smallerBox[i]]);
if not (smallerBox[i] in [1..10]) then
sysbeep(1);
with tempRect do
case i of
UpperLeft : begin
left := x;
top := realY;
right := x+leftWidth;
bottom := realY+upperHeight;
end;
UpperRight : begin
left := x+leftWidth;
top := realY;
right := x+leftWidth+rightWidth;
bottom := realY+upperHeight;
end;
LowerLeft : begin
left := x;
top := realY+upperHeight;
right := x+leftWidth;
bottom := realY+upperHeight+lowerHeight;
end;
LowerRight : begin
left := x+leftWidth;
top := realY+upperHeight;
right := x+leftWidth+rightWidth;
bottom := realY+upperHeight+lowerHeight;
end;
end;
with tempRect do begin
left := left*currentGridSize;
top := top *currentGridsize;
right := right*currentGridSize;
bottom := bottom*currentGridSize;
end;
PaintRect(tempRect);
PenNormal;
end;
begin
realY := yLow+segment*maxRows + y;
leftWidth := width div 2;
rightWidth := (width + 1) div 2;
upperHeight := height div 2;
lowerHeight := (height + 1) div 2;
for i := UpperLeft to LowerRight do
smallerBox[i] := 0;
if (leftWidth = 0) then begin
smallerBox[UpperLeft] := NullBox;
smallerBox[LowerLeft] := NullBox;
end;
if (upperHeight = 0) then begin
smallerBox[UpperLeft] := NullBox;
smallerBox[UpperRight] := NullBox;
end;
if (smallerBox[UpperLeft] <> NullBox) then
if (leftWidth = 1) and (upperHeight = 1) then
smallerBox[UpperLeft] := shadeSquare(x*currentGridSize,RealY*currentGridSize,
currentGridSize,currentGridSize,
ord(data[y]^[x]),ord(data[y+1]^[x]),
ord(data[y+1]^[x+1]),ord(data[y]^[x+1]))
else
smallerBox[UpperLeft] := shadePlot(x,y,leftWidth,upperHeight);
if (smallerBox[UpperRight] <> NullBox) then
if (rightWidth = 1) and (upperHeight = 1) then
smallerBox[UpperRight] := shadeSquare((x+leftWidth)*currentGridSize,
RealY*currentGridSize,
currentGridSize,currentGridSize,
ord(data[y]^[x+leftwidth]),
ord(data[y+1]^[x+leftWidth]),
ord(data[y+1]^[x+leftWidth+1]),
ord(data[y]^[x+leftWidth+1]))
else
smallerBox[UpperRight] := shadePlot(x+leftWidth,y,rightWidth,upperHeight);
if (smallerBox[LowerLeft] <> NullBox) then
if (leftWidth = 1) and (lowerHeight = 1) then
smallerBox[LowerLeft] := shadeSquare(x*currentGridSize,
(y+upperHeight)*currentGridSize,
currentGridSize,currentGridSize,
ord(data[y+upperHeight]^[x]),
ord(data[y+upperHeight+1]^[x]),
ord(data[y+upperHeight+1]^[x+1]),
ord(data[y+upperHeight]^[x+1]))
else
smallerBox[LowerLeft] := shadePlot(x,y+upperHeight,leftWidth,lowerHeight);
if (rightWidth = 1) and (lowerHeight = 1) then
smallerBox[LowerRight] := shadeSquare((x+leftWidth)*currentGridSize,
(y+upperHeight)*currentGridSize,
currentGridSize,currentGridSize,
ord(data[y+upperHeight]^[x+leftWidth]),
ord(data[y+upperHeight+1]^[x+leftWidth]),
ord(data[y+upperHeight+1]^[x+leftWidth+1]),
ord(data[y+upperHeight]^[x+leftWidth+1]))
else
smallerBox[LowerRight] := shadePlot(x+leftWidth,y+upperHeight,rightWidth,lowerHeight);
uniform := true;
drawingPat := smallerBox[LowerRight];
for i := UpperLeft to LowerLeft do
uniform := uniform and ((smallerBox[i] = NullBox) or (smallerBox[i] = drawingPat));
if uniform then
shadePlot := drawingPat
else begin
for i := UpperLeft to LowerRight do
if (smallerBox[i] > 0) then
paintArea;
shadePlot := 0;
end;
end;
begin
GetPenState(pState);
PenNormal;
divisor := 255 div numPatterns;
getIndPattern(patList[1], SysPatListID, 20); { white }
getIndPattern(patList[2], SysPatListID, 13);
getIndPattern(patList[3], SysPatListID, 21);
getIndPattern(patList[4], SysPatListID, 22);
getIndPattern(patList[5], SysPatListID, 23);
getIndPattern(patList[6], SysPatListID, 4);
getIndPattern(patList[7], SysPatListID, 3);
getIndPattern(patList[8], SysPatListID, 2);
StuffHex(@patList[9], '7FFFFFFFFFFFFFFF');
getIndPattern(patList[10], SysPatListID, 1); { black }
myPat := shadePlot(xLow,0,xhigh-xlow,noOfRows);
if myPat > 0 then begin
realY := yLow + segment*maxRows;
SetRect(myRect,xLow*currentGridSize,realY*currentGridSize
,xHigh*currentGridSize,(realY+noOfRows)*currentGridSize);
PenPat(PatList[myPat]);
PaintRect(myRect);
end;
SetPenState(pState);
end; { ShadePlot }
begin
GetMatrixBounds(UpdateRect,Xlow,Xhigh,Ylow,Yhigh);
GetPenState(PState);
NoOfSegments := round( (Yhigh-Ylow+1)/maxRows + 0.49);
remainingRows := (Yhigh-Ylow+1 - (NoOfSegments-1)*maxRows);
PenNormal;
count := maxX[windowIndex];
posOff := longint(Ylow)*maxX[windowIndex];
resultCode := SetFPos(theFile[windowIndex],fsFromStart,posOff);
if resultCode <> 0 then sysbeep(1);
resultCode := FSRead(theFile[windowIndex],count,ptr(data[maxRows]));
if resultCode <> 0 then sysbeep(1);
for segment := 0 to NoOfSegments -1 do begin
if cancelOp then
exit;
if segment = (NoOfSegments-1) then
NoOfRows := remainingRows -1
else
NoOfRows := maxRows;
SwapPtr(data[0],data[maxRows]);
for y := 1 to NoOfRows do begin
resultCode := FSRead(theFile[windowIndex],count,ptr(data[y]));
if resultCode <> 0 then sysbeep(1);
end;
if segment = (NoOfSegments-1) then
NoOfRows := NoOfRows+1;
if shadeSurface[windowIndex] then
initShade
else
for y := minY to NoOfRows - 1 do begin
if cancelOp then
exit;
RealY := Ylow + segment*maxRows + y;
for x := Xlow to Xhigh-1 do begin
minMaxVertex;
if (ContourLevel[windowIndex][1] <= DataMax) and
(DataMin <= contourLevel[windowIndex][NoOfLevels[windowIndex]]) then begin
for level := 1 to NoOfLevels[windowIndex] do begin
if (ContourLevel[windowIndex][level] <= DataMax) and
(DataMin <= contourLevel[windowIndex][level]) then begin
ProcessVertices;
ProcessTriangles;
end; {a plot in level}
end; {each contour level}
end; {at least one plot in box}
end; { each x coordinate}
end; { each y coordinate}
end; { each segment}
if gridOn[windowIndex] then
DrawGrid(xlow,xhigh,ylow,yhigh);
SetPenState(PState);
end; { contourPlot }
end.