Laden...

Gleiche Linien werden unterschiedlich gezeichnet?

Erstellt von srynoname vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.395 Views
S
srynoname Themenstarter:in
223 Beiträge seit 2006
vor 14 Jahren
Gleiche Linien werden unterschiedlich gezeichnet?

Hallo,

ich zeichne in einem Canvas mehrere Linien mit den selben Einstellungen, die Linien werden jedoch unterschiedlich dargestellt, vgl. Screenshot. Der Screenshot zeigt unterschiedliche Stellen des Canvas, der blaue Balken im Screenshot trennt die unterschiedlichen Darstellung der eigentlich gleichen Linien. Hier der genutzte Code zum Erzeugen der Linien:

 for (int i = 1; i <= 100; i++)
            {
                // Line
                LineGeometry line = new LineGeometry();
                line.StartPoint = new Point(i * 100, 0);
                line.EndPoint = new Point(i * 100, 100 * 100);
 
                // Path
                Path myPath = new Path();
                myPath.Stroke = Brushes.Black;
                myPath.StrokeThickness = 1;
                
                // Add to canvas
                myPath.Data = line;
                canvas1.Children.Add(myPath);
            }

Ist daran irgendwas falsch? Im Anhang auch nochmal mein Projekt, führt es doch bitte mal aus, maximiert das Fenster und scrollt etwas hin und her, ihr solltet das reproduzieren können : Vielen Dank!

S
srynoname Themenstarter:in
223 Beiträge seit 2006
vor 14 Jahren
5.742 Beiträge seit 2007
vor 14 Jahren

Hallo srynoname,

füge mal ein:


myPath.SnapsToDevicePixels = true;

Hintergrund ist, dass die Linien sonst antialiased werden, wenn sie zwischen zwei Pixeln liegen.

BTW: Freeze am besten deine Linien, um die Performance zu verbessern:


line.Freeze();

S
srynoname Themenstarter:in
223 Beiträge seit 2006
vor 14 Jahren

hallo winsharp,

vielen dank für deine beiden tipps, funktioniert nun alles wie es soll 😃
ich verstehe nur nicht, warum auf eine gerade linie antialiasing angewendet wird bzw. wie diese zwischen pixeln liegen kann?

5.742 Beiträge seit 2007
vor 14 Jahren

ich verstehe nur nicht, warum auf eine gerade linie antialiasing angewendet wird bzw. wie diese zwischen pixeln liegen kann?

Naja - sobald durch irgendwelche Koordinaten eine Zahl mit Nachkommastellen als Position für die Linie herauskommt, wird antialiased.
Vermutlich ist in diesem Fall der ScrollViewer die Ursache und erzeugt keine Integer als Positionsangaben.

S
srynoname Themenstarter:in
223 Beiträge seit 2006
vor 14 Jahren

hallo winsharp,
danke für deine antwort. ich habe hier noch einen artikel gefunden, in dem die richtige antwort drinne steht:
http://www.wpftutorial.net/DrawOnPhysicalDevicePixels.html

Align the edges not the center points

The reason why the lines appear blurry, is that our points are center points of the lines not edges. With a pen width of 1 the edges are drawn excactly between two pixels.

S
srynoname Themenstarter:in
223 Beiträge seit 2006
vor 14 Jahren

Hmm habe mich wohl zu früh gefreut. Wenn ich die Linie per Canvas anordne, wird sie wieder antialiased!? Bin langsam echt am verzweifeln, kann doch nicht so schwer sein, einfach ein Grid ohne Antialiasing in ein Canvas zu zeichnen ):
Untenstehend der zugehörige Code, das Projekt hängt an und ein Screenshot folgt in wenigen Sekunden im nächsten Post.

      
               // LINE POSITIONED BY CANVAS -> LINE GETS BLURRY

                // Line
                LineGeometry line = new LineGeometry();
                line.StartPoint = new Point(0, 0);
                line.EndPoint = new Point(0, 100); 
  

                // Path
                Path myPath = new Path();
                myPath.Stroke = Brushes.Black;
                myPath.StrokeThickness = 5;
                myPath.SnapsToDevicePixels = true;
                line.Freeze();
            

                // Add to canvas
                myPath.Data = line;
                Canvas.SetLeft(myPath, 10); // LINE POSITIONED BY CANVAS:  x=10
                Canvas.SetTop(myPath, 0);  // LINE POSITIONED BY CANVAS 
                canvas1.SnapsToDevicePixels = true; // doesnt help
                canvas1.Children.Add(myPath);
                



                // LINE POSITIONED BY LINE GEOMETRY

                // Line
                LineGeometry line2 = new LineGeometry();
                line2.StartPoint = new Point(20, 0);  //LINE POSITIONED BY LINE GEOMETRY: x=20
                line2.EndPoint = new Point(20, 100); 


                // Path
                Path myPath2 = new Path();
                myPath2.Stroke = Brushes.Blue;
                myPath2.StrokeThickness = 5;
                myPath2.SnapsToDevicePixels = true;
                line2.Freeze();


                // Add to canvas
                myPath2.Data = line2;
                
                // Don't use the canvas for positioning
                //Canvas.SetTop(myPath, 10); //NEW
                //Canvas.SetLeft(myPath, 10); //NEW
                canvas1.Children.Add(myPath2);
S
srynoname Themenstarter:in
223 Beiträge seit 2006
vor 14 Jahren