2016-08-21 18 views
8

tôi muốn tạo bố cục cây bố trí đẹp và một chút vấp với các cạnh cong. Vấn đề là với các góc khác nhau giữa các điểm nguồn và đích, các cạnh được vẽ khác nhau. Các bức ảnh được cung cấp là từ biểu đồ duy nhất để bạn có thể thấy chúng khác nhau như thế nào cho các hướng cạnh khác nhau. Tôi nghĩ rằng điểm là trong thế hệ điểm kiểm soát đường cong beizer và tôi chỉ không thể hiểu làm thế nào để sửa chữa chúng.Bố trí biểu đồ cây xuyên tâm: sửa đường cong beizer

Tôi muốn chúng được vẽ theo cùng một cách bất kể hướng của cạnh là gì.

Làm cách nào để đạt được điều này như trong Pic1? Làm thế nào tôi có thể đạt được điều này như trong Pic2?

Như ở đây: https://bl.ocks.org/mbostock/4063550

Cảm ơn bạn!

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: Tôi đã có góc giữa đỉnh trước và nguồn trong radian bằng cách sử dụng công thức sau: Math.Atan2 (trước. Y - source.Y, source.X - prev.X); Nhưng tôi vẫn nhận được các cạnh như trong Pic.4.

UPDATE 2 Các trước đỉnh pos cho branchAngle tính toán là không chính xác vì vậy tôi quyết định đi một góc trung bình giữa tất cả các cạnh trong một chi nhánh như branchAngle. Cách tiếp cận này thất bại khi các cạnh từ một brach là khoảng 180 deg mark và branch có thể có các góc cạnh như 175, 176 .. -176 !! Tôi sử dụng mã này để làm cho chúng hoàn toàn tích cực:

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

Nhưng bây giờ các góc có thể là 350, 359 .. 2 !!! Khá khó khăn để calc trung bình :) Bạn có thể vui lòng tư vấn cho tôi làm thế nào tôi có thể làm việc này xung quanh?

pic1 Beizer curve edges - up

pic2 Beizer curve edges - left

pic3 enter image description here

pic4 enter image description here

Trả lời

1

Nhìn vào đồ thị từ liên kết mà bạn cung cấp từng ngành trong cây đã thật góc riêng , được sử dụng để khai báo contro l điểm của chi nhánh. Điều này branchAngle là giống như một trong những vector đi từ nút đầu tiên đến trước đó (mỗi chi nhánh có thể đẻ trứng một số chi nhánh lần lượt). Góc của nhánh đầu tiên (nút đầu tiên = nút trước = trung tâm) có vẻ là khoảng -60 °.

Đặt loại đường cong có thể được thực hiện bằng cách bù góc chi nhánh này (0 °, -90 °, -180 °, ...) cho tất cả các nhánh trong cây. Kết quả trong các controlAngle được sử dụng để đặt ra các điểm kiểm soát.

Tạo các điểm kiểm soát trong khi có tính đến các góc:

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

Kiểm tra nhanh branchAngle = 30 ° & bồi thường = -90 ° -> controlAngle = -60 °

+0

Cảm ơn bạn đã trả lời nhưng tôi vẫn nhận được kết quả lạ, vui lòng xem cập nhật 1 trong op. –

+0

@Alexander xin lỗi về điều đó, đã phạm sai lầm trong dx và dy calc. Đã chuyển đổi sinB với cosB và ngược lại. – Funk

+0

Dường như có lỗi đánh máy trong bản chỉnh sửa của bạn, branchAngle phải là 'Math.Atan2 (prev.Y - source.Y, prev.X - source.X)'. – Funk

Các vấn đề liên quan