2016-08-21 3 views
8

मैं अच्छा रेडियल पेड़ लेआउट प्रस्तुत करना चाहता हूं और घुमावदार किनारों के साथ थोड़ा ठोकर देना चाहता हूं। समस्या यह है कि स्रोत और लक्ष्य बिंदुओं के बीच विभिन्न कोणों के साथ किनारों को अलग-अलग खींचा जाता है। बशर्ते चित्र एकल ग्राफ से हैं ताकि आप देख सकें कि वे विभिन्न किनारे दिशाओं के लिए अलग-अलग कैसे हैं। मुझे लगता है कि बिंदु बीज़र वक्र नियंत्रण बिंदु पीढ़ी में है और मैं समझ नहीं पा रहा हूं कि उन्हें कैसे ठीक किया जाए।रेडियल पेड़ ग्राफ़ लेआउट: फिक्स बीज़र वक्र

मैं चाहता हूं कि उन्हें किनारे की दिशा क्या हो, कोई फर्क नहीं पड़ता।

मैं इसे Pic1 में कैसे प्राप्त कर सकता हूं? मैं इसे Pic2 में कैसे प्राप्त कर सकता हूं?

यहाँ की तरह: https://bl.ocks.org/mbostock/4063550

धन्यवाद!

कोड:

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

अद्यतन 1: Math.Atan2 (पिछला: मैं रेडियंस निम्न सूत्र का उपयोग करने में पिछले शिखर और स्रोत के बीच के कोण मिल गया है। वाई - स्रोत। वाई, स्रोत.एक्स - prev.X); लेकिन फिर भी मुझे Pic.4 में किनारों मिलते हैं।

अद्यतन 2 branchAngle गणना के लिए पिछला शिखर स्थिति गलत है तो मैं branchAngle के रूप में एक शाखा में सभी किनारों के बीच औसत कोण लेने का फैसला किया। यह दृष्टिकोण विफल रहता है जब एक ब्रैच के किनारे 180 डिग्री अंक के आसपास होते हैं और शाखा में 175, 176 जैसे किनारे कोण हो सकते हैं .. -176 !! मैं उन्हें सभी सकारात्मक बनाने के लिए इस कोड का उपयोग करता हूं:

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

लेकिन अब कोण 350, 35 9 .. 2 !!! औसत को कैलक करना काफी मुश्किल है :) क्या आप कृपया मुझे सलाह दे सकते हैं कि मैं इसे कैसे काम कर सकता हूं?

pic1 Beizer curve edges - up

pic2 Beizer curve edges - left

pic3 enter image description here

pic4 enter image description here

उत्तर

1

लिंक आप पेड़ में प्रत्येक शाखा प्रदान की से ग्राफ को देखते हुए यह खुद कोण है है , जिसका उपयोग contro घोषित करने के लिए किया जाता है शाखा के एल अंक। यह branchAngle पहले नोड से पिछले एक में जाने वाले वेक्टर में से एक जैसा है (प्रत्येक शाखा बदले में कई शाखाएं पैदा कर सकती है)। पहली शाखा का कोण (पहला नोड = पिछला नोड = केंद्र) लगभग -60 डिग्री लगता है।

पेड़ की सभी शाखाओं के लिए इस शाखा कोण (0 डिग्री, -90 डिग्री, -180 डिग्री, ...) को क्षतिपूर्ति करके वक्र के प्रकार को सेट करके किया जा सकता है। controlAngle में परिणाम नियंत्रण बिंदु डालने के लिए उपयोग किया जाता है।

नियंत्रण बिंदुओं जनरेट कर रहा है, जबकि कोणों को ध्यान में रखते:

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

त्वरित जांच branchAngle = 30 डिग्री & मुआवजा = -90 ° -> controlAngle = -60 °

+0

उत्तर के लिए धन्यवाद, लेकिन फिर भी मुझे अजीब परिणाम मिलते हैं, कृपया op में अपडेट 1 देखें। –

+0

@Alexander इसके बारे में खेद है, डीएक्स और डीई कैल्क में गलती की। सीओएसबी के साथ sinb sinb और इसके विपरीत। – Funk

+0

आपके संपादन में एक टाइपो प्रतीत होता है, शाखा एंगल 'Math.Atan2 होना चाहिए (prev.Y - source.Y, prev.X - source.X) '। – Funk

संबंधित मुद्दे