我畫了一條由兩條線組成的路徑,向上然后回到同一個點,或者幾乎是同一個點,但是第一條線畫得太高了。如果我然后使用 DrawLine 繪制相同的線,我看不到問題。為什么會這樣?
下面是一個例子。只需將 400x400 TImage 放在空白的多平臺表單上即可。該代碼繪制了 2 條紅色路徑,一條線之間的夾角接近 180 度,另一條線之間的夾角較小。然后使用藍色的 DrawLine 繪制相同的線條。如果 DrawPath 函式正常作業,那么藍線應該完全覆寫紅線,但它們不會。在這個比例為 1.5 的示例中,路徑比第一條路徑高 7 個像素。隨著線之間的距離越來越遠,誤差的程度會減小。比例為 1 時仍會出現此問題,但不太明顯。
procedure TForm1.FormActivate(Sender: TObject);
var
LPath1, LPath2 : TPathData;
i : Integer;
begin
// A path of 2 lines going up and then back down to almost the same spot
LPath1 := TPathData.Create;
LPath1.MoveTo(PointF(100,200));
LPath1.LineTo(PointF(100,50 ));
LPath1.LineTo(PointF(105,200));
// A path of 2 lines going up and then back down at a wider angle
LPath2 := TPathData.Create;
LPath2.MoveTo(PointF(200,200));
LPath2.LineTo(PointF(200,50 ));
LPath2.LineTo(PointF(260,200));
Image1.Bitmap.BitmapScale := 1.5; // The issue shows up more at larger scales
Image1.Bitmap.SetSize(Trunc(Image1.Width), Trunc(Image1.Height));
with Image1.Bitmap.Canvas do if BeginScene then begin
Clear(TAlphaColorRec.White);
// Draw the paths using DrawPath in red
Stroke.Color := TAlphaColorRec.Red;
Stroke.Thickness := 1;
DrawPath(LPath1, 1);
DrawPath(LPath2, 1);
// Draw the paths using DrawLine in blue over the top
// The red lines should be completely hidden under the blue
Stroke.Color := TAlphaColorRec.Blue;
for i := 1 to LPath1.Count - 1 do
DrawLine(LPath1.Points[i-1].Point, LPath1.Points[i].Point, 1);
for i := 1 to LPath2.Count - 1 do
DrawLine(LPath2.Points[i-1].Point, LPath2.Points[i].Point, 1);
EndScene;
end;
LPath1.Free;
LPath2.Free;
Image1.Bitmap.SaveToFile('test.png');
end;
在 Windows 10 中運行時的代碼結果。我使用的是 Delphi 11,但 Delphi 10 也出現了同樣的問題。我嘗試切換 GPU,但出現了同樣的問題。

放大圖:

uj5u.com熱心網友回復:
我得出的結論是,這根本不是故障。這是因為 TCanvas.Stroke.Join 的默認設定是 TStrokeJoin.Miter。看到的人工制品只是斜接角的尖刺。在構建路徑時在每個線段之前使用 MoveTo 確實可以解決問題(因為單獨的線段之間沒有連接),但是將 TCanvas.Stroke.Join 引數設定為 TStrokeJoin.Round 或 TStrokeJoin.Bevel 也是如此。
請注意,在接近 180 度的非常銳角處,斜接將變為無限大。然而,它似乎以某種方式受到限制,可能與筆畫粗細成比例。我認為沒有辦法在delphi中改變這個斜接限制。
uj5u.com熱心網友回復:
這是因為默認情況下TPath在不同路徑段之間進行平滑過渡。我猜它可能使用二次插值來進行這些平滑過渡。
是的,在兩條線之間進行平滑過渡似乎不合邏輯,但看起來這就是它的實作方式。
現在你可以通過告訴TPath你的兩條線沒有連接,因此即使你實際上它們是連接的,也應該將它們視為兩條單獨的線來避免這種情況。您可以通過簡單地呼叫Path.MoveTowhich 來移動位置來做到這一點,這樣您就可以創建另一條不從上一個路徑點繼續的未連接線。
這是您的第一條尖角線的修改代碼的樣子:注意,我為MoveTo用于渲染先前路徑線的命令指定完全相同的位置,因為您不希望新線從新位置開始.
// A path of 2 lines going up and then back down to almost the same spot
LPath1 := TPathData.Create;
LPath1.MoveTo(PointF(100,200));
LPath1.LineTo(PointF(100,50 ));
//Add move to command to prevent Path from trying to make smooth transitions between two lines
LPath1.MoveTo(PointF(100,50));
LPath1.LineTo(PointF(105,200));
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/438619.html
下一篇:從jsonutf-8編碼字串
