📄 graphwin.pas.~93~
字号:
unit GraphWin;
interface
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs,
Buttons, ExtCtrls, StdCtrls, ComCtrls, Menus, Jpeg, StereoImg,
CustomizeDlg, ExtDlgs, BuildStaticModel;
type
// 程序启动后默认取值为dtLine
TDrawingTool = (dtNull, dtLine, dtRectangle, dtEllipse, dtRoundRect);
T3DPoint = record
X: Real; // 世界坐标系中的坐标
Y: Real; // 世界坐标系中的坐标
Z: Real; // 世界坐标系中的坐标
// 立体图像对I1的坐标
I1X: Integer;
I1Y: Integer;
// 立体图像对I2的坐标
I2X: Integer;
I2Y: Integer;
end;
TCube = record
// 立方体的中心坐标
cX: Real;
cY: Real;
cZ: Real;
hLen: Real; // 半边长
vertex: array[0..7] of T3DPoint; // 定义立方体的八个顶点
end;
TForm1 = class(TForm)
Panel1: TPanel;
LineButton: TSpeedButton;
RectangleButton: TSpeedButton;
EllipseButton: TSpeedButton;
RoundRectButton: TSpeedButton;
PenButton: TSpeedButton;
BrushButton: TSpeedButton;
PenBar: TPanel;
BrushBar: TPanel;
SolidPen: TSpeedButton;
DashPen: TSpeedButton;
DotPen: TSpeedButton;
DashDotPen: TSpeedButton;
DashDotDotPen: TSpeedButton;
ClearPen: TSpeedButton;
PenWidth: TUpDown;
PenSize: TEdit;
StatusBar1: TStatusBar;
ScrollBox1: TScrollBox;
Image: TImage;
SolidBrush: TSpeedButton;
ClearBrush: TSpeedButton;
HorizontalBrush: TSpeedButton;
VerticalBrush: TSpeedButton;
FDiagonalBrush: TSpeedButton;
BDiagonalBrush: TSpeedButton;
CrossBrush: TSpeedButton;
DiagCrossBrush: TSpeedButton;
PenColor: TSpeedButton;
BrushColor: TSpeedButton;
ColorDialog1: TColorDialog;
MainMenu1: TMainMenu;
File1: TMenuItem;
New1: TMenuItem;
Open1: TMenuItem;
Save1: TMenuItem;
Saveas1: TMenuItem;
N1: TMenuItem;
Exit1: TMenuItem;
Edit1: TMenuItem;
Cut1: TMenuItem;
Copy1: TMenuItem;
Paste1: TMenuItem;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
miStereo: TMenuItem;
miCube: TMenuItem;
miProc: TMenuItem;
mi2DTo3D: TMenuItem;
StereoImg: TStereoImg;
miCrossEntropy: TMenuItem;
ComboBox1: TComboBox;
MoveRight1: TMenuItem;
MoveLeft1: TMenuItem;
MoveRight21: TMenuItem;
miMergeJPS: TMenuItem;
OpenPicDlg: TOpenPictureDialog;
miMAXScript: TMenuItem;
miCreateScript: TMenuItem;
HandButton: TSpeedButton;
miConvert: TMenuItem;
miMove: TMenuItem;
procedure miMoveClick(Sender: TObject);
procedure HandButtonClick(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure LineButtonClick(Sender: TObject);
procedure RectangleButtonClick(Sender: TObject);
procedure EllipseButtonClick(Sender: TObject);
procedure RoundRectButtonClick(Sender: TObject);
procedure PenButtonClick(Sender: TObject);
procedure BrushButtonClick(Sender: TObject);
procedure SetPenStyle(Sender: TObject);
procedure PenSizeChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure SetBrushStyle(Sender: TObject);
procedure PenColorClick(Sender: TObject);
procedure BrushColorClick(Sender: TObject);
procedure Exit1Click(Sender: TObject);
procedure Open1Click(Sender: TObject);
procedure Save1Click(Sender: TObject);
procedure Saveas1Click(Sender: TObject);
procedure New1Click(Sender: TObject);
procedure Copy1Click(Sender: TObject);
procedure Cut1Click(Sender: TObject);
procedure Paste1Click(Sender: TObject);
procedure miCubeClick(Sender: TObject);
procedure mi2DTo3DClick(Sender: TObject);
procedure ComboBox1Change(Sender: TObject);
procedure MoveRight1Click(Sender: TObject);
procedure MoveLeft1Click(Sender: TObject);
procedure MoveRight21Click(Sender: TObject);
procedure miMergeJPSClick(Sender: TObject);
procedure miCreateScriptClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
BrushStyle: TBrushStyle;
PenStyle: TPenStyle;
PenWide: Integer;
Drawing: Boolean;
Origin, MovePt: TPoint;
W, U: T3DPoint; // 立体直线的两个端点
Pd, Od: Real; // Pd>0是正视差,pd<0是负视差
DrawingTool: TDrawingTool;
CurrentFile: string;
procedure SaveStyles;
procedure RestoreStyles;
procedure DrawShape(TopLeft, BottomRight: TPoint; AMode: TPenMode);
end;
var
Form1: TForm1;
sCube: TCube;
index: Integer;
implementation
uses BMPDlg, Clipbrd, unParaSet, unCrossEntropy, unRanVar;
{$R *.dfm}
const
h = 3.25;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Drawing := True; // 绘图
Image.Canvas.MoveTo(X, Y); // 画笔移到鼠标处
Origin := Point(X, Y); // 记录下当前点作为起始点
MovePt := Origin; // 记录下当前点作为目标点
StatusBar1.Panels[0].Text := Format('Origin: (%d, %d)', [X, Y]);
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Drawing then
begin
DrawShape(Origin, Point(X, Y), pmCopy);
Drawing := False;
end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if Drawing then
begin
// 画图
DrawShape(Origin, MovePt, pmNotXor);
MovePt := Point(X, Y); // 记录下当前点作为目标点
DrawShape(Origin, MovePt, pmNotXor);
end;
StatusBar1.Panels[1].Text := Format('Current: (%d, %d)', [X, Y]);
end;
procedure TForm1.LineButtonClick(Sender: TObject);
begin
DrawingTool := dtLine;
end;
procedure TForm1.RectangleButtonClick(Sender: TObject);
begin
DrawingTool := dtRectangle;
end;
procedure TForm1.EllipseButtonClick(Sender: TObject);
begin
DrawingTool := dtEllipse;
end;
procedure TForm1.RoundRectButtonClick(Sender: TObject);
begin
DrawingTool := dtRoundRect;
end;
procedure TForm1.DrawShape(TopLeft, BottomRight: TPoint; AMode: TPenMode);
begin
with Image.Canvas do
begin
Pen.Mode := AMode;
case DrawingTool of
dtLine:
begin
Image.Canvas.MoveTo(TopLeft.X, TopLeft.Y);
Image.Canvas.LineTo(BottomRight.X, BottomRight.Y);
end;
dtRectangle: Image.Canvas.Rectangle(TopLeft.X, TopLeft.Y, BottomRight.X,
BottomRight.Y);
dtEllipse: Image.Canvas.Ellipse(TopLeft.X, TopLeft.Y, BottomRight.X,
BottomRight.Y);
dtRoundRect: Image.Canvas.RoundRect(TopLeft.X, TopLeft.Y, BottomRight.X,
BottomRight.Y, (TopLeft.X - BottomRight.X) div 2,
(TopLeft.Y - BottomRight.Y) div 2);
end;
end;
end;
procedure TForm1.PenButtonClick(Sender: TObject);
begin
PenBar.Visible := PenButton.Down;
end;
procedure TForm1.BrushButtonClick(Sender: TObject);
begin
BrushBar.Visible := BrushButton.Down;
end;
procedure TForm1.SetPenStyle(Sender: TObject);
begin
with Image.Canvas.Pen do
begin
if Sender = SolidPen then
Style := psSolid
else
if Sender = DashPen then
Style := psDash
else
if Sender = DotPen then
Style := psDot
else
if Sender = DashDotPen then
Style := psDashDot
else
if Sender = DashDotDotPen then
Style := psDashDotDot
else
if Sender = ClearPen then
Style := psClear;
end;
end;
procedure TForm1.PenSizeChange(Sender: TObject);
begin
Image.Canvas.Pen.Width := PenWidth.Position;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
Bitmap: TBitmap;
begin
Bitmap := nil; // 先初始化为空
try
Bitmap := TBitmap.Create;
Bitmap.Width := 1600; // 两幅800*600
Bitmap.Height := 600;
Image.Picture.Graphic := Bitmap;
finally
Bitmap.Free;
end;
end;
procedure TForm1.SetBrushStyle(Sender: TObject);
begin
with Image.Canvas.Brush do
begin
if Sender = SolidBrush then
Style := bsSolid
else
if Sender = ClearBrush then
Style := bsClear
else
if Sender = HorizontalBrush then
Style := bsHorizontal
else
if Sender = VerticalBrush then
Style := bsVertical
else
if Sender = FDiagonalBrush then
Style := bsFDiagonal
else
if Sender = BDiagonalBrush then
Style := bsBDiagonal
else
if Sender = CrossBrush then
Style := bsCross
else
if Sender = DiagCrossBrush then
Style := bsDiagCross;
end;
end;
procedure TForm1.PenColorClick(Sender: TObject);
begin
ColorDialog1.Color := Image.Canvas.Pen.Color;
if ColorDialog1.Execute then
Image.Canvas.Pen.Color := ColorDialog1.Color;
end;
procedure TForm1.BrushColorClick(Sender: TObject);
begin
ColorDialog1.Color := Image.Canvas.Brush.Color;
if ColorDialog1.Execute then
Image.Canvas.Brush.Color := ColorDialog1.Color;
end;
procedure TForm1.Exit1Click(Sender: TObject);
begin
Close;
end;
procedure TForm1.Open1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
CurrentFile := OpenDialog1.FileName;
SaveStyles;
Image.Picture.LoadFromFile(CurrentFile);
RestoreStyles;
end;
end;
procedure TForm1.Save1Click(Sender: TObject);
var
MYJPEG: TJPEGImage;
begin
if CurrentFile <> EmptyStr then
if Pos('.jps', CurrentFile) <> 0 then
begin
MYJPEG := TJPEGImage.Create;
with MYJPEG do
begin
Assign(Image.Picture.Bitmap);
SaveToFile(CurrentFile); // 保存路径
Free;
end
end
else
Image.Picture.SaveToFile(CurrentFile) // 具体执行保存过程
else
Saveas1Click(Sender);
end;
procedure TForm1.Saveas1Click(Sender: TObject);
begin
if SaveDialog1.Execute then
begin
CurrentFile := SaveDialog1.FileName;
Save1Click(Sender);
end;
end;
procedure TForm1.New1Click(Sender: TObject);
var
Bitmap: TBitmap;
begin
NewBMPForm := TNewBMPForm.Create(Self);
with NewBMPForm do
begin
ActiveControl := WidthEdit;
WidthEdit.Text := IntToStr(Image.Picture.Graphic.Width);
HeightEdit.Text := IntToStr(Image.Picture.Graphic.Height);
if ShowModal <> idCancel then
begin
Bitmap := nil;
try
Bitmap := TBitmap.Create;
Bitmap.Width := StrToInt(WidthEdit.Text);
Bitmap.Height := StrToInt(HeightEdit.Text);
SaveStyles;
Image.Picture.Graphic := Bitmap;
RestoreStyles;
CurrentFile := EmptyStr;
finally
Bitmap.Free;
end;
end;
end;
NewBMPForm.Free;
end;
procedure TForm1.Copy1Click(Sender: TObject);
begin
Clipboard.Assign(Image.Picture);
end;
procedure TForm1.Cut1Click(Sender: TObject);
var
ARect: TRect;
begin
Copy1Click(Sender);
with Image.Canvas do
begin
CopyMode := cmWhiteness;
ARect := Rect(0, 0, Image.Width, Image.Height);
CopyRect(ARect, Image.Canvas, ARect);
CopyMode := cmSrcCopy;
end;
end;
procedure TForm1.Paste1Click(Sender: TObject);
var
Bitmap: TBitmap;
begin
if Clipboard.HasFormat(CF_BITMAP) then
begin
Bitmap := TBitmap.Create;
try
Bitmap.Assign(Clipboard);
Image.Canvas.Draw(0, 0, Bitmap);
finally
Bitmap.Free;
end;
end;
end;
procedure TForm1.SaveStyles;
begin
with Image.Canvas do
begin
BrushStyle := Brush.Style;
PenStyle := Pen.Style;
PenWide := Pen.Width;
end;
end;
procedure TForm1.RestoreStyles;
begin
with Image.Canvas do
begin
Brush.Style := BrushStyle;
Pen.Style := PenStyle;
Pen.Width := PenWide;
end;
end;
{ 这个过程实现将点的世界坐标系转换为图像坐标系,即计算点的立体图像对 }
procedure ConvertWCSToICS(vPd (*屏幕到眼睛所在平面的距离*): Real; var
p3D: T3DPoint);
begin
// 算点p3D的立体图像对的坐标
with p3D do
begin
I1X := Round(((X - h) * vPd / Z) * 28.35 + 1293.14);
// 1293.14 = 400 +800 + 3.25 * 28.35
I1Y := Round((Y * vPd / Z) * 28.35 + 300);
I2X := Round(((X + h) * vPd / Z) * 28.35 + 307.86);
// 400 - 3.25 * 28.35 = 307.86
I2Y := I1Y;
end;
end;
procedure DrawLine(var s3D, d3D: T3DPoint);
begin
// 绘制s3D的I2和I1,绘成圆,外接正方形边长为4个像素
with Form1.Image.Canvas do
begin
with s3D do
begin
Ellipse(I2X - 2, I2Y - 2, I2X + 2, I2Y + 2);
// 左眼看到的点I2,绘制在左图
Ellipse(I1X - 2, I1Y - 2, I1X + 2, I1Y + 2);
// 右眼看到的点I1,绘制在右图
end;
// 绘制d3D的I2和I1,绘成圆,外接正方形边长为4个像素
with d3D do
begin
Ellipse(I2X - 2, I2Y - 2, I2X + 2, I2Y + 2);
// 左眼看到的点I2,绘制在左图
Ellipse(I1X - 2, I1Y - 2, I1X + 2, I1Y + 2);
// 右眼看到的点I1,绘制在右图
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -