如何用for循环绘制正方形与三角形?能否点击顶点旋转三角形?
问题解答
一、用For循环实现图形绘制
把图形的顶点坐标存入数组,通过循环遍历数组完成绘制,代码更简洁易维护:
1. 正方形绘制(For循环版)
procedure squarClick(Sender: TObject); var SquarePoints: array[0..3] of TPoint; i: Integer; begin // 定义正方形四个顶点坐标 SquarePoints[0] := Point(164, 182); SquarePoints[1] := Point(390, 118); SquarePoints[2] := Point(455, 345); SquarePoints[3] := Point(228, 408); // 设置画笔属性 Canvas.Pen.Color := clGreen; Canvas.Pen.Style := psSolid; Canvas.Pen.Width := 1; // 移动到第一个顶点 Canvas.MoveTo(SquarePoints[0].X, SquarePoints[0].Y); // 循环绘制各边 for i := 1 to High(SquarePoints) do begin Canvas.LineTo(SquarePoints[i].X, SquarePoints[i].Y); end; // 闭合图形,回到起点 Canvas.LineTo(SquarePoints[0].X, SquarePoints[0].Y); end;
2. 三角形绘制(For循环版)
procedure TRIANGLEClick(Sender: TObject); var TrianglePoints: array[0..2] of TPoint; i: Integer; begin // 定义三角形三个顶点坐标 TrianglePoints[0] := Point(164, 182); TrianglePoints[1] := Point(453, 176); TrianglePoints[2] := Point(310, 428); // 设置画笔属性 Canvas.Pen.Color := clRed; Canvas.Pen.Width := 1; // 移动到第一个顶点 Canvas.MoveTo(TrianglePoints[0].X, TrianglePoints[0].Y); // 循环绘制各边 for i := 1 to High(TrianglePoints) do begin Canvas.LineTo(TrianglePoints[i].X, TrianglePoints[i].Y); end; // 闭合图形 Canvas.LineTo(TrianglePoints[0].X, TrianglePoints[0].Y); end;
二、点击三角形顶点实现旋转操作
可以实现,步骤如下:
1. 定义全局状态变量
在窗体类中添加全局变量,存储三角形顶点、旋转中心和角度:
type TForm1 = class(TForm) PaintBox1: TPaintBox; TRIANGLEBtn: TButton; // 其他组件声明 private TrianglePoints: array[0..2] of TPoint; RotateCenter: TPoint; // 旋转中心(点击的顶点) RotateAngle: Double; // 旋转角度(弧度制) function IsPointNearVertex(const P: TPoint; const Vertex: TPoint): Boolean; public { Public declarations } end;
2. 实现顶点点击判断函数
添加辅助函数,判断鼠标点击位置是否靠近顶点(容错范围10像素):
function TForm1.IsPointNearVertex(const P: TPoint; const Vertex: TPoint): Boolean; const Tolerance = 10; begin Result := (Abs(P.X - Vertex.X) <= Tolerance) and (Abs(P.Y - Vertex.Y) <= Tolerance); end;
3. 处理PaintBox点击事件
在OnMouseDown事件中识别点击的顶点,设置旋转参数并触发重绘:
procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var i: Integer; begin if Button = mbLeft then begin for i := 0 to High(TrianglePoints) do begin if IsPointNearVertex(Point(X, Y), TrianglePoints[i]) then begin RotateCenter := TrianglePoints[i]; RotateAngle := 30 * Pi / 180; // 每次顺时针转30度,转为弧度 RotateTriangle(); PaintBox1.Invalidate; Break; end; end; end; end;
4. 实现旋转计算函数
用二维旋转公式计算旋转后的顶点坐标:
procedure TForm1.RotateTriangle; var i: Integer; dx, dy: Double; newX, newY: Double; begin for i := 0 to High(TrianglePoints) do begin // 计算顶点相对旋转中心的偏移量 dx := TrianglePoints[i].X - RotateCenter.X; dy := TrianglePoints[i].Y - RotateCenter.Y; // 应用旋转公式 newX := dx * Cos(RotateAngle) - dy * Sin(RotateAngle) + RotateCenter.X; newY := dx * Sin(RotateAngle) + dy * Cos(RotateAngle) + RotateCenter.Y; // 更新顶点坐标 TrianglePoints[i] := Point(Round(newX), Round(newY)); end; end;
5. 修改绘制逻辑
更新三角形初始化和PaintBox绘制事件,使用全局顶点数组:
procedure TForm1.TRIANGLEClick(Sender: TObject); begin // 初始化三角形顶点 TrianglePoints[0] := Point(164, 182); TrianglePoints[1] := Point(453, 176); TrianglePoints[2] := Point(310, 428); PaintBox1.Invalidate; end; procedure TForm1.PaintBox1Paint(Sender: TObject); var i: Integer; begin // 绘制当前状态的三角形 Canvas.Pen.Color := clRed; Canvas.Pen.Width := 1; Canvas.MoveTo(TrianglePoints[0].X, TrianglePoints[0].Y); for i := 1 to High(TrianglePoints) do begin Canvas.LineTo(TrianglePoints[i].X, TrianglePoints[i].Y); end; Canvas.LineTo(TrianglePoints[0].X, TrianglePoints[0].Y); end;
现在点击三角形任意顶点,图形就会以该顶点为中心顺时针旋转30度。
内容的提问来源于stack exchange,提问作者Ebrahim
相关产品推荐
相关产品推荐

