2012-06-05 18 views
9

मेरे सी # WinForms एप्लिकेशन में मेरे पास एक पिक्चरबॉक्स है जो 2 वक्र होस्ट करता है (वोल्टेज/वर्तमान माप से परिणाम)। एक्स अक्ष वोल्टेज है और वाई अक्ष वर्तमान है। वोल्टेज धुरी -5 से 5 तक है, लेकिन वर्तमान धुरी -10 यूए से 10 यूए तक बहुत छोटा पैमाने है। कार्य यह देखने के लिए है कि दूसरा वक्र पहले वक्र के 10% के भीतर है या नहीं।एक वक्र के चारों ओर एक लिफाफा ड्राइंग

दृश्य निरीक्षण के लिए मैं पहले वक्र (ब्लू वन) के चारों ओर एक लिफाफा खींचने की कोशिश कर रहा हूं। वक्र सिर्फ PointF सरणी है। फिलहाल मुझे पता नहीं है कि नीले वक्र के चारों ओर एक सही लिफाफा कैसे आकर्षित किया जाए, मैं केवल दो अन्य वक्र खींचा हूं जो वास्तविक वक्र के एक्स बिंदुओं के परिणामस्वरूप मूल वक्र के 10% द्वारा घटाए गए हैं और घटाए गए हैं। बेशक यह एक बुरा दृष्टिकोण है, लेकिन वक्र के उस भाग के लिए कम से कम जो लंबवत है, यह काम करता है। लेकिन जैसे ही वक्र अपने गैर ऊर्ध्वाधर खंड पर है, इस चाल अब और काम नहीं करता है, के रूप में आप नीचे चित्र में देख सकते हैं:

enter image description here

यहाँ कोड है कि मैं लिफाफा आकर्षित करने के लिए उपयोग कर रहा हूँ है :

public Bitmap DrawEnvelope(double[,] pinData, float vLimit, float iLimit) 
{ 
    g = Graphics.FromImage(box); 
    g.SmoothingMode = SmoothingMode.AntiAlias; 
    g.PixelOffsetMode = PixelOffsetMode.HighQuality; 

    PointF[] u = new PointF[pinData.GetLength(0)]; //Up line 
    PointF[] d = new PointF[pinData.GetLength(0)]; //Down Line 
    List<PointF> joinedCurves = new List<PointF>(); 

    float posX = xMaxValue * (vLimit/100); 
    float minX = posX * -1; 


    for (int i = 0; i < pinData.GetLength(0); i++) 
    { 
     u[i] = new PointF(400 * (1 + (((float)pinData[i, 0]) + minX)/(xMaxValue + vExpand)), 400 * (1 - ((float)pinData[i, 1] * GetInvers((yMaxValue + iExpand))))); 
    } 

    for (int i = 0; i < pinData.GetLength(0); i++) 
    { 
     d[i] = new PointF(400 * (1 + (((float)pinData[i, 0]) + posX)/(xMaxValue + vExpand)), 400 * (1 - ((float)pinData[i, 1] * GetInvers((yMaxValue + iExpand))))); 
    } 


    Pen pengraph = new Pen(Color.FromArgb(50, 0 ,0 ,200), 1F); 
    pengraph.Alignment = PenAlignment.Center; 

    joinedCurves.AddRange(u); 
    joinedCurves.AddRange(d.Reverse()); 

    PointF[] fillPoints = joinedCurves.ToArray(); 
    SolidBrush fillBrush = new SolidBrush(Color.FromArgb(40, 0, 0, 250)); 
    FillMode newFillMode = FillMode.Alternate; 

    g.FillClosedCurve(fillBrush, fillPoints, newFillMode, 0); 

    g.Dispose(); 
    return box; 
} 

हरी हलकों अपने आप से जोड़ रहे हैं, और वे क्षेत्र है कि दूसरी अवस्था (लाल एक) संभावित है मूल वक्र से एक अंतर बड़ा 10% से है संकेत मिलता है।

अच्छा होगा अगर कोई मुझे सही तरीके से रखता है, तो मुझे मूल वक्र के चारों ओर एक अच्छा लिफाफा प्राप्त करने के लिए क्या देखना चाहिए?

अद्यतन क्योंकि मैं ऐसा noob हूँ मैं नहीं कर सकते अब तक इस सवाल का जवाब दिया लागू करने के लिए एक रास्ता खोजने, तो अगर somone कृपया मुझे इस समस्या का कम से कम एक कोडन दृष्टिकोण दिखा सकते हैं देखने के लिए एक इनाम रख दिया।

+2

लिफाफा + मतलब है? यदि ऐसा है, तो मुझे लगता है कि आपको जिस चीज की आवश्यकता है, वह वास्तव में "10% के भीतर" के बारे में अधिक निश्चितता है। प्रत्येक वोल्टेज पर 10% के भीतर वर्तमान? प्रत्येक वर्तमान में 10% के भीतर वोल्टेज? कुछ और बात? यदि यह स्कूल/विश्वविद्यालय असाइनमेंट से आता है, तो वास्तविक शब्द क्या था? यदि ऐसा कुछ है जो आप व्यावसायिक कारणों से कर रहे हैं, अंतर्निहित आवश्यकताओं क्या हैं? एक बार यह स्पष्ट हो जाने पर, यह संभवतया स्पष्ट होगा कि आपका "लिफाफा" कैसा दिखना चाहिए। –

+2

क्या आप अपने मूल वक्र को फिर से प्लॉट नहीं कर सकते हैं, लाइन की मोटाई बहुत बड़ी और अस्पष्टता कम कर सकते हैं? – Dan

+0

@ डैन मैंने पहले से ही आकार में एक बड़ी कलम के साथ मूल वक्र बनाने की कोशिश की है, लेकिन यह एक बुरा विचार है कि परिणाम अब मैं जो कर रहा हूं उससे भी बदतर होगा। –

उत्तर

1

आपकी सबसे अच्छी शर्त है कि आप अपनी पॉइंट सरणी को फिर से चालू करें और प्रत्येक लंबवत वेक्टर की गणना प्रत्येक बार दो बार करें (कार्यान्वयन सुराग के लिए Calculating a 2D Vector's Cross Product देखें)। अपने लिफाफा के दो बिंदु सरणी उत्पन्न करने के लिए इन लंबवत वैक्टरों के साथ किसी भी दिशा में परियोजना।

इस समारोह में उन्हें मोटे तौर पर खंड मध्य बिन्दुओं का उपयोग कर उत्पन्न करता है (जब तक कि बिंदु गिनती अधिक है और अपने ऑफसेट बहुत छोटा यह ठीक जब साजिश रची दिखना चाहिए नहीं है):

private void GetEnvelope(PointF[] curve, out PointF[] left, out PointF[] right, float offset) 
     { 
      left = new PointF[curve.Length - 1]; 
      right = new PointF[curve.Length - 1]; 

      for (int i = 1; i < curve.Length; i++) 
      { 
       PointF normal = new PointF(curve[i].Y - curve[i - 1].Y, curve[i - 1].X - curve[i].X); 
       float length = (float)Math.Sqrt(normal.X * normal.X + normal.Y * normal.Y); 
       normal.X /= length; 
       normal.Y /= length; 

       PointF midpoint = new PointF((curve[i - 1].X + curve[i].X)/2F, (curve[i - 1].Y + curve[i].Y)/2F); 
       left[i - 1] = new PointF(midpoint.X - (normal.X * offset), midpoint.Y - (normal.Y * offset)); 
       right[i - 1] = new PointF(midpoint.X + (normal.X * offset), midpoint.Y + (normal.Y * offset)); 
      } 
     } 
+0

धन्यवाद, यह मेरी इच्छा के करीब थोड़ा सा है। –

3

आप अंक की प्रत्येक जोड़ी के बीच ढाल को खोजने और मध्य बिंदु के माध्यम से पारित ऑर्थोगोनल पर दो बिंदुओं की गणना करने का प्रयास कर सकते हैं।

आपके पास दो बिंदुओं को एक बिंदु के सेट के रूप में परिभाषित किया जाएगा जिसका उपयोग आप लिफाफे को आकर्षित करने के लिए कर सकते हैं।

+0

क्या आप कृपया थोड़ा कोड प्रदान कर सकते हैं ताकि मैं देख सकूं कि मुझे क्या करना है? –

1

यह सब इस तरह निर्भर करता है कि आप लिफाफे को आकार देने के तरीके पर निर्भर करते हैं।

आप अगले बिंदु पर ढलान की गणना करके और पिछली बिंदु पर ढलान की गणना करके प्रत्येक बिंदु में वक्र की ढलान की गणना/अतिथि की गणना कर सकते हैं, औसत औसत और फिर ढलान पर लंबवत वेक्टर की गणना कर सकते हैं।

इस वेक्टर को वक्र के बिंदु पर जोड़ें; यह आपको लिफाफे का दायां हाथ देता है।

वक्र के बिंदु से इस वेक्टर को घटाएं; यह आपको लिफाफे के बाएं हाथ के किनारे देता है।

यदि यह बिंदु बहुत दूर हैं या बिंदुओं में अचानक अचानक परिवर्तन होते हैं तो यह विधि विफल हो जाएगी।

+0

हमम ... मैंने अभी देखा है कि निकोलस ने इसके बारे में सोचा था। –

+0

@ टिप के लिए धन्यवाद ... यह देखने का कोई मौका कि कोड कैसा दिखना चाहिए? कुछ डेटा बिंदुओं के लिए कम से कम? –

+0

मुझे यह जानने की जरूरत है कि आप कैसे लिफाफा तैयार करना चाहते हैं। –

0

यह शायद एक गूंगा सुझाव है। शायद लिफाफे को स्वयं खींचने के बजाय, शायद आप Winforms को आपके लिए कर सकते हैं। लिफाफा को एक पेन के साथ एक रेखा के रूप में खींचने का प्रयास करें जिसमें बड़ी चौड़ाई है। शायद यह काम कर सकता है।

यदि आप कलम चौड़ाई को बदलने पर इस एमएसडीएन उदाहरण को देखते हैं, तो आप देख सकते हैं कि मेरा क्या मतलब है। 10% क्षेत्र -

http://msdn.microsoft.com/en-us/library/3bssbs7z.aspx

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