Какова цель переменной StepSize в TStrokeBuilder.BuildSolidPolygon? - PullRequest
2 голосов
/ 25 апреля 2020

У меня проблема, под движком GPU (то есть под android / ios) мы не можем нарисовать Ar c (Canvas.DrawAr c) с углом, который меньше толщины его хода. это проблема, особенно если у вас большая толщина хода. Поэтому я смотрю исходный код delphi и код функции TStrokeBuilder.BuildSolidPolygon:

procedure TStrokeBuilder.BuildSolidPolygon(const Points: TPolygon; const Opacity: Single; BreakAtEnd: Boolean);
var
  StepSize, Distance: Single;
  CurScale, SrcPos, DestPos, PieceDirVec, ThickPerp: TPointF;
  SrcPosValid, DestPosValid, PrevVerticesPlaced: Boolean;
  CurIndex: Integer;
begin
  if Length(Points) < 2 then
  begin
    InitArrays(0, 0);
    Exit;
  end;

  CurScale := GetMatrixScale;

  FThickness := FBrush.Thickness * (CurScale.X + CurScale.Y) * 0.5;
  FHalfThickness := FThickness * 0.5;
  FStrokeColor := PremultiplyAlpha(MakeColor(FBrush.Color, Opacity));

  FUndeterminedMode := True;
  InitArrayPointers;

  StepSize := FThickness;
  if StepSize < 2 then
    StepSize := 2;

  CurIndex := 0;

  SrcPosValid := False;
  DestPosValid := False;
  PrevVerticesPlaced := False;

  while CurIndex < Length(Points) do
  begin
    if (CurIndex >= Length(Points) - 1) and BreakAtEnd and (Points[0] <> Points[Length(Points) - 1]) then
      Break;

    if not SrcPosValid then
    begin
      SrcPos := Points[CurIndex];

      if (SrcPos.X >= $FFFF) or (SrcPos.Y >= $FFFF) then
      begin
        DestPosValid := False;
        PrevVerticesPlaced := False;
        Inc(CurIndex);
        Continue;
      end;

      SrcPos := SrcPos * FMatrix;
    end
    else
      SrcPosValid := False;

    if not DestPosValid then
    begin
      DestPos := Points[(CurIndex + 1) mod Length(Points)];

      if (DestPos.X >= $FFFF) or (DestPos.Y >= $FFFF) then
      begin
        DestPos := Points[CurIndex];
        if (DestPos.X >= $FFFF) or (DestPos.Y >= $FFFF) then
        begin
          PrevVerticesPlaced := False;
          Inc(CurIndex);
          Continue;
        end;

        DestPos := DestPos * FMatrix;
      end
      else
        DestPos := DestPos * FMatrix;
    end
    else
      DestPosValid := False;

    Distance := DestPos.Distance(SrcPos);

    if Distance >= StepSize then
    begin
      PieceDirVec := (DestPos - SrcPos).Normalize;
      ThickPerp := TPointF.Create(-PieceDirVec.Y, PieceDirVec.X) * FHalfThickness;

      InsertVertex(SrcPos - ThickPerp, FStrokeColor);
      InsertVertex(SrcPos + ThickPerp, FStrokeColor);

      if PrevVerticesPlaced then
      begin
        InsertIndex(FCurrentVertex - 3);
        InsertIndex(FCurrentVertex - 1);
        InsertIndex(FCurrentVertex - 2);

        InsertIndex(FCurrentVertex - 2);
        InsertIndex(FCurrentVertex - 4);
        InsertIndex(FCurrentVertex - 3);
      end;

      PrevVerticesPlaced := True;

      SrcPos := SrcPos + (PieceDirVec * StepSize);

      SrcPosValid := True;
      DestPosValid := True;
      Continue;
    end;

    if ((CurIndex < Length(Points) - 2) and (Points[CurIndex + 1].X < $FFFF) and (Points[CurIndex + 1].Y < $FFFF) and
      (Points[CurIndex + 2].X < $FFFF) and (Points[CurIndex + 2].Y < $FFFF) and
      (Points[CurIndex + 1].Distance(Points[CurIndex + 2]) > StepSize)) then
    begin
      PieceDirVec := (DestPos - SrcPos).Normalize;
      ThickPerp := TPointF.Create(-PieceDirVec.Y, PieceDirVec.X) * FHalfThickness;

      InsertVertex(DestPos - ThickPerp, FStrokeColor);
      InsertVertex(DestPos + ThickPerp, FStrokeColor);

      if PrevVerticesPlaced then
      begin
        InsertIndex(FCurrentVertex - 3);
        InsertIndex(FCurrentVertex - 1);
        InsertIndex(FCurrentVertex - 2);

        InsertIndex(FCurrentVertex - 2);
        InsertIndex(FCurrentVertex - 4);
        InsertIndex(FCurrentVertex - 3);
      end;

      if CurIndex < Length(Points) - 1 then
      begin
        Inc(CurIndex);
        Continue;
      end
      else
        Break;
    end;

    if (CurIndex = Length(Points) - 1) or (Points[CurIndex + 1].X >= $FFFF) or (Points[CurIndex + 1].Y >= $FFFF) then
    begin
      PieceDirVec := (DestPos - SrcPos).Normalize;
      ThickPerp := TPointF.Create(-PieceDirVec.Y, PieceDirVec.X) * FHalfThickness;

      InsertVertex(DestPos - ThickPerp, FStrokeColor);
      InsertVertex(DestPos + ThickPerp, FStrokeColor);

      if PrevVerticesPlaced then
      begin
        InsertIndex(FCurrentVertex - 3);
        InsertIndex(FCurrentVertex - 1);
        InsertIndex(FCurrentVertex - 2);

        InsertIndex(FCurrentVertex - 2);
        InsertIndex(FCurrentVertex - 4);
        InsertIndex(FCurrentVertex - 3);
      end;

      PrevVerticesPlaced := False;

      if CurIndex < Length(Points) - 1 then
      begin
        Inc(CurIndex);
        Continue;
      end
      else
        Break;
    end;

    SrcPosValid := True;
    Inc(CurIndex);
  end;

  FinalizeArrays;
end;

Что я не понимаю, почему они это сделали:

if StepSize < 2 then
  StepSize := 2;

Почему 2 а не 1? Даже не совсем понимаю назначение переменной StepSize ...

...