2011-09-08 14 views
8

पर धराशायी घटता मेरे आवेदन में से एक के लिए मुझे एचटीएमएल 5 कैनवास में बेजियर पथ पर एक धराशायी घटता खींचने की आवश्यकता होगी ... डैश की लंबाई और अंतराल के बीच अंतर होना चाहिए ... यह अचूक है जावाएफएक्स, see this link ... मैं एचटीएमएल 5 कैनवास का उपयोग कर एक ही प्रभाव प्राप्त करना चाहता हूं। मुझे पता है कि धराशायी सीधी रेखाएं, लेकिन बेज़ियर साथ घुमावदार नहीं लाइनों आकर्षित करने के लिए ...एचटीएमएल 5 कैनवास बेजियर

हालांकि मैं एक विशेषज्ञ नहीं हूँ, मैं bezier drawing algorithm पता है, समस्या मैं इस एल्गोरिथ्म के साथ देखते हैं, यह आप पर निर्देशांक की पहचान करने की अनुमति देता है समय पैरामीटर का उपयोग करते हुए बेजियर जो 0 से 1 तक है ...

यह ध्रुवीय बेजियर खींचने के लिए पर्याप्त नहीं है, मुझे निर्दिष्ट लंबाई पैरामीटर और दिए गए अंतर दूरी पर, कई छोटे बेजियर आकर्षित करने होंगे, मुख्य बेजियर पथ। जावाफैक्स द्वारा उपयोग किया जाने वाला कुछ एल्गोरिदम होना चाहिए। अगर कोई मेरी मदद कर सकता है तो यह बहुत अच्छा होगा।

+0

वहाँ कुछ इसी तरह आप यहाँ धराशायी घटता के लिए अनुकूल करने में सक्षम हो सकता है कि एक स्मार्ट दिया गया है: http://stackoverflow.com/questions/ 4576724/डॉटेड-स्ट्रोक-इन-कैनवास लाइव उदाहरण यहां: http://phrogz.net/tmp/canvas_dashed_line.html – unmounted

+0

जैसा कि मैंने कहा था, मुझे पता है कि धराशायी रेखा को कैसे प्लॉट करना है, समस्या यह है कि डैश किए गए वक्र को कैसे आकर्षित किया जाए बेजियर पथ ... –

+0

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

उत्तर

4

मुझे लगता है कि जावाएफएक्स किसी भी धराशायी वक्र को चित्रित करने के लिए एक सामान्य तकनीक का उपयोग कर रहा है और बस उस उदाहरण में एक बेजियर पर इसका उपयोग होता है।

कठिन हिस्सा यह पता लगा रहा है कि प्रत्येक डैश को कहां से शुरू करना और रोकना है, जिसके लिए विभिन्न बिंदुओं पर आपके बेजियर वक्र के arc length को जानना आवश्यक है।

एक विश्लेषणात्मक दृष्टिकोण नहीं है, लेकिन मैं निम्नलिखित सुझाव है:

var bezier = function(controlPoints, t) { 
    /* your code here, I'll presume it returns a 2-element array of x and y. */ 
}; 

//just figure out the coordinates of all the points in each dash, don't draw. 
//returns an array of arrays, each sub-array will have an even number of nu- 
//merical elements, to wit, x and y pairs. 

//Argument dashPattern should be an array of alternating dash and space 
//lengths, e.g., [10, 10] would be dots, [30, 10] would be dashes, 
//[30, 10, 10, 10] would be 30-length dash, 10-length spaces, 10-length dash 
// and 10-length space. 
var calculateDashedBezier = function(controlPoints, dashPattern) { 
    var step = 0.001; //this really should be set by an intelligent method, 
        //rather than using a constant, but it serves as an 
        //example. 

    //possibly gratuitous helper functions 
    var delta = function(p0, p1) { 
    return [p1[0] - p0[0], p1[1] - p0[1]]; 
    }; 
    var arcLength = function(p0, p1) { 
    var d = delta(p0, p1); 
    return Math.sqrt(d[0]*d[0] + d[1] * d[1]); 
    }; 

    var subPaths = []; 
    var loc = bezier(controlPoints, 0); 
    var lastLoc = loc; 

    var dashIndex = 0; 
    var length = 0; 
    var thisPath = []; 
    for(var t = step; t <= 1; t += step) { 
    loc = bezier(controlPoints, t); 
    length += arcLength(lastLoc, loc); 
    lastLoc = loc; 

    //detect when we come to the end of a dash or space 
    if(length >= dashPattern[dashIndex]) { 

     //if we are on a dash, we need to record the path. 
     if(dashIndex % 2 == 0) 
     subPaths.push(thisPath); 

     //go to the next dash or space in the pattern 
     dashIndex = (dashIndex + 1) % dashPattern.length; 

     //clear the arclength and path. 
     thisPath = []; 
     length = 0; 
    } 

    //if we are on a dash and not a space, add a point to the path. 
    if(dashIndex % 2 == 0) { 
     thisPath.push(loc[0], loc[1]); 
    } 
    } 
    if(thisPath.length > 0) 
    subPaths.push(thisPath); 
    return subPaths; 
}; 

//take output of the previous function and build an appropriate path 
var pathParts = function(ctx, pathParts) { 
    for(var i = 0; i < pathParts.length; i++) { 
    var part = pathParts[i]; 
    if(part.length > 0) 
     ctx.moveTo(part[0], part[1]); 
    for(var j = 1; j < part.length/2; j++) { 
     ctx.lineTo(part[2*j], part[2*j+1]); 
    } 
    } 
}; 

//combine the above two functions to actually draw a dashed curve. 
var drawDashedBezier = function(ctx, controlPoints, dashPattern) { 
    var dashes = calculateDashedBezier(controlPoints, dashPattern); 
    ctx.beginPath(); 
    ctx.strokeStyle = /* ... */ 
    ctx.lineWidth = /* ... */ 
    pathParts(ctx, dashes); 
    ctx.stroke(); 
}; 

इस दृष्टिकोण के साथ मुख्य समस्या अपने मूर्ख के विवरण का स्तर है। जब आपके (छोटे) डैश या (बड़े) वक्र के लिए चरण बहुत बड़ा होता है, तो चरण का आकार अच्छी तरह से काम नहीं करेगा और डैश सीमाएं बिल्कुल ठीक नहीं होंगी जहां आप उन्हें चाहते हैं। जब चरण बहुत छोटा होता है, तो आप lineTo() एस को उन बिंदुओं पर कर सकते हैं जो एक-दूसरे से एक उप-पिक्सेल दूरी दूर हैं, कभी-कभी एए कलाकृतियों के लिए। उप पिक्सेल दूरी निर्देशांक को फ़िल्टर करना मुश्किल नहीं है, लेकिन वास्तव में आपको जितनी जरूरत है उससे अधिक 'शिखर' उत्पन्न करने में अक्षम है। बेहतर कदम आकार के साथ आना वास्तव में कुछ है जो मैं अधिक विश्लेषणात्मक रूप से हमला करने पर विचार करता हूं।

इस दृष्टिकोण का उपयोग करने के लिए एक बोनस है: यदि आप किसी भी वक्र के मूल्यांकन के लिए bezier(controlPoints, t) को प्रतिस्थापित करते हैं, तो आप डैश किए गए व्हाटवर्स को चित्रित करेंगे! - फिर पिछले पैराग्राफ में सूचीबद्ध समान संभावित समस्याओं के साथ। लेकिन ग्रैन्युलरिटी समस्या का वास्तव में अच्छा समाधान सभी 'अच्छी तरह से व्यवहार' वक्र के लिए काम कर सकता है।

+1

आपने सही ढंग से पहचाना है कि, कदम = 0.001 के चरणों को मानना ​​एक बड़ा जोखिम है क्योंकि आप उन्नत में बेजियर के आकार को नहीं जानते हैं। यह बेहतर होगा यदि मध्य बिंदु को ढूंढकर चरण दो बार की दूरी तक शून्य या वक्र सीधे हो जाता है ... –

+0

ऐसा करने का एक और आसान तरीका आर्क चरण बेजियर वक्र की विभाजित है कि सबसे छोटी डैश लंबाई से। फिर भी, एक निश्चित 'चरण' ठीक काम करेगा यदि आपके वक्र ऐसे हैं कि '1/चरण' छोटी लंबाई की लंबाई से विभाजित चाप लंबाई से काफी अधिक है। – ellisbben

+0

इससे मदद मिली, धन्यवाद ... –

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