2016-08-21 14 views
8

Güzel radyal ağaç yerleşimi oluşturmak ve biraz kavisli kenarları ile tökezlemek istiyorum. Sorun, kaynak ve hedef noktaları arasındaki farklı açılarda kenarların farklı şekilde çizilmesidir. Sağlanan resimler tek grafikten, böylece farklı kenar yönleri için nasıl farklı olduklarını görebilirsiniz. Bence nokta beizer eğrisi kontrol noktalarının üretilmesinde ve bunların nasıl düzeltileceğini anlayamıyorum.Radyal ağaç grafik düzeni: düzeltmek berat eğrileri

Kenarların yönü ne olursa olsun aynı şekilde çizilmelerini istiyorum.

Bunu Pic1'deki gibi nasıl yapabilirim? Pic2'deki gibi bunu nasıl yapabilirim? Burada gibi

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

teşekkür ederiz!

Kodu:

//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);

GÜNCELLEME 1: Math.Atan2 (önceki: Ben aşağıdaki formül kullanılarak radyan önceki tepe noktası ve kaynağı arasındaki açıyı var. Y - source.Y, source.X - prev.X); Ama yine de kenarları Pic.4'de görüyorum.

GÜNCELLEME 2 branchAngle hesaplanması için önceki köşe konum yüzden branchAngle gibi bir dal tüm kenarları arasında bir ortalama açı almaya karar tutarlı. Bu yaklaşım, bir brachin kenarları 180 derece işareti civarında olduğunda ve şube 175, 176 .. -176 gibi kenar açılarına sahip olduğunda başarısız olur!

 var angle = Math.Atan2(point1.Y - point2.Y, point1.X - point2.X); 
     while (angle < 0d) 
      angle += Math.PI*2; 

Ama şimdi açıları 350, 359 .. 2 olabilir !!!: Ben hepsini olumlu yapmak için bu kodu kullanın Ortalama olarak hesaplamak oldukça zor :) Bu konuda nasıl çalışabilirim?

Pic1 Beizer curve edges - up

Pic2 Beizer curve edges - left

Pic3 enter image description here

enter image description here

cevap

1

pic4 ağaca her dalını sağlanan bağlantıdan grafikte baktığımızda kendi açı etti , contro bildirmek için kullanılır Şubenin l noktaları. Bu branchAngle, ilk düğümden öncekine giden vektörlerden biriyle aynıdır (her dal, sırayla birkaç dal oluşturabilir). İlk dalın açısı (ilk düğüm = önceki düğüm = merkez) -60 ° civarında görünmektedir.

Eğri türünü ayarlamak, ağaçtaki tüm dallar için bu dal açısını (0 °, -90 °, -180 °, ...) telafi ederek yapılabilir. Kontrol noktalarının düzenlenmesi için kullanılan controlAngle ile sonuçlanır.-> controlAngle = -60 °

//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

Hızlı onay branchAngle = 30 ° & tazminat = -90 °: açıları dikkate çekerken

kontrol noktalarını oluşturuluyor

+0

Cevabınız için teşekkürler, ancak yine de garip sonuçlar alıyorum, lütfen op. –

+0

@Alexander bu konuda üzgün, dx ve dy calc bir hata yaptı. CosB ile anahtarlanmış sinB ve tersi. – Funk

+0

Düzenlemenizde bir yazım hatası var gibi görünüyor, branchAngle 'Math.Atan2 (prev.Y - source.Y, prev.X - source.X) 'olmalıdır. – Funk