दिलचस्प पोस्ट
एक अलग उपयोगकर्ता के रूप में एक नेट प्रक्रिया शुरू करें एक प्रोग्राम में OpenSSL पुस्तकालयों को लिंक करना जीजीप्लोट में विशेष चर (..काउंट .., ..density .., आदि) कोणीय जेएस: यूआई-राउटर का प्रयोग करके एक ऑब्जेक्ट को एक राज्य में पास करें फ़ंक्शन का प्रयोग करके दो तिथियों के बीच की तारीखों की एक सूची प्राप्त करें सूची से किसी तत्व को निकालने का प्रयास करते समय मुझे एक असमर्थितऑपरेशन अपवाद क्यों मिलता है? एंड्रॉइड: स्पिनर को कस्टम ऑब्जेक्ट लिस्ट में बाँध कैसे करें? HTML इनपुट एरेज़ Java 6 enums के लिए मान () कैसे लागू किया जाता है? जावास्क्रिप्ट में रिक्त और अपरिभाषित अंतर के बीच क्या अंतर है? समारोह हस्ताक्षर का वापसी प्रकार हिस्सा है? क्या रेंज लूप के लिए पायथन को लागू करने के लिए संभव है जिसमें इटरेटर वैरिएबल नहीं है? मोंगो डीबी में, आप अपने इंडेक्स से सरणी तत्व कैसे निकाल सकते हैं बराबर के बराबर तरीका बराबर () और GetHashCode () एक विंडोज सेवा बनाने के लिए सबसे आसान भाषा

जावास्क्रिप्ट एचटीएमएल 5 कैनवास का उपयोग करते हुए एन अंक के माध्यम से चिकनी वक्र कैसे निकालना है?

ड्राइंग एप्लीकेशन के लिए मैं माउस आंदोलन को एक सरणी में सहेजता हूं और उन्हें रेखा से रेखांकित करता हूं। परिणामस्वरूप लाइन चिकनी नहीं है मैं सभी एकत्रित बिंदुओं के बीच एक एकल वक्र कैसे उत्पन्न करूं?

मैं googled है, लेकिन मैं केवल लाइनों ड्राइंग के लिए 3 कार्य मिल गया है: 2 नमूना अंक के लिए, बस लाइन का उपयोग करें 3 नमूना अंक के लिए क्वाड्रेटिक कूर्चे टू, 4 नमूना बिंदुओं के लिए, बेज़िअर क्रिव्टो।

(मैं सरणी में हर 4 अंक के लिए बेजियर क्रावेटो को चित्रित करने की कोशिश की, लेकिन यह निरंतर चिकनी वक्र के बजाय प्रत्येक 4 नमूना बिंदुओं को जोड़ता है।)

मैं 5 नमूना अंक और परे के साथ एक चिकनी वक्र आकर्षित करने के लिए एक समारोह कैसे लिखूं?

वेब के समाधान से एकत्रित समाधान "जावास्क्रिप्ट एचटीएमएल 5 कैनवास का उपयोग करते हुए एन अंक के माध्यम से चिकनी वक्र कैसे निकालना है?"

विसंगति "वक्र टू" प्रकार फ़ंक्शंस को एक साथ मिलकर बाद के नमूने बिंदुओं में शामिल होने की समस्या यह है कि जहां घटता मिलना चिकनी नहीं है यह इसलिए है क्योंकि दो घटता एक अंत बिंदु का हिस्सा है, लेकिन पूरी तरह से नियंत्रण बिंदुओं से असहज प्रभावित होते हैं। एक समाधान अगले 2 के बाद के नमूने बिंदुओं के बीच के मध्य बिंदुओं को "वक्र" करने का है। इन नए इंटरपोलेटेड पॉइंट का उपयोग करते हुए घटता से जुड़ने के अंत बिंदु पर एक चिकनी संक्रमण देता है (अगले चलने के लिए एक पुनरावृत्ति के लिए एक अंत बिंदु एक नियंत्रण बिंदु बन जाता है।) दूसरे शब्दों में, दो असंबद्ध घटता अब आम में अधिक है।

यह समाधान "फाउंडेशन एक्शन स्क्रिप्ट 3.0 एनीमेशन: चीजों को हिलना" के बाहर निकाला गया था पी .95 – प्रतिपादन तकनीकें: कई घटता बनाने

नोट: यह समाधान वास्तव में प्रत्येक अंक के माध्यम से नहीं खींचता है, जो मेरे प्रश्न का शीर्षक था (बल्कि यह नमूना अंक के माध्यम से वक्र का अनुमान लगाता है, लेकिन कभी भी नमूना बिंदुओं के माध्यम से नहीं जाता), लेकिन मेरे उद्देश्यों (एक ड्राइंग एप्लीकेशन) के लिए यह मेरे लिए काफी अच्छा है और नेत्रहीन आप अंतर नहीं बता सकते सभी नमूना बिंदुओं के माध्यम से जाने का एक समाधान है, लेकिन यह अधिक जटिल है (देखें http://www.cartogrammar.com/blog/actionscript-curves-update/ )

सन्निकटन विधि के लिए ड्राइंग कोड यहां दिया गया है:

// move to the first point ctx.moveTo(points[0].x, points[0].y); for (i = 1; i < points.length - 2; i ++) { var xc = (points[i].x + points[i + 1].x) / 2; var yc = (points[i].y + points[i + 1].y) / 2; ctx.quadraticCurveTo(points[i].x, points[i].y, xc, yc); } // curve through the last two points ctx.quadraticCurveTo(points[i].x, points[i].y, points[i+1].x,points[i+1].y); 

थोड़ा देर हो चुकी है, लेकिन रिकॉर्ड के लिए

अंक के माध्यम से चलाए जाने वाले चिकनी घटता आकर्षित करने के लिए आप कार्डिनल स्प्लिने (उर्फ कैनोनिकल स्पलाइन) का उपयोग करके चिकनी लाइन प्राप्त कर सकते हैं।

मैंने कैनवास के लिए यह फ़ंक्शन बनाया है – यह बहुमुखी प्रतिभा को बढ़ाने के लिए तीन फ़ंक्शन में विभाजित है मुख्य आवरण समारोह इस तरह दिखता है:

 function drawCurve(ctx, ptsa, tension, isClosed, numOfSegments, showPoints) { showPoints = showPoints ? showPoints : false; ctx.beginPath(); drawLines(ctx, getCurvePoints(ptsa, tension, isClosed, numOfSegments)); if (showPoints) { ctx.stroke(); ctx.beginPath(); for(var i=0;i<ptsa.length-1;i+=2) ctx.rect(ptsa[i] - 2, ptsa[i+1] - 2, 4, 4); } } 

वक्र आकर्षित करने के लिए एक्स के साथ एक सरणी है, क्रम में y अंक: x1,y1, x2,y2, ...xn,yn

इसे इस तरह प्रयोग करें:

 var myPoints = [10,10, 40,30, 100,10]; //minimum two points var tension = 1; drawCurve(ctx, myPoints); //default tension=0.5 drawCurve(ctx, myPoints, tension); 

ऊपर कार्य दो उप-फ़ंक्शंस कॉल करता है, एक चिकनी अंक की गणना करने के लिए। यह नए बिंदुओं के साथ एक सरणी देता है – यह मुख्य कार्य है जो कि चिकनी अंक की गणना करता है:

 function getCurvePoints(pts, tension, isClosed, numOfSegments) { // use input value if provided, or use a default value tension = (typeof tension != 'undefined') ? tension : 0.5; isClosed = isClosed ? isClosed : false; numOfSegments = numOfSegments ? numOfSegments : 16; var _pts = [], res = [], // clone array x, y, // our x,y coords t1x, t2x, t1y, t2y, // tension vectors c1, c2, c3, c4, // cardinal points st, t, i; // steps based on num. of segments // clone array so we don't change the original // _pts = pts.slice(0); // The algorithm require a previous and next point to the actual point array. // Check if we will draw closed or open curve. // If closed, copy end points to beginning and first points to end // If open, duplicate first points to befinning, end points to end if (isClosed) { _pts.unshift(pts[pts.length - 1]); _pts.unshift(pts[pts.length - 2]); _pts.unshift(pts[pts.length - 1]); _pts.unshift(pts[pts.length - 2]); _pts.push(pts[0]); _pts.push(pts[1]); } else { _pts.unshift(pts[1]); //copy 1. point and insert at beginning _pts.unshift(pts[0]); _pts.push(pts[pts.length - 2]); //copy last point and append _pts.push(pts[pts.length - 1]); } // ok, lets start.. // 1. loop goes through point array // 2. loop goes through each segment between the 2 pts + 1e point before and after for (i=2; i < (_pts.length - 4); i+=2) { for (t=0; t <= numOfSegments; t++) { // calc tension vectors t1x = (_pts[i+2] - _pts[i-2]) * tension; t2x = (_pts[i+4] - _pts[i]) * tension; t1y = (_pts[i+3] - _pts[i-1]) * tension; t2y = (_pts[i+5] - _pts[i+1]) * tension; // calc step st = t / numOfSegments; // calc cardinals c1 = 2 * Math.pow(st, 3) - 3 * Math.pow(st, 2) + 1; c2 = -(2 * Math.pow(st, 3)) + 3 * Math.pow(st, 2); c3 = Math.pow(st, 3) - 2 * Math.pow(st, 2) + st; c4 = Math.pow(st, 3) - Math.pow(st, 2); // calc x and y cords with common control vectors x = c1 * _pts[i] + c2 * _pts[i+2] + c3 * t1x + c4 * t2x; y = c1 * _pts[i+1] + c2 * _pts[i+3] + c3 * t1y + c4 * t2y; //store points in array res.push(x); res.push(y); } } return res; } 

और वास्तव में बिंदुओं को एक चिकनी वक्र के रूप में आकर्षित करने के लिए (या जब तक आपके पास x, y सरणी है):

 function drawLines(ctx, pts) { ctx.moveTo(pts[0], pts[1]); for(i=2;i<pts.length-1;i+=2) ctx.lineTo(pts[i], pts[i+1]); } 
 var ctx = document.getElementById("c").getContext("2d"); function drawCurve(ctx, ptsa, tension, isClosed, numOfSegments, showPoints) { ctx.beginPath(); drawLines(ctx, getCurvePoints(ptsa, tension, isClosed, numOfSegments)); if (showPoints) { ctx.beginPath(); for(var i=0;i<ptsa.length-1;i+=2) ctx.rect(ptsa[i] - 2, ptsa[i+1] - 2, 4, 4); } ctx.stroke(); } var myPoints = [10,10, 40,30, 100,10, 200, 100, 200, 50, 250, 120]; //minimum two points var tension = 1; drawCurve(ctx, myPoints); //default tension=0.5 drawCurve(ctx, myPoints, tension); function getCurvePoints(pts, tension, isClosed, numOfSegments) { // use input value if provided, or use a default value tension = (typeof tension != 'undefined') ? tension : 0.5; isClosed = isClosed ? isClosed : false; numOfSegments = numOfSegments ? numOfSegments : 16; var _pts = [], res = [], // clone array x, y, // our x,y coords t1x, t2x, t1y, t2y, // tension vectors c1, c2, c3, c4, // cardinal points st, t, i; // steps based on num. of segments // clone array so we don't change the original // _pts = pts.slice(0); // The algorithm require a previous and next point to the actual point array. // Check if we will draw closed or open curve. // If closed, copy end points to beginning and first points to end // If open, duplicate first points to befinning, end points to end if (isClosed) { _pts.unshift(pts[pts.length - 1]); _pts.unshift(pts[pts.length - 2]); _pts.unshift(pts[pts.length - 1]); _pts.unshift(pts[pts.length - 2]); _pts.push(pts[0]); _pts.push(pts[1]); } else { _pts.unshift(pts[1]); //copy 1. point and insert at beginning _pts.unshift(pts[0]); _pts.push(pts[pts.length - 2]); //copy last point and append _pts.push(pts[pts.length - 1]); } // ok, lets start.. // 1. loop goes through point array // 2. loop goes through each segment between the 2 pts + 1e point before and after for (i=2; i < (_pts.length - 4); i+=2) { for (t=0; t <= numOfSegments; t++) { // calc tension vectors t1x = (_pts[i+2] - _pts[i-2]) * tension; t2x = (_pts[i+4] - _pts[i]) * tension; t1y = (_pts[i+3] - _pts[i-1]) * tension; t2y = (_pts[i+5] - _pts[i+1]) * tension; // calc step st = t / numOfSegments; // calc cardinals c1 = 2 * Math.pow(st, 3) - 3 * Math.pow(st, 2) + 1; c2 = -(2 * Math.pow(st, 3)) + 3 * Math.pow(st, 2); c3 = Math.pow(st, 3) - 2 * Math.pow(st, 2) + st; c4 = Math.pow(st, 3) - Math.pow(st, 2); // calc x and y cords with common control vectors x = c1 * _pts[i] + c2 * _pts[i+2] + c3 * t1x + c4 * t2x; y = c1 * _pts[i+1] + c2 * _pts[i+3] + c3 * t1y + c4 * t2y; //store points in array res.push(x); res.push(y); } } return res; } function drawLines(ctx, pts) { ctx.moveTo(pts[0], pts[1]); for(i=2;i<pts.length-1;i+=2) ctx.lineTo(pts[i], pts[i+1]); } 
 canvas { border: 1px solid red; } 
 <canvas id="c"><canvas> 

पहला जवाब सभी बिंदुओं से गुजारें नहीं होगा यह ग्राफ़ वास्तव में सभी बिंदुओं से गुजरता है और अंक के साथ प्रीफेक्ट वक्र हो जाएगा [[x:, y:}] जैसे अंक।

 var points = [{x:1,y:1},{x:2,y:3},{x:3,y:4},{x:4,y:2},{x:5,y:6}] //took 5 example points ctx.moveTo((points[0].x), points[0].y); for(var i = 0; i < points.length-1; i ++) { var x_mid = (points[i].x + points[i+1].x) / 2; var y_mid = (points[i].y + points[i+1].y) / 2; var cp_x1 = (x_mid + points[i].x) / 2; var cp_y1 = (y_mid + points[i].y) / 2; var cp_x2 = (x_mid + points[i+1].x) / 2; var cp_y2 = (y_mid + points[i+1].y) / 2; ctx.quadraticCurveTo(cp_x1,points[i].y ,x_mid, y_mid); ctx.quadraticCurveTo(cp_x2,points[i+1].y ,points[i+1].x,points[i+1].y); } 

KineticJS को एक कोशिश दें – आप अंकों की एक सरणी के साथ एक स्पलाइन परिभाषित कर सकते हैं। यहां एक उदाहरण है:

पुराना यूआरएल: http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-spline-tutorial/

संग्रह यूआरएल देखें: https://web.archive.org/web/20141204030628/http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-spline-tutorial/

जैसा कि डैनियल हॉवर्ड बताते हैं , रोब स्पेन्सर आपको http://scaledinnovation.com/analytics/splines/aboutSplines.html पर क्या चाहते हैं।

यहां एक इंटरैक्टिव डेमो है: http://jsbin.com/ApitIxo/2/

यहां यह एक स्निपेट के रूप में है, जिस स्थिति में जेएसबीन नीचे है

 <!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <title>Demo smooth connection</title> </head> <body> <div id="display"> Click to build a smooth path. (See Rob Spencer's <a href="http://scaledinnovation.com/analytics/splines/aboutSplines.html">article</a>) <br><label><input type="checkbox" id="showPoints" checked> Show points</label> <br><label><input type="checkbox" id="showControlLines" checked> Show control lines</label> <br> <label> <input type="range" id="tension" min="-1" max="2" step=".1" value=".5" > Tension <span id="tensionvalue">(0.5)</span> </label> <div id="mouse"></div> </div> <canvas id="canvas"></canvas> <style> html { position: relative; height: 100%; width: 100%; } body { position: absolute; left: 0; right: 0; top: 0; bottom: 0; } canvas { outline: 1px solid red; } #display { position: fixed; margin: 8px; background: white; z-index: 1; } </style> <script> function update() { $("tensionvalue").innerHTML="("+$("tension").value+")"; drawSplines(); } $("showPoints").onchange = $("showControlLines").onchange = $("tension").onchange = update; // utility function function $(id){ return document.getElementById(id); } var canvas=$("canvas"), ctx=canvas.getContext("2d"); function setCanvasSize() { canvas.width = parseInt(window.getComputedStyle(document.body).width); canvas.height = parseInt(window.getComputedStyle(document.body).height); } window.onload = window.onresize = setCanvasSize(); function mousePositionOnCanvas(e) { var el=e.target, c=el; var scaleX = c.width/c.offsetWidth || 1; var scaleY = c.height/c.offsetHeight || 1; if (!isNaN(e.offsetX)) return { x:e.offsetX*scaleX, y:e.offsetY*scaleY }; var x=e.pageX, y=e.pageY; do { x -= el.offsetLeft; y -= el.offsetTop; el = el.offsetParent; } while (el); return { x: x*scaleX, y: y*scaleY }; } canvas.onclick = function(e){ var p = mousePositionOnCanvas(e); addSplinePoint(px, py); }; function drawPoint(x,y,color){ ctx.save(); ctx.fillStyle=color; ctx.beginPath(); ctx.arc(x,y,3,0,2*Math.PI); ctx.fill() ctx.restore(); } canvas.onmousemove = function(e) { var p = mousePositionOnCanvas(e); $("mouse").innerHTML = p.x+","+py; }; var pts=[]; // a list of x and ys // given an array of x,y's, return distance between any two, // note that i and j are indexes to the points, not directly into the array. function dista(arr, i, j) { return Math.sqrt(Math.pow(arr[2*i]-arr[2*j], 2) + Math.pow(arr[2*i+1]-arr[2*j+1], 2)); } // return vector from i to j where i and j are indexes pointing into an array of points. function va(arr, i, j){ return [arr[2*j]-arr[2*i], arr[2*j+1]-arr[2*i+1]] } function ctlpts(x1,y1,x2,y2,x3,y3) { var t = $("tension").value; var v = va(arguments, 0, 2); var d01 = dista(arguments, 0, 1); var d12 = dista(arguments, 1, 2); var d012 = d01 + d12; return [x2 - v[0] * t * d01 / d012, y2 - v[1] * t * d01 / d012, x2 + v[0] * t * d12 / d012, y2 + v[1] * t * d12 / d012 ]; } function addSplinePoint(x, y){ pts.push(x); pts.push(y); drawSplines(); } function drawSplines() { clear(); cps = []; // There will be two control points for each "middle" point, 1 ... len-2e for (var i = 0; i < pts.length - 2; i += 1) { cps = cps.concat(ctlpts(pts[2*i], pts[2*i+1], pts[2*i+2], pts[2*i+3], pts[2*i+4], pts[2*i+5])); } if ($("showControlLines").checked) drawControlPoints(cps); if ($("showPoints").checked) drawPoints(pts); drawCurvedPath(cps, pts); } function drawControlPoints(cps) { for (var i = 0; i < cps.length; i += 4) { showPt(cps[i], cps[i+1], "pink"); showPt(cps[i+2], cps[i+3], "pink"); drawLine(cps[i], cps[i+1], cps[i+2], cps[i+3], "pink"); } } function drawPoints(pts) { for (var i = 0; i < pts.length; i += 2) { showPt(pts[i], pts[i+1], "black"); } } function drawCurvedPath(cps, pts){ var len = pts.length / 2; // number of points if (len < 2) return; if (len == 2) { ctx.beginPath(); ctx.moveTo(pts[0], pts[1]); ctx.lineTo(pts[2], pts[3]); ctx.stroke(); } else { ctx.beginPath(); ctx.moveTo(pts[0], pts[1]); // from point 0 to point 1 is a quadratic ctx.quadraticCurveTo(cps[0], cps[1], pts[2], pts[3]); // for all middle points, connect with bezier for (var i = 2; i < len-1; i += 1) { // console.log("to", pts[2*i], pts[2*i+1]); ctx.bezierCurveTo( cps[(2*(i-1)-1)*2], cps[(2*(i-1)-1)*2+1], cps[(2*(i-1))*2], cps[(2*(i-1))*2+1], pts[i*2], pts[i*2+1]); } ctx.quadraticCurveTo( cps[(2*(i-1)-1)*2], cps[(2*(i-1)-1)*2+1], pts[i*2], pts[i*2+1]); ctx.stroke(); } } function clear() { ctx.save(); // use alpha to fade out ctx.fillStyle = "rgba(255,255,255,.7)"; // clear screen ctx.fillRect(0,0,canvas.width,canvas.height); ctx.restore(); } function showPt(x,y,fillStyle) { ctx.save(); ctx.beginPath(); if (fillStyle) { ctx.fillStyle = fillStyle; } ctx.arc(x, y, 5, 0, 2*Math.PI); ctx.fill(); ctx.restore(); } function drawLine(x1, y1, x2, y2, strokeStyle){ ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); if (strokeStyle) { ctx.save(); ctx.strokeStyle = strokeStyle; ctx.stroke(); ctx.restore(); } else { ctx.save(); ctx.strokeStyle = "pink"; ctx.stroke(); ctx.restore(); } } </script> </body> </html> 

मैं किसी दूसरे पोस्ट पर अपना समाधान पोस्ट करने के बजाय, जोड़ने का फैसला करता हूं नीचे मैं जिस समाधान का निर्माण कर रहा हूं, वह सही नहीं है, लेकिन अब तक उत्पादन अच्छा है।

महत्वपूर्ण: यह सभी बिंदुओं से गुजरना होगा!

यदि आपके पास कोई विचार है, तो इसे बेहतर बनाने के लिए, कृपया मुझे साझा करें धन्यवाद।

यहां पहले की तुलना की गई है:

यहां छवि विवरण दर्ज करें

इसे जांचने के लिए इस कोड को HTML में सहेजें।

 <!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="1200" height="700" style="border:1px solid #d3d3d3;">Your browser does not support the HTML5 canvas tag.</canvas> <script> var cv = document.getElementById("myCanvas"); var ctx = cv.getContext("2d"); function gradient(a, b) { return (by-ay)/(bx-ax); } function bzCurve(points, f, t) { //f = 0, will be straight line //t suppose to be 1, but changing the value can control the smoothness too if (typeof(f) == 'undefined') f = 0.3; if (typeof(t) == 'undefined') t = 0.6; ctx.beginPath(); ctx.moveTo(points[0].x, points[0].y); var m = 0; var dx1 = 0; var dy1 = 0; var preP = points[0]; for (var i = 1; i < points.length; i++) { var curP = points[i]; nexP = points[i + 1]; if (nexP) { m = gradient(preP, nexP); dx2 = (nexP.x - curP.x) * -f; dy2 = dx2 * m * t; } else { dx2 = 0; dy2 = 0; } ctx.bezierCurveTo(preP.x - dx1, preP.y - dy1, curP.x + dx2, curP.y + dy2, curP.x, curP.y); dx1 = dx2; dy1 = dy2; preP = curP; } ctx.stroke(); } // Generate random data var lines = []; var X = 10; var t = 40; //to control width of X for (var i = 0; i < 100; i++ ) { Y = Math.floor((Math.random() * 300) + 50); p = { x: X, y: Y }; lines.push(p); X = X + t; } //draw straight line ctx.beginPath(); ctx.setLineDash([5]); ctx.lineWidth = 1; bzCurve(lines, 0, 1); //draw smooth line ctx.setLineDash([0]); ctx.lineWidth = 2; ctx.strokeStyle = "blue"; bzCurve(lines, 0.3, 1); </script> </body> </html> 

K3N के कार्डिनल स्प्लिने पद्धति में जोड़ने के लिए और संभवतः भ्रामक स्थानों में टीजे क्रॉडर के बारे में चिंताओं को 'डिपिंग' के बारे में पता करने के लिए, मैंने getCurvePoints() फ़ंक्शन में निम्न कोड डाला, बस res.push(x); से पहले res.push(x);

 if ((y < _pts[i+1] && y < _pts[i+3]) || (y > _pts[i+1] && y > _pts[i+3])) { y = (_pts[i+1] + _pts[i+3]) / 2; } if ((x < _pts[i] && x < _pts[i+2]) || (x > _pts[i] && x > _pts[i+2])) { x = (_pts[i] + _pts[i+2]) / 2; } 

यह प्रभावी रूप से लगातार अंकों के प्रत्येक जोड़ी के बीच एक (अदृश्य) सीमा बॉक्स बनाता है और यह सुनिश्चित करता है कि कवच इस बाउंडिंग बॉक्स में रहता है – यानी यदि वक्र पर एक बिंदु दोनों बिंदुओं के ऊपर / नीचे / बायां / दायां है, तो यह बॉक्स के भीतर होने की स्थिति बदलता है। यहां मिडपॉइंट का उपयोग किया जाता है, लेकिन यह सुधार किया जा सकता है, शायद रेखीय प्रक्षेप का उपयोग करना