unit mainWin; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Math, ComCtrls; type TExtendedPoint = record X, Y: real; end; TVector = record X, Y, Z: real; end; TForm1 = class(TForm) Button1: TButton; Button2: TButton; cnvs: TImage; Button3: TButton; Button4: TButton; ECPX: TEdit; ECPY: TEdit; ECPZ: TEdit; EFI: TTrackBar; ETH: TTrackBar; EZOOM: TTrackBar; Button5: TButton; Memo1: TMemo; ERO: TTrackBar; cnvs2: TImage; btndebugset: TButton; highres: TCheckBox; ProgressBar1: TProgressBar; ERES: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; procedure FormCreate(Sender: TObject); procedure CreateSet(Sender: TObject); procedure DrawSet(Sender: TObject); procedure CreateFctnGraph(Sender: TObject); procedure CreateFctnParamGraph(Sender: TObject); procedure EFIChange(Sender: TObject); procedure CreateBaseGrid(Sender: TObject); procedure cbDebugClick(Sender: TObject); procedure Button2Click(Sender: TObject); procedure ECPXKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure highresClick(Sender: TObject); procedure ERESKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); procedure FormShow(Sender: TObject); procedure ERESEnter(Sender: TObject); procedure ERESExit(Sender: TObject); private { Private declarations } public { Public declarations } function Vctr(A, B, C: real): TVector; function Add(A, B: TVector): TVector; function Sub(A, B: TVector): TVector; function Mul(A: real; B: TVector): TVector; function Dot(A, B: TVector): real; function VecLength(A: TVector): real; function VecLengthCompare(A: TVector): real; procedure FindDirection; function FindProjection(X: TVector): TVector; function FindProjection2(X: TVector): TVector; function VectorToString(V: TVector): string; function GetColorFromPos(x, y, z: real): TColor; function LogToScrn(Point: TExtendedPoint): TPoint; function ScrnToLog(Point: TPoint): TExtendedPoint; function LogToScrn2(Point: TExtendedPoint): TPoint; function Scrn2ToLog(Point: TPoint): TExtendedPoint; function SpaceSysToPlaneSys(X: TVector): TVector; function SpaceSysToPlaneSys2(X: TVector): TVector; function Cross(X, Y: TVector): TVector; end; var Form1: TForm1; xmax, xmin, ymax, ymin, zmin, zmax: real; Vector: TVector; CameraPos, CameraPos2: TVector; PlaneVec, PlaneVec2: TVector; Direction: TVector; d, d2: real; resfktn, reseval: real; Graph: array of TVector; CPF, CPT, CPD, CPR: real; CenterPos, PlaneCenterPos, Plane2CenterPos: TVector; T: array[1..3, 1..3] of real; T2: array[1..3, 1..3] of real; DebugGraph: array of TVector; implementation {$R *.dfm} function TForm1.Vctr(A, B, C: real): TVector; begin result.X := A; result.Y := B; result.Z := C; end; function TForm1.Add(A, B: TVector): TVector; begin result := Vctr(A.X + B.X, A.Y + B.Y, A.Z + B.Z); end; function TForm1.Sub(A, B: TVector): TVector; begin result := Vctr(A.X - B.X, A.Y - B.Y, A.Z - B.Z); end; function TForm1.Mul(A: real; B: TVector): TVector; begin result := Vctr(A*B.X, A*B.Y, A*B.Z); end; function TForm1.Dot(A, B: TVector): real; begin Dot := A.X * B.X + A.Y * B.Y + A.Z * B.Z; end; function TForm1.VecLength(A: TVector): real; begin VecLength := sqrt(Dot(A, A)); end; function TForm1.VecLengthCompare(A: TVector): real; begin VecLengthCompare := (Dot(A, A)); end; procedure TForm1.FormCreate(Sender: TObject); var NPlaneVec, NPlaneVec2: TVector; fx, fy, fx2, fy2: TVector; A: array[1..3, 1..3] of real; CPRsin, CPRcos, CZOOM: real; begin//X_f = T^-1 X_e omm _f = _eT; i programmet är T transponatet (=inversen, ja ortogonal ty ON-basbyte!) av T i formeln CPF := EFI.Position * PI / 180; CPT := ETH.Position * PI / 180; CPD := 20; CZOOM := EZOOM.Position; CPR := ERO.Position * PI/180; CenterPos := Vctr(StrToFloat(ECPX.Text), StrToFloat(ECPY.Text), StrToFloat(ECPZ.Text)); xmin := -CZOOM; xmax := CZOOM; ymin := -CZOOM; ymax := CZOOM; zmin := -CZOOM; zmax := CZOOM; PlaneVec := Vctr(sin(CPT) * cos(CPF), sin(CPT) * sin(CPF), cos(CPT)); /////Test //if false then begin //setlength(Graph, length(Graph) + 1); //Graph[high(Graph)] := Mul(10/VecLength(PlaneVec), PlaneVec); end; // memo1.Lines.Add(VectorToString(PlaneVec)); /////Test slut CameraPos := Add(CenterPos, Mul(2*CPD / VecLength(PlaneVec), PlaneVec)); d := (CPD * VecLength(PlaneVec) + Dot(PlaneVec, CenterPos)){ * Sign(d - Dot(PlaneVec, CenterPos))}; // Planekvationens högerled PlaneCenterPos := FindProjection(CenterPos); /////Test //Caption := floattostr(VecLength(Sub(CameraPos, CenterPos))) + ' ---- ' + floattostr(VecLength(Sub(PlaneCenterPos, CenterPos))) + ' ---- ' + floattostr(VecLength(Sub(CameraPos, PlaneCenterPos))); /////Test slut resfktn := StrToFloat(ERES.Text); reseval := StrToFloat(ERES.Text); // Rymd-Plan-omvandling NPlaneVec := Mul(1/VecLength(PlaneVec), PlaneVec); // f_z T[3, 1] := NPlaneVec.X; // T är transpontatet (inversen, ty alla baser är ON => T är ortogonal) av T i f=eT. T[3, 2] := NPlaneVec.Y; T[3, 3] := NPlaneVec.Z; // f_x // Varför sätter vi inte bara t ex fx := vctr(0, -T[3, 3], T[3, 2])? // Det är väl klart att fx då blir ortogonal med fz? // Jo, det är klart, men om t ex fz = vctr(1, 0, 0), så blir ju fx nollvektorn! // Visst är den ortogonal med fz, men någon basvektor är det inte! // Krav på vektorn fx är (i) (fx|fz) = 0 // (ii) fx IN {z=0} // => (fx3 = 0) ^ (npv1 * fx1 = -npv2 * fx2) // Antingen är (1) npv1 = npv2 = 0 // (2) npv1 = 0; npv2 <> 0 // (3) npv1 <> 0; npv2 = 0 // (4) npv1 <> 0; npv2 <> 0; if NPlaneVec.Y = 0 then begin fx := vctr(0, 1, 0); // Mikebuggen // Bibehåll den skenbara kamerarotation som FI ger upphov till CPR := CPR + CPF; end else begin if CPF <= PI then fx := vctr(-1, NPlaneVec.X/NPlaneVec.Y, 0) else fx := vctr(1, -NPlaneVec.X/NPlaneVec.Y, 0); fx := Mul(1/VecLength(fx), fx); end; T[1, 1] := fx.X; T[1, 2] := fx.Y; T[1, 3] := fx.Z; // f_y fy := Cross(Vctr(T[3,1], T[3,2], T[3,3]), Vctr(T[1,1], T[1,2], T[1,3])); fy := Mul(1/VecLength(fy), fy); T[2, 1] := fy.X; T[2, 2] := fy.Y; T[2, 3] := fy.Z; if Dot(Cross(fx, fy), NPlaneVec) < 0 then begin fy := Mul(-1, fy); beep; end; // Rotera f_x och f_y runt f_z // Avbildningsmatrisen A för rotation CPR grader runt den tredje koordinataxeln // Bara för prestandan CPRsin := sin(CPR); CPRcos := cos(CPR); A[1, 1] := CPRcos; A[1, 2] := -CPRsin; A[1, 3] := 0; A[2, 1] := CPRsin; A[2, 2] := CPRcos; A[2, 3] := 0; A[3, 1] := 0; A[3, 2] := 0; A[3, 3] := 1; // F(fX) = fAX // Vi skall alltså multiplicera koordinatvektorn X uttryckt i basen f från vänster med A. // Koordinatmatriserna för fx och fy är (1 0 0)^t respektive (0 1 0)^t. fx := Vctr(A[1,1]{ * 1 + A[1,2] * 0 + A[1,3] * 0}, A[2,1]{ * 1 + A[2,2] * 0 + A[2,3] * 0}, A[3,1]{ * 1 + A[3,2] * 0 + A[3,3] * 0}); fy := Vctr({A[1,1] * 0 + }A[1,2]{ * 1 + A[1,3] * 0}, {A[2,1] * 0 + }A[2,2]{ * 1 + A[2,3] * 0}, {A[3,1] * 0 + }A[3,2]{ * 1 + A[3,3] * 0}); // I rätt bas också! (fx och fy blir koordinatmatriserna i gamla f-systemet, men de skall anges i e-systemet! X_e = T X_f, där T är transponatet av matrisen T i koden. fx := Vctr(T[1,1] * fx.X + T[2,1] * fx.Y + T[3,1] * fx.Z, T[1,2] * fx.X + T[2,2] * fx.Y + T[3,2] * fx.Z, T[1,3] * fx.X + T[2,3] * fx.Y + T[3,3] * fx.Z); fy := Vctr(T[1,1] * fy.X + T[2,1] * fy.Y + T[3,1] * fy.Z, T[1,2] * fy.X + T[2,2] * fy.Y + T[3,2] * fy.Z, T[1,3] * fy.X + T[2,3] * fy.Y + T[3,3] * fy.Z); T[1, 1] := fx.X; T[1, 2] := fx.Y; T[1, 3] := fx.Z; T[2, 1] := fy.X; T[2, 2] := fy.Y; T[2, 3] := fy.Z; /////Test //Caption := floattostr(VecLength(Cross(PlaneVec, vctr(T[3,1], T[3,2], T[3,3])))); { // parvis ortogonalitet Caption := floattostr(dot(vctr(T[1,1], T[1,2], T[1,3]), vctr(T[2,1], T[2,2], T[2,3]))); Caption := Caption + ' --- ' + floattostr(dot(vctr(T[1,1], T[1,2], T[1,3]), vctr(T[3,1], T[3,2], T[3,3]))); Caption := Caption + ' --- ' + floattostr(dot(vctr(T[2,1], T[2,2], T[2,3]), vctr(T[3,1], T[3,2], T[3,3]))); }{ // normering Caption := floattostr(VecLength(vctr(T[1,1], T[1,2], T[1,3]))); Caption := Caption + ' --- ' + floattostr(VecLength(vctr(T[2,1], T[2,2], T[2,3]))); Caption := Caption + ' --- ' + floattostr(VecLength(vctr(T[3,1], T[3,2], T[3,3]))); } /////Test slut //CLW PlaneVec2 := Vctr(sin(PI/4) * cos(PI/4), sin(PI/4) * sin(PI/4), cos(PI/4)); CameraPos2 := Add(CenterPos, Mul(2*CPD / VecLength(PlaneVec2), PlaneVec2)); d2 := (CPD * VecLength(PlaneVec2) + Dot(PlaneVec2, CenterPos)){ * Sign(d - Dot(PlaneVec2, CenterPos))}; // Planekvationens högerled Plane2CenterPos := FindProjection2(CenterPos); // Rymd-Plan-omvandling CLW! NPlaneVec2 := Mul(1/VecLength(PlaneVec2), PlaneVec2); // f_z T2[3, 1] := NPlaneVec2.X; T2[3, 2] := NPlaneVec2.Y; T2[3, 3] := NPlaneVec2.Z; // f_x fx2 := vctr(-T2[3, 2], T2[3, 1], 0); fx2 := Mul(1/VecLength(fx2), fx2); T2[1, 1] := fx2.X; T2[1, 2] := fx2.Y; T2[1, 3] := fx2.Z; // f_y fy2 := Cross(Vctr(T2[3,1], T2[3,2], T2[3,3]), Vctr(T2[1,1], T2[1,2], T2[1,3])); fy2 := Mul(1/VecLength(fy2), fy2); T2[2, 1] := fy2.X; T2[2, 2] := fy2.Y; T2[2, 3] := fy2.Z; //CLW slut end; procedure TForm1.FindDirection; begin Direction := Sub(CameraPos, Vector); end; function TForm1.FindProjection(X: TVector): TVector; var t: real; begin Vector := Vctr(X.X, X.Y, X.Z); FindDirection; t := (d - Dot(PlaneVec, Vector))/(Dot(PlaneVec, Direction)); result := Add(Vector, Mul(t, Direction)); end; function TForm1.FindProjection2(X: TVector): TVector; var t: real; Direction2: TVector; begin Vector := Vctr(X.X, X.Y, X.Z); Direction2 := Sub(CameraPos2, Vector); t := (d2 - Dot(PlaneVec2, Vector))/(Dot(PlaneVec2, Direction2)); result := Add(Vector, Mul(t, Direction2)); end; function TForm1.VectorToString(V: TVector): string; begin result := '(' + FloatToStr(V.X) + ', ' + FloatToStr(V.Y) + ', ' + FloatToStr(V.Z) + ')'; end; procedure TForm1.CreateSet(Sender: TObject); var i: integer; begin // for x := low(Graph) to high(Graph) do // MySet[x, y, z] := x + z - y = 100; // MySet[x, y, z] := (x < 50) or (x > 150) or (y < 50) or (y > 150) or (sqrt((x-100)*(x-100) + 2*(y-100)*(y-100) + 3*(z-100)*(z-100) + (x-100)*(y-100) - (z-100)*(x-100)) <= 80); // MySet[x, y, z] := (x < 50) or (x > 150) or (y < 50) or (y > 150); // MySet[x, y, z] := sqrt((x-100)*(x-100) + 2*(y-100)*(y-100) + 3*(z-100)*(z-100) + (x-100)*(y-100) - (z-100)*(x-100)) <= 80; // MySet[x, y, z] := (sqrt((x-50)*(x-50) + (y-50)*(y-50) + (z-40)*(z-40)) <= 40) Or (sqrt((x-150)*(x-150) + (y-150)*(y-150) + (z-worldsize+40)*(z-worldsize+40)) <= 40) end; procedure TForm1.DrawSet(Sender: TObject); var i: integer; prj: TVector; extp: TExtendedPoint; scrn: TPoint; Buffer, Buffer2: TBitmap; crdist: integer; crdistin, crdistout, pbpos: integer; MinDist: TBitmap; //hellre en array[1..screenwidth] of arraw[1..screenheight] of real, men ger stack overflow... //Test //st:TStringList; //Test slut // Camera Localisation Window CamLocGraph: array of TVector; prj2: TVector; extp2: TExtendedPoint; scrn2: TPoint; // End CLW begin Buffer := TBitmap.Create; Buffer.Width := cnvs.Width; Buffer.Height := cnvs.Height; Buffer.Canvas.Brush.Color := clWhite; Buffer.Canvas.FillRect(Rect(0, 0, Buffer.Width, Buffer.Height)); //CLW Buffer2 := TBitmap.Create; Buffer2.Width := cnvs2.Width; Buffer2.Height := cnvs2.Height; Buffer2.Canvas.Brush.Color := clWhite; Buffer2.Canvas.FillRect(Rect(0, 0, Buffer2.Width, Buffer2.Height)); //CLW slut MinDist := TBitmap.Create; // MED BLOCKET NEDAN! MinDist.Width := Buffer.Width; MinDist.Height := Buffer.Height; MinDist.Canvas.Draw(0, 0, Buffer); //MED BLOCKET NEDAN! /////TEST // st := TStringList.Create; /////Test slut ProgressBar1.Min := 0; ProgressBar1.Max := 100; ProgressBar1.Position := ProgressBar1.Min; for i := low(Graph) to high(Graph) do begin prj := SpaceSysToPlaneSys(FindProjection(Graph[i])); /////Test //st.Add(VectorToString(prj)); /////Test slut extp.X := prj.X; extp.Y := prj.Y; scrn := LogToScrn(extp); crdist := round(VecLengthCompare(Sub(CameraPos, Graph[i]))); // Utan blocket: 10 s; Med blocket: 60+ sekunder. Varför??????? Troligtvis tar det tid att läsa från/skriva till TBitmap.Canvas. Kanske löses problemet med arrayen ovan? crdistin := MinDist.Canvas.Pixels[scrn.X, scrn.Y]; if crdistin = 0 then crdistout := crdist else crdistout := min(crdistin, crdist); MinDist.Canvas.Pixels[scrn.X, scrn.Y] := crdistout; if MinDist.Canvas.Pixels[scrn.X, scrn.Y] = crdist then {} Buffer.Canvas.Pixels[scrn.X, scrn.Y] := GetColorFromPos(Graph[i].X, Graph[i].Y, Graph[i].Z); //CLW prj2 := SpaceSysToPlaneSys2(FindProjection2(Graph[i])); extp2.X := prj2.X; extp2.Y := prj2.Y; scrn2 := LogToScrn2(extp2); Buffer2.Canvas.Pixels[scrn2.X, scrn2.Y] := clBlack; //CLW slut // Progress if i mod 2000 = 0 then begin pbpos := round(100*(i / high(Graph))); if ProgressBar1.Position <> pbpos then begin ProgressBar1.Position := pbpos; ProgressBar1.Repaint; end; end; end; cnvs.Canvas.Draw(0, 0, Buffer); ProgressBar1.Position := 100; Buffer.Free; MinDist.Free; /////Test // memo1.Lines.AddStrings(st); // st.Free; /////Test slut //CLW prj2 := SpaceSysToPlaneSys2(FindProjection2(Mul(0.5, PlaneCenterPos))); extp2.X := prj2.X; extp2.Y := prj2.Y; scrn2 := LogToScrn2(extp2); Buffer2.Canvas.Brush.Color := clRed; Buffer2.Canvas.FillRect(Rect(scrn2.X-2, scrn2.Y-2, scrn2.X+2, scrn2.Y+2)); cnvs2.Canvas.Draw(0, 0, Buffer2); Buffer2.Free; //CLW slut memo1.clear; memo1.lines.add('Medelpunkt: ' + VectorToString(vctr(strtofloat(ECPX.Text), strtofloat(ECPY.Text), strtofloat(ECPZ.Text)))); memo1.lines.add('THETA: ' + IntToStr(ETH.Position) + ' grader'); memo1.lines.add('FI: ' + IntToStr(EFI.Position) + ' grader'); memo1.lines.add('Kamerarotation: ' + IntToStr(ERO.Position) + ' grader'); memo1.lines.add('Zoomnivå: -' + IntToStr(EZOOM.Position)); memo1.lines.add('Upplösning: ' + FloatToStr(resfktn)); memo1.lines.add('Antal punkter uppritade: ' + IntToStr(length(Graph))); end; function TForm1.GetColorFromPos(x, y, z: real): TColor; begin // result := RGB(255, round(255*((zmax-2*z)/(zmax-zmin))), round(255*((zmax-2*z)/(zmax-zmin)))); //RED result := RGB(round(255*((zmax-2*z)/(zmax-zmin))), round(255*((zmax-2*z)/(zmax-zmin))), 255); //BLUE end; function TForm1.LogToScrn(Point: TExtendedPoint): TPoint; begin result.X := Round((cnvs.Width / (xmax-xmin))*(Point.X - xmin)); result.Y := cnvs.Height - Round((cnvs.Height / (ymax-ymin))*(Point.Y - ymin)); end; function TForm1.ScrnToLog(Point: TPoint): TExtendedPoint; begin result.X := ((xmax-xmin)/cnvs.Width) * Point.X + xmin; result.Y := ((ymax-ymin)/cnvs.Height) * (cnvs.Height - Point.Y) + ymin; end; function TForm1.LogToScrn2(Point: TExtendedPoint): TPoint; begin result.X := Round((cnvs2.Width / (xmax-xmin))*(Point.X - xmin)); result.Y := cnvs2.Height - Round((cnvs2.Height / (ymax-ymin))*(Point.Y - ymin)); end; function TForm1.Scrn2ToLog(Point: TPoint): TExtendedPoint; begin result.X := ((xmax-xmin)/cnvs2.Width) * Point.X + xmin; result.Y := ((ymax-ymin)/cnvs2.Height) * (cnvs2.Height - Point.Y) + ymin; end; procedure TForm1.CreateFctnGraph(Sender: TObject); function fktn(x, y: real): real; begin result := 1.5*sin(sqrt(x*x + y*y)); end; var x, y: real; begin // SetLength(Graph, 0); y := ymin; repeat x := xmin; repeat SetLength(Graph, length(Graph) + 1); Graph[high(Graph)] := Vctr(x, y, fktn(x, y)); x := x + resfktn; if length(Graph) > 100000000 then begin abort; application.Terminate; end; until x > xmax; y := y + resfktn; until y > ymax; end; procedure TForm1.CreateFctnParamGraph(Sender: TObject); function fktn(s, t: real): TVector; begin result := vctr(sin(s) * cos(t), sin(s) * sin(t), cos(s)); end; var s, t: real; begin t := 0; repeat s := 0; repeat if length(Graph) > 100000000 then begin abort; application.Terminate; end; SetLength(Graph, Length(Graph) + 3); Graph[high(Graph)-2] := add(fktn(t,s), vctr(-3, -2, -1)); Graph[high(Graph)-1] := add(fktn(t,s), vctr(2, 2, 2)); Graph[high(Graph)] := add(fktn(t,s), vctr(3, 4, 0)); s := s + resfktn; until s > 2*Pi; t := t + resfktn; until t > PI; end; function TForm1.SpaceSysToPlaneSys(X: TVector): TVector; begin X := Sub(X, PlaneCenterPos); result := Vctr(T[1,1] * X.X + T[1,2] * X.Y + T[1,3] * X.Z, T[2,1] * X.X + T[2,2] * X.Y + T[2,3] * X.Z, T[3,1] * X.X + T[3,2] * X.Y + T[3,3] * X.Z); end; function TForm1.SpaceSysToPlaneSys2(X: TVector): TVector; begin X := Sub(X, Plane2CenterPos); result := Vctr(T2[1,1] * X.X + T2[1,2] * X.Y + T2[1,3] * X.Z, T2[2,1] * X.X + T2[2,2] * X.Y + T2[2,3] * X.Z, T2[3,1] * X.X + T2[3,2] * X.Y + T2[3,3] * X.Z); end; function TForm1.Cross(X, Y: TVector): TVector; begin result := Vctr(X.Y * Y.Z - X.Z * Y.Y, X.Z * Y.X - X.X * Y.Z, X.X * Y.Y - X.Y * Y.X); end; procedure TForm1.EFIChange(Sender: TObject); begin FormCreate(sender); DrawSet(sender); end; procedure TForm1.CreateBaseGrid(Sender: TObject); const bvlength = 20; arlength = 2; dotres = 0.1; var t: real; x,y,z : real; begin t := 0; repeat SetLength(Graph, length(Graph) + 1); Graph[high(Graph)] := Vctr(t, 0, 0); t := t + 0.04; until t > bvlength; t := 0; repeat SetLength(Graph, length(Graph) + 1); Graph[high(Graph)] := Vctr(0, t, 0); t := t + 0.04; until t > bvlength; t := 0; repeat SetLength(Graph, length(Graph) + 1); Graph[high(Graph)] := Vctr(0, 0, t); t := t + 0.04; until t > bvlength; end; procedure TForm1.cbDebugClick(Sender: TObject); begin FormCreate(sender); end; procedure TForm1.Button2Click(Sender: TObject); begin FormCreate(sender); DrawSet(sender); end; procedure TForm1.ECPXKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if (Key = VK_UP) and (Sender is TEdit) then with Sender as TEdit do Text := IntToStr(StrToInt(Text) + 1); if (Key = VK_DOWN) and (Sender is TEdit) then with Sender as TEdit do Text := IntToStr(StrToInt(Text) - 1); FormCreate(sender); DrawSet(sender); end; procedure TForm1.highresClick(Sender: TObject); begin SetLength(Graph, 0); FormCreate(sender); DrawSet(sender); end; procedure TForm1.ERESKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if key = vk_return then begin FormCreate(Sender); SetLength(Graph, 0); {20080329: del 2008-06-01 undel} CreateBaseGrid(Sender); {20080329:del *Param*} CreateFctnGraph(Sender); DrawSet(Sender); KeyPreview := true; Memo1.SetFocus; end; end; procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var intstep: integer; begin if ssCtrl in Shift then begin intstep := IfThen(ssShift in Shift, 1, 15); if ssAlt in Shift then begin if Key = VK_LEFT then ERO.Position := (360 + ERO.Position + intstep) mod 360; if Key = VK_RIGHT then ERO.Position := (360 + ERO.Position - intstep) mod 360; end else begin if Key = VK_LEFT then EFI.Position := (360 + EFI.Position - intstep) mod 360; if Key = VK_RIGHT then EFI.Position := (360 + EFI.Position + intstep) mod 360; if Key = VK_UP then ETH.Position := ETH.Position - intstep; if Key = VK_DOWN then ETH.Position := ETH.Position + intstep; end; end else begin intstep := IfThen(ssShift in Shift, 1, 5); if ssAlt in Shift then begin if Key = VK_UP then ECPZ.Text := IntToStr(StrToInt(ECPZ.Text) + intstep); if Key = VK_DOWN then ECPZ.Text := IntToStr(StrToInt(ECPZ.Text) - intstep); end else begin if Key = VK_LEFT then ECPY.Text := IntToStr(StrToInt(ECPY.Text) - intstep); if Key = VK_RIGHT then ECPY.Text := IntToStr(StrToInt(ECPY.Text) + intstep); if Key = VK_UP then ECPX.Text := IntToStr(StrToInt(ECPX.Text) - intstep); if Key = VK_DOWN then ECPX.Text := IntToStr(StrToInt(ECPX.Text) + intstep); end; end; if (Key = VK_LEFT) or (Key = VK_RIGHT) or (Key = VK_UP) or (Key = VK_DOWN) then begin FormCreate(Sender); DrawSet(Sender); end; end; procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); begin EZOOM.Position := EZOOM.Position - sign(WheelDelta); FormCreate(Sender); DrawSet(Sender); end; procedure TForm1.FormShow(Sender: TObject); begin { 20080329: del 20080601 undel } CreateBaseGrid(Sender); // 20080329: del CreateFctnParamGraph(Sender); ins following row: CreateFctnGraph(Sender); DrawSet(Sender); end; procedure TForm1.ERESEnter(Sender: TObject); begin KeyPreview := false; end; procedure TForm1.ERESExit(Sender: TObject); begin KeyPreview := true; end; end.