2011-02-25 5 views
9

मैं सी # में एक प्रोग्राम लिख रहा हूं जो अनिवार्य रूप से एक एसवीजी फ़ाइल पढ़ता है, और सामग्री के साथ कुछ उपयोगी चीजें करता है। सबसे जटिल डेटा मैं साथ काम कर रहा हूँ पथ हैं। वे इस तरह के रूप लेते हैं:सी # के साथ एसवीजी "पथ" तत्वों को पार करना - क्या ऐसा करने के लिए वहाँ पुस्तकालय हैं?

<path d="M5.4,3.806h6.336v43.276h20.738v5.256H5.4V3.806z"/> 

इस मामले में, एम, एच, वी, एच, वी, और जेड कुछ कमांड इंगित करता है। एक तरह से वे कार्यों की तरह हैं, उनके बाद तर्क होने के बाद संख्याएं हैं। वहाँ भी कुछ और अधिक जटिल हैं:

<path d="M70.491,50.826c-2.232,1.152-6.913,2.304-12.817,2.304c-13.682,0-23.906-8.641-23.906-24.626 
     c0-15.266,10.297-25.49,25.346-25.49c5.977,0,9.865,1.296,11.521,2.16l-1.584,5.112C66.747,9.134,63.363,8.27,59.33,8.27 
     c-11.377,0-18.938,7.272-18.938,20.018c0,11.953,6.841,19.514,18.578,19.514c3.888,0,7.777-0.792,10.297-2.016L70.491,50.826z"/> 

इस मामले में, "सी" कमांड (पहले मामले में -2.232, 1.152, -6.913, 2.304, -12.817, और 2.304) 6 तर्कों द्वारा पीछा किया जाता । आप देख सकते हैं कि यह कैसे मुश्किल हो सकता है। मेरे प्रश्न यह हैं: क्या एसओ समुदाय किसी मौजूदा पुस्तकालयों से अवगत है जो कुछ उपयोगी एडीटी में ऐसे डेटा को पढ़ते हैं?

इससे पहले कि मैं सब कुछ कोडिंग और स्ट्रिंग पार्सिंग कार्यों का एक टन लिखने से पहले, मैं वास्तव में पहिया का पुन: आविष्कार नहीं करना चाहता। इसके अलावा, किसी भी सलाह की सराहना की जाएगी। मुझे पता है कि XML दस्तावेज़ को कैसे पढ़ा जाए, यह समस्या यहां नहीं है।

+0

क्या आपको केवल प्रत्येक पथ को कमांड की सूची में बदलने की आवश्यकता है (जहां प्रत्येक कमांड के अपने पैरामीटर होते हैं) या क्या आपको उन आदेशों का मूल दुभाषिया बनाने की आवश्यकता है? –

+0

दोनों को होने की आवश्यकता होगी, और मैं दोनों पर अंतर्दृष्टि की तलाश कर रहा हूं। –

उत्तर

9

मैं सी # में विशिष्ट पुस्तकालयों में से पता नहीं है, तथापि आप इस तरह की संरचना इस तरह की पार्स करने से शुरू कर सकता है:

string path = "M5.4,3.806h6.336v43.276h20.738v5.256H5.4V3.806z"; 
string separators = @"(?=[MZLHVCSQTAmzlhvcsqta])"; // these letters are valid SVG 
          // commands. Whenever we find one, a new command is 
          // starting. Let's split the string there. 
var tokens = Regex.Split(path, separators).Where(t => !string.IsNullOrEmpty(t)); 

अब आप अपने तर्क के बाद आदेशों की एक सूची है। फिर आप तर्कों को उसी तरह विभाजित करने के लिए आगे बढ़ सकते हैं।

आपने कहा कि तर्कों को एक स्थान, एक अल्पविराम या एक ऋण चिह्न से अलग किया जा सकता है (जो, अल्पविराम और सफेद जगह के विपरीत, तर्कों का हिस्सा बने रहना चाहिए), ताकि आप एक और सरल रेगेक्स का उपयोग कर सकें (ध्यान दें कि मैं मैं नियमित अभिव्यक्तियों का कोई प्रशंसक नहीं हूं, लेकिन इस मामले में मुझे लगता है कि वे पठनीयता में जोड़ते हैं)।

string argSeparators = @"[\s,]|(?=-)"; // discard whitespace and comma but keep the - 
var splitArgs = Regex 
    .Split(remainingargs, argSeparators) 
    .Where(t => !string.IsNullOrEmpty(t)); 

मैं एक SVGCommand कक्षा में इस लपेट होगा, इस

class SVGCommand 
{ 
    public char command {get; private set;} 
    public float[] arguments {get; private set;} 

    public SVGCommand(char command, params float[] arguments) 
    { 
     this.command=command; 
     this.arguments=arguments; 
    } 

    public static SVGCommand Parse(string SVGpathstring) 
    { 
     var cmd = SVGpathstring.Take(1).Single(); 
     string remainingargs = SVGpathstring.Substring(1); 

     string argSeparators = @"[\s,]|(?=-)"; 
     var splitArgs = Regex 
      .Split(remainingargs, argSeparators) 
      .Where(t => !string.IsNullOrEmpty(t)); 

     float[] floatArgs = splitArgs.Select(arg => float.Parse(arg)).ToArray(); 
     return new SVGCommand(cmd,floatArgs); 
    } 
} 

अब की तरह एक साधारण "दुभाषिया" कुछ इस तरह दिखाई दे सकता है:

string path = "M70.491,50.826c-2.232,1.152-6.913,2.304-12.817,2.304c-13.682,0-23.906-8.641-23.906-24.626" + 
"c0-15.266,10.297-25.49,25.346-25.49c5.977,0,9.865,1.296,11.521,2.16l-1.584,5.112C66.747,9.134,63.363,8.27,59.33,8.27" + 
"c-11.377,0-18.938,7.272-18.938,20.018c0,11.953,6.841,19.514,18.578,19.514c3.888,0,7.777-0.792,10.297-2.016L70.491,50.826z"; 
    string separators = @"(?=[A-Za-z])"; 
    var tokens = Regex.Split(path, separators).Where(t => !string.IsNullOrEmpty(t)); 

    // our "interpreter". Runs the list of commands and does something for each of them. 
    foreach (string token in tokens){ 
        // note that Parse could throw an exception 
        // if the path is not correct 
     SVGCommand c = SVGCommand.Parse(token); 
     Console.WriteLine("doing something with command {0}", c.command); 
    } 

आप कुछ करने के लिए की जरूरत है अधिक परिष्कृत, एफ # शायद better suited for the job (और सी # के साथ अंतःक्रियाशील है)। मैं सिर्फ इस विशिष्ट कार्य के लिए एफ # सीखने का सुझाव नहीं दे रहा हूं, मैंने सोचा कि मैं इसका जिक्र करूँगा, अगर आप इसे किसी और चीज़ के लिए देख रहे हैं।

+0

मैंने मूल को एक उदाहरण के साथ संपादित किया। तर्कों के साथ समस्या यह है कि वे एक अल्पविराम, या एक स्थान, या एक ऋण चिह्न के रूप में एक अल्पविराम का उपयोग कर सकते हैं। माइनस साइन के मामले में, यह "सच्चा डेलीमीटर" नहीं है क्योंकि यह तर्क का भी हिस्सा है। –

+0

@Adam मैंने आपकी स्पष्टीकरण के आधार पर उत्तर का विस्तार किया। उम्मीद है कि यह –

+0

में मदद करता है, इसके लिए एक और गड़बड़ी है, कोड वैज्ञानिक नोटेशन में संख्याओं को सही तरीके से संभाल नहीं करता है। उदाहरण के लिए 1.78e-34 दो निर्देशांक में विभाजित किया जाएगा। किसी भी विचार रेगेक्स के साथ उस मामले को पकड़ने के लिए कैसे?पहले रेगेक्स में – thalm

4

WPF ज्यामिति ऑब्जेक्ट का उपयोग करके ऐसा करना संभव होगा। जहां तक ​​मैं डब्ल्यूपीएफ द्वारा उपयोग किए गए Path Markup syntax को एसवीजी पथ के समान वाक्यविन्यास बता सकता हूं।

var data = "M5.4,3.806h6.336v43.276h20.738v5.256H5.4V3.806z"; 

var geometry = Geometry.Parse(data); 

var pathGeometry = PathGeometry.CreateFromGeometry(geometry); 

foreach (var figure in pathGeometry.Figures) 
{ 
    // Do something interesting with each path figure. 
    foreach (var segment in figure.Segments) 
    { 
     // Do something interesting with each segment. 
    } 
} 
+1

यह लगभग मेरा दिन केवल तब तक बना रहा जब तक मुझे पता चला कि यह सिस्टम का हिस्सा था। विन्डोज़ जो मोनो के कारण यूनिटी 3 डी में समर्थित नहीं है। –

+0

क्षमा करें मैं वहां मदद नहीं कर सकता क्योंकि मैं यूनिटी 3 डी – bstoney

+0

से परिचित नहीं हूं, यह सैद्धांतिक रूप से .NET स्रोत कोड से निकला जा सकता है। –

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