我遇到了小问题
想象一下两件事:形式,应该涵盖 - 封面形式;和表格将涵盖封面 - 瓷砖。
我的主要目标是用瓷砖覆盖我的封面。所以它看起来像瓷砖。我用下面的图片说明了这个想法
黄色是封面形式,棕色形式 - 瓷砖。在此图像上,您可以看到表单彼此之间的距离太近 - 它们之间没有自由空间。这就是我需要的。
但是当我试图达到同样的效果时,我得到的结果并不令人满意。如下图所示
第二个图像在最后一个图块之后有一个偏移。这是因为形式的大小不同。我不确切知道Cover-Form的宽度是多少。我简单地将Cover-Form的整个宽度分成三部分。但是如果Cover-Form有宽度,例如173像素,我的每个Tiles的宽度将等于173/3 = 57.6像素,这将是圆形到58,但是58 * 3 = 174并且它很糟糕。
以下代码在第二张图像上运行情况。
type
TTileArray = Array of Array of TPoint;
// This routine comes here from David's answer below and were changed by me
procedure EvenlySpacedTiles(PixelCountH, PixelCountV, TileCount: Integer; var ArrayOut: TTileArray);
var
X: Integer;
Y: Integer;
OldH: Integer;
OldV: Integer;
OldCount: Integer;
OldCount1: Integer;
TempInt: Integer;
begin
if (PixelCountH) or (PixelCountV) or(TileCount) = 0 then
Exit;
OldH := PixelCountH;
OldCount1 := TileCount;
for X:=Low(ArrayOut) to High(ArrayOut) do
begin
OldV := PixelCountV;
OldCount := TileCount;
TempInt := OldH div OldCount1;
Dec(OldH, TempInt);
Dec(OldCount1);
for Y:=Low(ArrayOut) to High(ArrayOut) do
begin
ArrayOut[X, Y] := Point(TempInt, OldV div OldCount);
Dec(OldV, ArrayOut[X, Y].Y);
Dec(OldCount);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
F: TForm;
P: TForm;
Delta: Integer;
PrevLeft: Integer;
PrevTop: Integer;
X:Integer;
Y: Integer;
Arr: TTileArray;
IncLeft: Integer;
begin
Delta := 3;
F := TForm.Create(Application);
F.BorderStyle := Forms.bsNone;
F.SetBounds(0, 0, 173, 115);
F.Position := poDesktopCenter;
F.Color := $11DFEE;
F.Show;
SetLength(Arr, Delta, Delta);
EvenlySpacedTiles(F.Width, F.Height, Delta, Arr);
PrevLeft := F.Left;
PrevTop := F.Top;
IncLeft := 0;
for X:=Low(Arr) to High(Arr) do
begin
PrevTop := F.Top;
Inc(PrevLeft, IncLeft);
for Y:=Low(Arr) to High(Arr) do
begin
P := TForm.Create(Application);
P.FormStyle := fsStayOnTop;
P.BorderStyle := Forms.bsNone;
P.Color := Random($FFFFFF);//clSkyBlue;
P.Show;
P.Width := Arr[X, Y].X;
P.Height := Arr[X, Y].Y;
P.Left := PrevLeft;
P.Top := PrevTop;
P.Canvas.Rectangle(P.ClientRect);
Inc(PrevTop, Arr[X, Y].y);
IncLeft := Arr[X, Y].X;
end;
end;
end;
所以我的问题是:如何调整所有瓷砖的宽度(每行3个),与封面形式的宽度无关?
提前致谢。
已修改
P.S。 我修改了上面代码的一些部分。现在它可以完美地工作,即使是极小和大的Cover-Form宽度 - 从67像素。到1237像素。 当然有一种方法可以改进这个代码,但主要目标是实现的。 我想我明天可以完成垂直瓷砖的放置并在那里发布这个部分 在许多方面,大卫的评论让我知道如何做到这一点。谢谢你,大卫!
P.S.S。
我已经在对角线上阅读了David的第一条评论,所以我更新代码以另一种方式工作,但结果仍然不好。您可以在下面的图片中看到它
第一块瓷砖有57像素。宽度;第二个--59像素。第三个瓷砖 - 仅31 px
我只是无法使用David的评论中建议的算法来正确放置Tiles。
P.S.S.S。
再没有结果
右侧红线表示最后一块瓷砖的大尺寸。每个瓷砖的宽度为58像素
大卫写道:
3分之173= 58。 173-58 = 115。 2分之115= 58。 115-58 = 57。 57/1 = 57
我能够在现实生活中计算它,但我无法在代码中实现它 源代码已更新。
P.S.S.S.S。
大卫的程序没有做它应该做的事情。下图说明了它
第一个和第二个Tile之间有一个间隙,右侧的红色线与前一个图片之间有一个间隙。
P.S.S.S.S.S。
那么,此时我的任务的第一部分已经完成。第二个 - 添加更多瓷砖,但我不确定我是否真的需要它们。我感谢David Heffernan !!他花了很多时间向我解释一些事情,我不知道如何更多地说出他而不是“非常感谢你”。我担心,我能够提高他的声誉并接受他的帖子作为答案。它确实做到了!
在图片上,我们可以看到我需要的结果
答案 0 :(得分:3)
我会使用这样一个简单的算法:
function EvenlySpacedColumns(PixelCount, ColumnCount: Integer): TArray<Integer>;
var
i: Integer;
begin
Assert(PixelCount>0);
Assert(ColumnCount>0);
SetLength(Result, ColumnCount);
for i := low(Result) to high(Result) do begin
Result[i] := PixelCount div ColumnCount;
dec(PixelCount, Result[i]);
dec(ColumnCount);
end;
end;
这里我使用的div
实际上使用了除法后截断。但如果您愿意,也可以使用Round(PixelCount / ColumnCount)
。它有点武断,所以我个人会选择整数运算,理由是如果没有必要,应该避免浮点运算。