2016-08-21 1 views
8

Ich möchte schöne radiale Baum Layout und ein wenig mit gebogenen Kanten gestolpert. Das Problem ist, dass bei unterschiedlichen Winkeln zwischen Quell- und Zielpunkten die Kanten unterschiedlich gezeichnet werden. Die bereitgestellten Bilder stammen aus dem einzelnen Diagramm, sodass Sie sehen können, wie sie sich für die verschiedenen Kantenrichtungen unterscheiden. Ich denke, der Punkt liegt in der Generierung der Kontrollpunkte der Beizer-Kurve und ich kann einfach nicht verstehen, wie man sie repariert.Radial Baumdiagramm Layout: Fix Beizer Kurven

Ich möchte, dass sie auf die gleiche Weise gezeichnet werden, egal welche Richtung die Kante hat.

Wie kann ich dies wie in Pic1 erreichen? Wie kann ich das wie in Pic2 erreichen?

wie hier: https://bl.ocks.org/mbostock/4063550

Vielen Dank!

Code:

//draw using DrawingContext of the DrawingVisual 
 

 
//gen 2 control points 
 
double dx = target.X - source.X, dy = target.Y - source.Y; 
 
var pts = new[] 
 
{ 
 
    new Point(source.X + 2*dx/3, source.Y), 
 
    new Point(target.X - dx/8, target.Y - dy/8) 
 
}; 
 

 
//get geometry 
 
var geometry = new StreamGeometry { FillRule = FillRule.EvenOdd }; 
 
using (var ctx = geometry.Open()) 
 
{ 
 
    ctx.BeginFigure(START_POINT, false /* is filled */, false /* is closed */); 
 
    ctx.BezierTo(pts[0], pts[1], END_POINT, true, false); 
 
} 
 
geometry.Freeze(); 
 

 
//draw it 
 
dc.DrawGeometry(DrawingBrush, DrawingPen, geometry);

UPDATE 1: Ich habe den Winkel zwischen vorherigen Vertex und Quelle in Radiant bekam die folgende Formel: Math.atan2 (i. Y - source.Y, source.X - prev.X); Aber immer noch bekomme ich die Kanten wie in Pic.4.

UPDATE 2 PREV Eckpunkt pos für branchAngle Berechnung ist ungenau, so entschieden, i in einem Zweig als branchAngle einen mittleren Winkel zwischen allen Kanten zu nehmen. Dieser Ansatz schlägt fehl, wenn die Kanten aus einer Brach-Position um die 180-Grad-Marke liegen und die Verzweigung Kantenwinkel wie 175, 176 .. -176 haben kann !! Ich verwende diesen Code, um sie alle positiv zu machen:

Aber jetzt können die Winkel 350, 359 .. 2 sein !!! Ziemlich schwierig, einen Durchschnitt zu berechnen :) Kannst du mir bitte raten, wie ich das umgehen kann?

Pic1 Beizer curve edges - up

Pic2 Beizer curve edges - left

Pic3 enter image description here

Pic4 enter image description here

Antwort

1

in der grafischen Darstellung der Suche aus dem Link, den Du jeden Zweig in dem Baum zur Verfügung gestellt hat ist es eigene Winkel , mit dem die Contro deklariert wird l Punkte der Branche. Diese branchAngle ist die gleiche wie die des Vektors, der vom ersten Knoten zum vorherigen geht (jeder Zweig kann wiederum mehrere Zweige erzeugen). Der Winkel der ersten Verzweigung (erster Knoten = vorhergehender Knoten = Mitte) scheint um -60 ° zu liegen.

Die Einstellung des Kurventyps kann durch Kompensieren dieses Verzweigungswinkels (0 °, -90 °, -180 °, ...) für alle Zweige im Baum erfolgen. Daraus ergibt sich die controlAngle zum Auslegen der Kontrollpunkte.

Generieren der Kontrollpunkte unter Berücksichtigung der Winkel:

//gen per branch 
double branchAngle = 30 * Math.PI/180; //e.g., calc vector angle here 
double cosB = Math.Cos(branchAngle); 
double sinB = Math.Sin(branchAngle);  
//depending on the desired curve compensate -90°, -180°,... 
double controlAngle = branchAngle - (90 * Math.PI/180); 
double cosA = Math.Cos(controlAngle); 
double sinA = Math.Sin(controlAngle); 

//gen 2 control points 
//calculate dx dy after rotation with branchAngle 
double dxbase = target.X - source.X, dybase = target.Y - source.Y; 
double dx = dxbase*sinB - dybase*cosB 
double dy = dxbase*cosB + dybase*sinB 
//control points based on controlAngle 
var pts = new[] 
{ 
    new Point(source.X + (2*dx/3)*cosA , source.Y + (2*dx/3)*sinA), 
    new Point(target.X - (dx/8)*cosA + (dy/8)*sinA, target.Y - (dx/8)*sinA - (dy/8)*cosA) 
}; 

Branch

Quick-Check branchAngle = 30 ° & Kompensation = -90 ° -> controlAngle = -60 °

+0

Danke für die Antwort, aber ich bekomme immer noch seltsame Ergebnisse, siehe Update 1 in der Op. –

+0

@Alexander sorry darüber, machte einen Fehler in dx und dy calc. Switched sinB mit cosB und umgekehrt. – Funk

+0

Es scheint einen Tippfehler in Ihrer Bearbeitung zu geben, BranchAngle sollte 'Math.Atan2 (prev.Y - source.Y, prev.X - source.X)' sein. – Funk