2012-11-30 34 views
8

मैं एक स्ट्रोक पथ को एक भरे ऑब्जेक्ट में कनवर्ट करना चाहता हूं। (प्रोग्रामेटिक रूप से, जावास्क्रिप्ट में।)स्ट्रोक की रूपरेखा कैसे प्राप्त करें?

रेखा केवल एक साधारण घुमावदार रेखा है, जो निर्देशांक का अनुक्रम है। मैं इस रेखा को पथ के रूप में प्रस्तुत कर सकता हूं, और इसे एक निश्चित मोटाई का स्ट्रोक दे सकता हूं ... लेकिन मैं स्ट्रोक लाइन की बजाय एक भरे आकार को प्राप्त करने की कोशिश कर रहा हूं, ताकि मैं उस पर और संशोधन कर सकूं, जैसे कि युद्ध यह, इसलिए परिणामी 'स्ट्रोक' मोटाई में भिन्न हो सकता है या इसमें कस्टम बिट्स काट दिया जा सकता है (इनमें से कोई भी वास्तविक एसवीजी स्ट्रोक के साथ संभव नहीं है, जहां तक ​​मैं कह सकता हूं)।

तो मैं एक ठोस आकार में एक पंक्ति को मैन्युअल रूप से 'मोटा' करने की कोशिश कर रहा हूं। मुझे कोई ऐसा फ़ंक्शन नहीं मिल रहा है जो ऐसा करता है - मैंने D3.js और Raphaël के दस्तावेज़ों को देखा है, लेकिन कोई भाग्य नहीं है। क्या किसी को लाइब्रेरी/फ़ंक्शन के बारे में पता है जो ऐसा करेगा?

या इससे भी बेहतर: अगर कोई मुझे ज्यामिति सिद्धांत समझा सकता है कि मैं इस कार्य को मैन्युअल रूप से कैसे करूँगा, लाइन निर्देशांक की सूची ले कर मेरे पास है और एक नया पथ तैयार कर रहा है जो प्रभावी रूप से 'स्ट्रोक' करता है, अद्भुत होगा। इसे एक और तरीके से रखने के लिए, ब्राउज़र क्या करता है जब आप इसे पथ को स्ट्रोक करने के लिए कहते हैं - यह कैसे काम करता है स्ट्रोक का आकार क्या होना चाहिए?

उत्तर

3

वहाँ एक ऐसी ही सवाल हाल ही में किया गया है: svg: generate 'outline path'

सभी में

सभी, यह एक गैर तुच्छ काम है। जैसा कि लिंक किए गए प्रश्न के मेरे उत्तर में बताया गया है, पोस्टस्क्रिप्ट में ऐसे पथ उत्पन्न करने के लिए एक आदेश है जो मूल रूप से स्ट्रोक के समान आउटपुट उत्पन्न करते हैं, जिसे strokepath कहा जाता है। यदि आप देखते हैं कि जब आप लिंक किए गए प्रश्न पर पोस्ट कोड चलाते हैं तो Ghostscript क्या थूकता है, यह बहुत बदसूरत है। और यहां तक ​​कि इंकस्केप भी वास्तव में अच्छा काम नहीं करता है। मैंने बस इंकस्केप में पथ => रूपरेखा स्ट्रोक की कोशिश की (मुझे लगता है कि अंग्रेजी कैप्शन क्या कहना चाहिए), और जो बाहर आया वह वास्तव में स्ट्रोक पथ के समान नहीं दिखता था।

"सबसे सरल" मामला होगा यदि आपके पास केवल गैर-आत्म-छेड़छाड़ वाले पॉलिलाइन, बहुभुज या पथ होते हैं जिनमें वक्र नहीं होते हैं क्योंकि आम तौर पर, आप दाईं ओर सटीक "समांतर" बेज़ीयर वक्र नहीं खींच सकते हैं और एक गैर-तुच्छ बेजियर वक्र का बायां जो स्ट्रोक क्षेत्र को सीमित करेगा - यह गणितीय रूप से मौजूद नहीं है। तो आपको इसे एक तरह से या दूसरे का अनुमान लगाना होगा। सीधी रेखा खंडों के लिए, सटीक समाधान तुलनात्मक रूप से आसानी से पाया जा सकता है।

उनमें वक्र/आर्क के साथ वेक्टर पथों को प्रस्तुत करने का क्लासिक तरीका पर्याप्त पॉलीलाइन वाली पॉलीलाइन वाली चीज़ों का अनुमान लगाने के लिए है। De Casteljau's Algorithm आमतौर पर बेजियर वक्र को लाइन सेगमेंट में बदलने के लिए उपयोग किया जाता है। (यह मूल रूप से तब भी आता है जब आप Ghostscript में strokepath कमांड का उपयोग करते हैं।) फिर आप समांतर रेखा खंडों को सीमित कर सकते हैं, लेकिन उपयुक्त लाइनजॉइन और मिटरलिमिट नियमों का उपयोग करके उन्हें सही ढंग से शामिल करना होगा। बेशक, लाइनकैप मत भूलना।

मैंने सोचा कि स्वयं को छेड़छाड़ करने वाले पथ मुश्किल हो सकते हैं क्योंकि आपको पथ के अंदर खोखले क्षेत्र मिल सकते हैं, यानी एक काले पथ का "क्रॉसिंग एरिया" सफेद हो सकता है। nonzero winding rule का उपयोग करते समय यह खुले पथों के लिए कोई समस्या नहीं हो सकती है, लेकिन मैं इसके बारे में सतर्क रहूंगा। बंद पथों के लिए, आपको शायद विपरीत अभिविन्यास में चलाने के लिए दो "सीमित" पथों की आवश्यकता है। लेकिन मुझे अभी यकीन नहीं है कि क्या यह वास्तव में सभी संभावित नुकसान को कवर करता है।

क्षमा करें अगर मैं इसके साथ बहुत भ्रम पैदा करता हूं और शायद बहुत मदद नहीं कर रहा हूं।

1

मानक विधि टिलर-हैंनसन एल्गोरिदम (दो-आयामी प्रोफाइल ऑफसेट्स, 1 9 84 का ऑफसेट है, जो परेशान रूप से मुक्त नहीं है) जो एक अच्छा अनुमान बनाता है।विचार यह है कि प्रत्येक बेजियर वक्र के नियंत्रण बिंदु वक्र के प्रारंभ और अंत तक टेंगेंट लाइनों पर झूठ बोलते हैं, समानांतर वक्र में एक ही संपत्ति होगी। इसलिए हम वक्र की शुरुआत और अंत को ऑफ़सेट करते हैं, फिर इन चौराहे का उपयोग करके नए नियंत्रण बिंदु खोजें। हालांकि, यह तेज घटता के लिए बहुत खराब परिणाम देता है, इसलिए पहला कदम मूल वक्र को विभाजित करना है, जो बेजियर वक्रों के साथ करना बहुत आसान है, जब तक यह पर्याप्त रूप से छोटे कोण से गुजरता न हो।

प्रत्येक कशेरुक के अंदर समानांतरों के बीच अंतरण (i) के साथ निपटने के लिए अन्य परिष्करण की आवश्यकता है; (ii) प्रत्येक चरम के बाहर के अंतर को भरने के लिए एक सर्कल का एक आर्क डालना; और (iii) अंत-कैप्स जोड़ना - वर्ग, बट या परिपत्र।

टिलर-हैंनसन को कार्यान्वित करना मुश्किल है, लेकिन फ्रीटाइप पुस्तकालय में एक अच्छा ओपन-सोर्स कार्यान्वयन है, ftstroke.c (http://git.savannah.gnu.org/cgit/freetype/freetype2.git/ में) पेड़/src/आधार/ftstroke.c)।

मुझे खेद है कि इस कोड को एकीकृत करना काफी मुश्किल हो सकता है, लेकिन मैंने इसे सफलतापूर्वक उपयोग किया है, और यह अच्छी तरह से काम करता है।

1

इस पृष्ठ में ऑफ़सेट वक्र पर एक अच्छे सेक्शन के साथ सामान्य रूप से बेजियर वक्र पर काफी अच्छा ट्यूटोरियल है।

http://pomax.github.io/bezierinfo/

एक कम सटीक लेकिन संभवतः तेजी से विधि यहां पाया जा सकता।

http://seant23.wordpress.com/2010/11/12/offset-bezier-curves/

कोई गणितीय जवाब है, क्योंकि एक बेज़ियर वक्र को वक्र समानांतर आम तौर पर एक बेज़ियर वक्र नहीं है। अधिकांश विधियों में गिरावट के मामले होते हैं, खासकर जब वक्र की श्रृंखला से निपटते हैं।

बिना किसी परेशानी वाले स्पॉट वाले एक साधारण वक्र के बारे में सोचें। कोई cusps, कोई loops, कोई inflections, और आदर्श रूप से एक कड़ाई से बढ़ती वक्रता। इन सरल वक्रों में सभी शुरुआती घटता को ऊपर उठाएं। इन सरल घटता के सभी ऑफसेट वक्र खोजें। अंतराल घटकों को अंतराल और अंतराल से निपटने के साथ एक साथ रख दें। यदि आपके पास उनके साथ काम करने का विकल्प है तो क्वाड्रैटिक वक्र अधिक ट्रैक्टेबल हैं।

मुझे लगता है कि अधिकतर ब्राउज़र प्रसंस्करण के समान कुछ करते हैं, क्योंकि उनके पास वर्गिक वक्र के साथ भी खराब मामलों हैं। उदाहरण के लिए, 100 या उससे अधिक की मोटाई के साथ वक्र 200,300 719,301 500,300 देखें।