How to find out the rendered size of a curve in html5 canvas 2d?

8

I need to figure out the rendered size of a curve on 2d canvas

context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);

with this code, for example

// pontos de controle
var cp1x = 200,
    cp1y = 150,
    cp2x = 260,
    cp2y = 10;

var x = 0,
    y = 0;

// calculação
var curveWidth = cp1x > x ? cp1x - x : x - cp1x,
    curveHeight = cp1y > y ? cp1y - y : y - cp1y;

However, point cp2 can further lengthen the curve if it exceeds a starting or ending point (that is what happens in that code, cp1x = 200, cp2x = 260 ). For example, let's assume that point cp2 is marked with the red ball in this image and that its x-coordinate is greater than the x-coordinate of cp1, which appears to be the end point of the curve:

So, how can I consider the width of point cp2 in the value of curveWidth and in the value of curveHeight to be exact?

    
asked by anonymous 08.09.2016 / 13:36

1 answer

1

Comrade I found your question very interesting, I had never worked with bezier of the canvas and did a test to play.

I understood from your question that you want to know the distance from the left side to the rightmost curve point, which is the width of the curve.

I wish I could say something like curveWidth = cpx1 + ( (cpx2 - cpx1)/2 ) but in reality it is that in my tests I could not find a mathematical relation that remained constant, so this relation changes much according to the values of the variables at any moment.

But I noticed that in your question you are not seeing in the chart the 2 bezier control points and I believe this will make all the difference to improve your understanding of how you can find this distance.

Just as a debugging tool, I've made a code that might help you in this understanding and help you find a suitable answer, as follows:

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	
	<style>
		body { margin:0; padding:0;}
		#dot1 {background-color:red; position:absolute; z-index:999;}
		#dot2 {background-color:blue; position:absolute; z-index:998;}	
		#dot1,#dot2 {width:8px; height:8px;  border-radius: 8px;}
	</style>

	<!-- https://en.wikipedia.org/wiki/B%C3%A9zier_curve -->
</head>
<body>

	<span id="dot1"></span>
	<span id="dot2"></span>
	
	<canvas id="meucanvas" width="500" height="400" style="border:1px solid #d3d3d3;">
	Your browser does not support the HTML5 canvas tag.</canvas>

	<script>
	cp1x = 150;
	cp1y = 25;

	cp2x = 400;
	cp2y = 200;

	x = 300;
	y = 300;

	function cria_grafico(cp1x, cp1y, cp2x, cp2y, x, y)
	{
		var c = document.getElementById("meucanvas");
		var ctx = c.getContext("2d");
		
		ctx.clearRect(0, 0, 500, 400);		
		
			ctx.beginPath();
			ctx.moveTo(0, 0);
			
			ctx.strokeStyle = "#000000";
			ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
			ctx.stroke();
			
			ctx.strokeStyle = "#ff0000";
			ctx.strokeText("cp1 ( "+cp1x+", "+cp1y+" )", cp1x+10, cp1y+10);
			ctx.beginPath();
			ctx.moveTo(0,0);
			ctx.lineTo(cp1x,cp1y);
			ctx.stroke();				

	
			ctx.strokeStyle = "#0000ff";
			ctx.strokeText("cp2 ( "+cp2x+", "+cp2y+" )", cp2x+10, cp2y+10);	
			ctx.beginPath();
			ctx.moveTo(x,y);
			ctx.lineTo(cp2x,cp2y);
			ctx.stroke();				

			
		document.getElementById("dot1").style.left=cp1x+'px';
		document.getElementById("dot1").style.top=cp1y+'px';	
		

		document.getElementById("dot2").style.left=cp2x+'px';
		document.getElementById("dot2").style.top=cp2y+'px';	
	}	
	
	window.onload=function()
	{
	
		document.getElementById("cp1x").value = cp1x;
		document.getElementById("cp1y").value = cp1y;

		document.getElementById("cp2x").value = cp2x;
		document.getElementById("cp2y").value = cp2y;

		document.getElementById("x").value = x;
		document.getElementById("y").value = y;	

		cria_grafico(cp1x, cp1y, cp2x, cp2y, x, y);		
	
	}
	

	function redesenhar()
	{
		cp1x = parseInt( document.getElementById("cp1x").value );
		cp1y = parseInt( document.getElementById("cp1y").value );	

		cp2x = parseInt( document.getElementById("cp2x").value );
		cp2y = parseInt( document.getElementById("cp2y").value );	
		
		x = parseInt( document.getElementById("x").value );
		y = parseInt( document.getElementById("y").value );		

		cria_grafico(cp1x, cp1y, cp2x, cp2y, x, y);		
	}
	</script>	

	
	<br clear="both">
	
	cp1x: <input type="text" id="cp1x">
	cp1y: <input type="text" id="cp1y">

	<br><br>

	cp2x: <input type="text" id="cp2x">
	cp2y: <input type="text" id="cp2y">

	<br><br>
	
	x: <input type="text" id="x">
	y: <input type="text" id="y">	
	
	<input type="button" value="Redesenhar" onclick="redesenhar()">


</body>
</html>

If this answer helps you in anything give a +1, but do not mark my answer as you accept because I could not answer it. I would like you to post the answer to your problem when you can resolve it.

Good luck and hugs, Anything we change idea here in the question.

    
19.01.2017 / 18:14