{$U-} unit ThreeD(35); interface uses MemTypes, QuickDraw, OSIntf, ToolIntf,MacPrint,FixMath,Graf3D, Globals, Utilities; procedure ThreeDPlot(bounds : rect); procedure redrawBox; procedure Refresh3D; procedure Prepare3DPlot; procedure CreateData(x,y:integer); implementation const zID = 253; yID = 254; xID = 255; HBarID = 256; VBarID = 257; WindID = 32503; MagLevel = 7; type directions = (up,dn,rt,lt); var Dx,Dy,Dz : integer; PlotAxis, choice1,choice2 : directions; rgnA,rgnB : PolyHandle; {-----------------------------------------------------------------------} function fix(normal:longint):fixed; { convert a longint to fixed } begin fix := normal*65536; end; {-----------------------------------------------------------------------} procedure PlotData(method : directions); var row, col, curRow, curCol : longint; regionA, regionB : RgnHandle; maxRow, maxColumn, minX, minY, minZ : longint; begin maxRow := fix(90); maxColumn := maxRow; minX := fix(-85); minY := fix(-85); minZ := 0; regionB := NewRgn; SetEmptyRgn(regionB); regionA := NewRgn; case method of rt : for row := 1 to 25 do begin curRow := fix(row*magLevel-85); OpenRgn; MoveTo3D(curRow,MaxColumn,minZ); LineTo3D(minX,maxColumn,minZ); LineTo3D(minX,minY,minZ); LineTo3D(curRow,minY,minZ); for col := 1 to 25 do LineTo3D(curRow,fix(col*magLevel-85),fix(data3D[row,col])); LineTo3D(curRow,maxColumn,minZ); closeRgn(regionA); unionRgn(regionA,regionB,regionB); FrameRgn(regionB); end; Up : for col := 25 downto 1 do begin curCol := fix(col*magLevel-85); openRgn; MoveTo3D(minX,curCol,minZ); LineTo3D(minX,maxColumn,minZ); LineTo3D(maxRow,maxColumn,minZ); LineTo3D(maxRow,curCol,minZ); for row := 25 downto 1 do LineTo3D(fix(row*maglevel-85),curCol,fix(data3D[row,col])); LineTo3D(minX,curCol,minZ); closeRgn(regionA); unionRgn(regionA,regionB,regionB); FrameRgn(regionB); end; lt : for row := 25 downto 1 do begin curRow := fix(row*magLevel-85); openRgn; MoveTo3D(curRow,minY,minZ); LineTo3D(maxRow,minY,minZ); LineTo3D(maxRow,maxColumn,minZ); LineTo3D(curRow,maxColumn,minZ); for col := 25 downto 1 do LineTo3D(curRow,fix(col*magLevel-85),fix(data3D[row,col])); LineTo3D(curRow,minY,minZ); closeRgn(regionA); unionRgn(regionA,regionB,regionB); FrameRgn(regionB); end; dn : for col := 1 to 25 do begin curCol := fix(col*magLevel-85); openRgn; MoveTo3D(maxRow,curCol,minZ); LineTo3D(maxRow,minY,minZ); LineTo3D(minX,minY,minZ); LineTo3D(minX,curCol,minZ); for row := 1 to 25 do LineTo3D(fix(row*maglevel-85),curCol,fix(data3D[row,col])); LineTo3D(maxRow,curCol,minZ); closeRgn(regionA); unionRgn(regionA,regionB,regionB); FrameRgn(regionB); end; end; disposeRgn(regionB); disposeRgn(regionA); end; procedure drawBox; var src,dst : Point3D; length : longint; pState : PenState; begin GetPenState(pState); length := fix(20); MoveTo3D(length,-length,length); PenSize(2,2); LineTo3D(length,-length,-length); MoveTo3D(length,length,length); LineTo3D(length,length,-length); PenSize(1,1); MoveTo3D(-length,length,length); LineTo3D(-length,length,-length); MoveTo3D(-length,-length,length); LineTo3D(-length,-length,-length); rgnA := OpenPoly; MoveTo3D(-length,-length,-length); LineTo3D(length,-length,-length); LineTo3D(length,length,-length); LineTo3D(-length,length,-length); LineTo3D(-length,-length,-length); closePoly; rgnB := OpenPoly; MoveTo3D(-length,-length,length); LineTo3D(length,-length,length); LineTo3D(length,length,length); LineTo3D(-length,length,length); LineTo3D(-length,-length,length); closePoly; with src do begin x := 0; y := 0; z := length; end; Transform(src,dst); if dst.z >= 0 then begin PenSize(1,1); FramePoly(rgnA); FillPoly(rgnB,white); PenSize(2,2); FramePoly(rgnB); PenSize(1,1); end else begin PenSize(2,2); FramePoly(rgnB); FillPoly(rgnA,white); PenSize(1,1); FramePoly(rgnA); end; SetPenState(pState); end; procedure redrawBox; var newPt, oldPt : Point; deltaX, deltaY : longint; boxRect : rect; changed : boolean; begin GetMouse(oldPt); Translate(fix(40),fix(155),0); repeat GetMouse(newPt); deltaX := newPt.h - oldPt.h; deltaY := newPt.v - oldPt.v; if (abs(deltaX) > 5) or (abs(deltaY) > 5) then begin changed := true; setRect(boxRect,0,10,100,340); EraseRect(boxRect); Translate(fix(-40),fix(-155),0); Yaw(-fix(deltaX)); Pitch(fix(deltaY)); Translate(fix(40),fix(155),0); drawBox; oldPt := newPt; end; until not StillDown; Translate(-fix(40),-fix(155),0); if changed then InvalRect(myRect[windowIndex]); end; procedure Prepare3DPlot; var src,dst : Point3D; begin if toggle[windowIndex] then begin with src do begin x := fix(20); y := 0; z := 0; end; Transform(src,dst); if dst.z >= 0 then plotAxis := lt else plotAxis := rt; end else begin with src do begin x := 0; y := fix(20); z := 0; end; Transform(src,dst); if dst.z >= 0 then plotAxis := up else plotAxis := dn; end; Translate(fix(Dx),fix(Dy),fix(Dz)); PlotData(PlotAxis); Translate(-fix(Dx),-fix(Dy),-fix(Dz)); end; {-----------------------------------------------------------------------} procedure CreateData {(x,y : integer)}; var a,b,c : longint; min,max : integer; begin SetCursor(clockCursor^^); min := 0; max := 0; for a := 1 to 25 do begin c := ((a-1)*yStep+y)*maxX[windowIndex]; resultCode := setFPos(theFile[windowIndex],FSFromStart,c); if resultCode <> 0 then sysBeep(1); resultCode := FSRead(theFile[windowIndex],count,ptr(data[0])); if resultCode <> 0 then sysBeep(1); for b := 1 to 25 do begin data3D[b,a] := ord(data[0]^[x+xStep*(b-1)]); if data3D[b,a] < min then min := data3D[b,a] else if data3D[b,a] > max then max := data3D[b,a]; end; end; for a := 1 to 25 do for b := 1 to 25 do begin data3D[b,a] := data3D[b,a]*100 div (max-min); end; InitCursor; end; {-----------------------------------------------------------------------} procedure Refresh3D; begin SetPort3D(@my3DPort); ShowControl(TDHBar[windowIndex]); ShowControl(TDVBar[windowIndex]); DrawControls(ThreeDWindow[windowIndex]); Translate(fix(40),fix(155),0); drawBox; Translate(-fix(40),-fix(155),0); end; {-----------------------------------------------------------------------} procedure InitStuff; begin ThreeDWindow[windowIndex] := GetNewWindow(WindID,nil,pointer(-1)); SetPort(ThreeDWindow[windowIndex]); open3DPort(@my3DPort[windowIndex]); Identity; setRect(myRect[windowIndex],0,0,460,284); ViewPort(myRect[windowIndex]); LookAt(0,0,fix(460),fix(284)); ViewAngle(fix(25)); Dx := 300; Dy := 145; Dz := 0; PenNormal; toggle[windowIndex] := false; Pitch(fix(-40)); Yaw(fix(-30)); Roll(0); xTops[windowIndex] := 0; yTops[windowIndex] := 0; TDHBar[windowIndex] := GetNewControl(HBarID,ThreeDWindow[windowIndex]); TDVBar[windowIndex] := GetNewControl(VBarID,ThreeDWindow[windowIndex]); end; procedure ThreeDPlot; { bounds: rect } begin if ThreeDWindow[windowIndex] = nil then InitStuff else if secondTime[windowIndex] and (FrontWindow <> ThreeDWindow[windowIndex]) then begin SelectWindow(ThreeDWindow[windowIndex]); ShowWindow(ThreeDWindow[windowIndex]); end else secondTime[windowIndex] := true; GetMatrixBounds(bounds,Xlow,Xhigh,Ylow,Yhigh); if (Xhigh - Xlow) < 24 then begin if (Xlow+24) > maxX[windowIndex] then Xlow := Xhigh-24 else Xhigh := Xlow+24; xStep := 1; end else xStep := round((Xhigh-Xlow+1)/25); if (Yhigh-Ylow)<24 then begin if (Ylow+24) > maxY[windowIndex] then Ylow := Yhigh-24 else Yhigh := Ylow+24; yStep := 1; end else yStep := round((Yhigh-Ylow+1)/25); if (maxX[windowIndex]-xStep*25) < 0 then SetCtlMax(TDHBar[windowIndex],0) else SetCtlMax(TDHBar[windowIndex],MaxX[windowIndex]-xStep*25); if (maxY[windowIndex]-yStep*25) < 0 then SetCtlMax(TDVBar[windowIndex],0) else SetCtlMax(TDVBar[windowIndex],MaxY[windowIndex]-yStep*25); SetCtlValue(TDHBar[windowIndex],Xlow); SetCtlValue(TDVBar[windowIndex],Ylow); enableItem(PlotMenu,5); CreateData(Xlow,Ylow); end; end. .