【问题标题】:Delphi Firemonkey draw and fill an arbitrary 3D shape or polygonDelphi Firemonkey 绘制和填充任意 3D 形状或多边形
【发布时间】:2016-01-13 09:05:42
【问题描述】:

我试图弄清楚如何使用 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,但是如果没有数学博士学位就很难弄清楚,我完全迷路了。任何帮助都会很棒。

【问题讨论】:

    标签: delphi 3d firemonkey


    【解决方案1】:

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

    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;
    

    希望这对某人、某处、某种方式有所帮助...

    【讨论】:

    • Rick,如果你能直观地看到你的答案,那就太棒了。 :)
    【解决方案2】:

    试试 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;
    

    【讨论】:

    • 谢谢,但这是我已经知道的 2D 画布。我需要弄清楚没有相同方法的 TContext3D。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 2015-01-12
    • 1970-01-01
    相关资源
    最近更新 更多