AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Transparente Polygone zeichnen
Thema durchsuchen
Ansicht
Themen-Optionen

Transparente Polygone zeichnen

Ein Thema von Jacks · begonnen am 24. Aug 2016 · letzter Beitrag vom 25. Aug 2016
Antwort Antwort
Jacks

Registriert seit: 7. Mär 2016
14 Beiträge
 
#1

Transparente Polygone zeichnen

  Alt 24. Aug 2016, 13:19
Hi Zusammen,

In meiner Datenbank befinden sich >10000 Polygone (jedes Polygon kann sich in Color und Style unterscheiden).
Alle Polygone möchte ich gerne mit Transparenz (unabhängig von der ausgelesenen Reihenfolge) zeichnen.

Aktuell bekomme ich leider nur folgendes Ergebnis Hier werden früh gezeichnete Polygone nur überzeichnet.
polygone.png zielpolygone.png
Gewünschtes Resultat jedoch:

Hat jemand einen Tipp?
Code:
Bitmap.Transparent := True;
Bitmap.TransparentColor := clWhite;
...
BitMap.canvas.brush.color := Random
BitMap.canvas.brush.style:= Random
...
MyCanvas.Canvas.Polygon(polygon);
Danke und Grüße
Jacks
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#2

AW: Transparente Polygone zeichnen

  Alt 24. Aug 2016, 13:27
Je nach Delphi-Version könntest Du auf Firemonkey, GDI+ oder TransparentCanvas zurückgreifen.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von ibp
ibp

Registriert seit: 31. Mär 2004
Ort: Frankfurt am Main
1.511 Beiträge
 
Delphi 7 Architect
 
#3

AW: Transparente Polygone zeichnen

  Alt 24. Aug 2016, 16:18
schau mal hier
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Transparente Polygone zeichnen

  Alt 24. Aug 2016, 17:25
Je nach Delphi-Version könntest Du auf Firemonkey, GDI+ oder TransparentCanvas zurückgreifen.
Oder ab Delphi 2010 auch der TDirect2DCanvas aus Vcl.Direct2D.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#5

AW: Transparente Polygone zeichnen

  Alt 24. Aug 2016, 17:39
(unabhängig von der ausgelesenen Reihenfolge)
Das hier ist, wenn die Auslesereihenfolge nachher auch deine Zeichenreihenfolge ist, dein Problem. Und das ist ein absolut klassisches Problem . Deinen Bildern nach hast du nur 2D-Polygone, aber sobald (beliebige) Tranzparenzen ins Spiel kommen, bist du zwangsweise in der 3. Dimension. Grund: Ein 80% deckendes Polygon auf ein 20% deckendes gezeichnet sieht anders aus als ein 20% deckendes auf einem 80% deckenden. Noch deutlicher wird es, wenn eines der beiden 100% deckt.
Egal wie man sich dreht und wendet: Du brauchst eine Z-Order, wenn du ein immer klar definiertes immer gleiches Ergebnis haben willst.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Transparente Polygone zeichnen

  Alt 24. Aug 2016, 18:58
Hier mal eine alte Routine von mir:

Delphi-Quellcode:
procedure FillPolygonAlpha(Vertices: TVertexList; Dest: TBitmap;
  Color: TColor);
type
  TIntegerArray = array of integer;
var
  x,y: integer;
  i,j: integer;
  PixelPtr: PColor;
  BasePixelPtr: PColor;
  ColorPartR, ColorPartG, ColorPartB, ColorA: Byte;
  Breakpoints: TIntegerArray;

  function GetBreakpoints(Row: integer; XOffset: integer): TIntegerArray;
  var
    Pt1, Pt2: TPoint;
    PtOld, PtNew: TPoint;
    Count: integer;
    i: integer;

    procedure QuickSort(var SortList: TIntegerArray; L, R: Integer);
    var
      I, J: Integer;
      P, T: Integer;
    begin
      repeat
        I := L;
        J := R;
        P := Sortlist[(L + R) div 2];
        repeat
          while SortList[i] < P do
            Inc(I);
          while SortList[j] > P do
            Dec(J);
          if I <= J then
          begin
            T := SortList[I];
            SortList[I] := SortList[J];
            SortList[J] := T;
            Inc(I);
            Dec(J);
          end;
        until I > J;
        if L < J then
          QuickSort(SortList, L, J);
        L := I;
      until I >= R;
    end;

  begin
    PtOld := Vertices.Last;
    Count := 0;
    SetLength(Result, Vertices.Count);
    for i := 0 to Vertices.Count - 1 do
    begin
      PtNew := Vertices[i];
      if PtNew.Y > PtOld.Y then
      begin
        Pt1 := PtOld;
        Pt2 := PtNew;
      end
      else
      begin
        Pt1 := PtNew;
        Pt2 := PtOld;
      end;
      if ((PtNew.Y < Row) = (Row <= PtOld.Y)) and
         ((XOffset-Pt1.X)*(Pt2.Y-Pt1.Y) < (Pt2.X-Pt1.X)*(Row-Pt1.Y)) then
      begin
        Result[Count] := trunc(Pt2.X * (Row-Pt1.y) / (Pt2.Y-Pt1.Y)
                             + Pt1.X * (Pt2.Y-Row) / (Pt2.Y-Pt1.Y));
        inc(Count);
      end;
      PtOld := PtNew;
    end;
    SetLength(Result,Count);
    if length(Result)>=1 then
      Quicksort(Result,0,high(Result));
  end;
begin

  if Vertices.Count < 3 then exit;

  Dest.PixelFormat := pf32Bit;

  ColorA := Color shr 24;
  ColorPartR := Muldiv(GetRValue(Color), ColorA,255);
  ColorPartG := Muldiv(GetGValue(Color), ColorA,255);
  ColorPartB := Muldiv(GetBValue(Color), ColorA,255);
  
  for y := EnsureRange(Vertices.BoundingBox.Top, 0, Dest.Height-1) to
           EnsureRange(Vertices.BoundingBox.Bottom, 0, Dest.Height-1) do
  begin
    BasePixelPtr := Dest.ScanLine[y];
    x := Vertices.BoundingBox.Left;
    BreakPoints := GetBreakpoints(y,x-1);
    i := 0;
    while i <= high(Breakpoints) do
    begin
      PixelPtr := BasePixelPtr;
      inc(PixelPtr, EnsureRange(Breakpoints[i], 0, Dest.Width-1));
      for j := EnsureRange(Breakpoints[i], 0, Dest.Width) to
               EnsureRange(Breakpoints[i+1], 0, Dest.Width-1) do
      begin
        PixelPtr^ :=
          ColorPartR +
          Muldiv(PixelPtr^ and $00FF0000 shr 16,255-ColorA,255) shl 16 or

          ColorPartG +
          Muldiv(PixelPtr^ and $0000FF00 shr 8,255-ColorA,255) shl 8 or

          ColorPartB +
          Muldiv(PixelPtr^ and $000000FF,255-ColorA,255);
        inc(PixelPtr);
      end;
      inc(i,2);
    end;
  end;
end;
Wahrscheinlich nicht das allerschnellste (Polygone rendern ist sowieso eine Wissenschaft für sich), aber tut seinen Job.

TVertexList ist so deklariert:
Delphi-Quellcode:
  TVertexList = class
  public
    property Items[Index: integer]: TPoint read GetItem write SetItem; default;
    { ... }

    property BoundingBox: TRect read FBoundingBox;
  end;
Die Implementierung kann man sich denken. Wenn man keine Klasse dafür verwenden will, kann man die Routine natürlich auch leicht auf array of TPoint oder so anpassen, aber dazu bin ich jetzt zu faul. Man müsste aber nur drei, vier Stellen ändern.
  Mit Zitat antworten Zitat
Jacks

Registriert seit: 7. Mär 2016
14 Beiträge
 
#7

AW: Transparente Polygone zeichnen

  Alt 25. Aug 2016, 10:58
Vielen Dank,

ich verwende XE2. Habe nun das ganze mit Direct2D umgesetzt.
Hätte nun erwartet, wenn ich alle Polygone mit einer Deckkraft von 50% zeichne, bekomme ich mein gewünschtes Ergebnis. Ist leider nicht so!

Ein 80% deckendes Polygon auf ein 20% deckendes gezeichnet sieht anders aus als ein 20% deckendes auf einem 80% deckenden. Noch deutlicher wird es, wenn eines der beiden 100% deckt.
Kann ich vielleicht die Deckkraft an den Brush.Color anpassen? oder bin ich da auf dem falschen Dampfer?
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: Transparente Polygone zeichnen

  Alt 25. Aug 2016, 11:01
Was willst du denn genau erreichen? Es kommt halt immer auf die Reihenfolge an in der du zeichnest.
Wenn deine einzige Anforderung ist, dass es immer gleich aussieht kannst du ja notfalls einfach per Datenbank-ID sortieren.
Falls das nicht ausreicht musst du wie bereits erwähnt die Z-Werte speichern.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Jacks

Registriert seit: 7. Mär 2016
14 Beiträge
 
#9

AW: Transparente Polygone zeichnen

  Alt 25. Aug 2016, 11:03
Wahrscheinlich nicht das allerschnellste (Polygone rendern ist sowieso eine Wissenschaft für sich), aber tut seinen Job.
Ich brauche schon eine schnellere Methode, da ich recht große Datensätze zum zeichnen habe.
  Mit Zitat antworten Zitat
Jacks

Registriert seit: 7. Mär 2016
14 Beiträge
 
#10

AW: Transparente Polygone zeichnen

  Alt 25. Aug 2016, 11:13
Was willst du denn genau erreichen? Es kommt halt immer auf die Reihenfolge an in der du zeichnest.
Wenn deine einzige Anforderung ist, dass es immer gleich aussieht kannst du ja notfalls einfach per Datenbank-ID sortieren.
Falls das nicht ausreicht musst du wie bereits erwähnt die Z-Werte speichern.
Hatte die Hoffnung - es gibt eine Funktion für mein Problem. Aber du hast natürlich Recht!
Werde nun meine Datenbank nach Ebenen sortieren.
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:41 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz