Delphi Firemonkey绘制并填充任意3D形状或多边形

时间:2016-01-13 09:05:42

标签: delphi 3d firemonkey

我试图弄清楚如何使用Delphi XE7 Firemonkey填充3D多边形。使用具有内置组件的GLScene之后,Firemonkey对我来说似乎对健康有害,因为内置的控件较少,样本很少,而且文档也很少。

我的多边形是使用以下代码生成的:

Context.BeginScene;
try
  Context.DrawLine(TPoint3D.Create(1, -1, 0), TPoint3D.Create(1, 1, 0), 0.5, TAlphaColorRec.Black);
  Context.DrawLine(TPoint3D.Create(1, 1, 0), TPoint3D.Create(0, 1, 0), 0.5, TAlphaColorRec.Black);
  Context.DrawLine(TPoint3D.Create(0, 1, 0), TPoint3D.Create(-1, 0.5, 0), 0.5, TAlphaColorRec.Black);
  Context.DrawLine(TPoint3D.Create(-1, 0.5, 0), TPoint3D.Create(-1, 0, 0), 0.5, TAlphaColorRec.Black);
  Context.DrawLine(TPoint3D.Create(-1, 0, 0), TPoint3D.Create(-0.5, 0, 0), 0.5, TAlphaColorRec.Black);
  Context.DrawLine(TPoint3D.Create(-0.5, 0, 0), TPoint3D.Create(-0.5, -1, 0), 0.5, TAlphaColorRec.Black);
  Context.DrawLine(TPoint3D.Create(-0.5, -1, 0), TPoint3D.Create(1, -1, 0), 0.5, TAlphaColorRec.Black);
finally
  Context.EndScene;
end;

此代码生成如下多边形:https://cyberflexsoftware.tinytake.com/sf/NDQ5NTIxXzI0MjgzNjg

但是我需要用颜色材料填充这个形状,我不知道如何做到这一点。我想我需要创建一个TMesh但很难在没有数学博士的情况下弄清楚,而且我完全迷失了。任何帮助都会很棒。

2 个答案:

答案 0 :(得分:0)

尝试使用TCanvas的FillPolyton方法:http://docwiki.embarcadero.com/Libraries/XE7/en/FMX.Graphics.TCanvas.FillPolygon

示例:

var
  p1, p2, p3, p4, p5: TPointF;
  MyPolygon: TPolygon;
begin
 Image1.Bitmap.Clear($FFFFFF);
  // sets the points that define the polygon
  p1 := TPointF.Create(210, 220);
  p2 := TPointF.Create(330, 360);
  p3 := TPointF.Create(380, 260);
  p4 := TPointF.Create(200, 180);
  p5 := TPointF.Create(140, 160);
  // creates the polygon
  SetLength(MyPolygon, 5);
  MyPolygon[0] := p1;
  MyPolygon[1] := p2;
  MyPolygon[2] := p3;
  MyPolygon[3] := p4;
  MyPolygon[4] := p5;
  // fills and draws the polygon on the canvas
  Image1.Bitmap.Canvas.BeginScene;
  Image1.Bitmap.Canvas.FillPolygon(MyPolygon, 50);
  Image1.Bitmap.Canvas.EndScene;

答案 1 :(得分:0)

经过一番挖掘和玩耍后,我想出了这个解决方案:

procedure TForm1.DummyObjectRender(Sender: TObject; Context: TContext3D);
var
  MyPolygon: TPolygon;
  I: Integer;
begin
  Context.BeginScene;
  try

    // creates the polygon
    SetLength(MyPolygon, 8);

    MyPolygon[0] := TPointF.Create(1, -1);
    MyPolygon[1] := TPointF.Create(1, 1);
    MyPolygon[2] := TPointF.Create(0, 1);
    MyPolygon[3] := TPointF.Create(-1, 0.5);
    MyPolygon[4] := TPointF.Create(-1, 0);
    MyPolygon[5] := TPointF.Create(-0.5, 0);
    MyPolygon[6] := TPointF.Create(-0.5, -1);
    MyPolygon[7] := TPointF.Create(1, -1);

    // Draw the polygon lines
    for I := 0 to Length(MyPolygon) - 1 do
      if I = Length(MyPolygon) - 1 then
        Context.DrawLine(TPoint3D.Create(MyPolygon[I].X, MyPolygon[I].Y, 0),
          TPoint3D.Create(MyPolygon[0].X, MyPolygon[0].Y, 0), 1, TAlphaColorRec.Red)
      else
        Context.DrawLine(TPoint3D.Create(MyPolygon[I].X, MyPolygon[I].Y, 0),
          TPoint3D.Create(MyPolygon[I + 1].X, MyPolygon[I + 1].Y, 0), 1, TAlphaColorRec.Red);

    // Fill the polygon shape
    Context.FillPolygon(TPoint3D.Create(0, 0, 0), TPoint3D.Create(2, 2, 0), MyPolygon.MaxEntents, MyPolygon,
      TMaterialSource.ValidMaterial(ColorMaterialSource1), 1);

  finally
    Context.EndScene;
  end;

end;

我还为多边形的MaxEntents创建了一个Polygon Helper:

TPolygonHelper = record helper for TPolygon
  function MaxEntents: TRectF;
end;

{ TPolygonHelper }

function TPolygonHelper.MaxEntents: TRectF;
var
  I: Integer;
begin
  for I := 0 to Length(Self) - 1 do
  begin
    Result.Left := Min(Result.Left, Self[I].X);
    Result.Right := Max(Result.Right, Self[I].X);
    Result.Top := Max(Result.Top, Self[I].Y);
    Result.Bottom := Min(Result.Bottom, Self[I].Y);
  end;

end;

希望这能帮助某个人,不管怎么说......