Reputation: 3225
Maybe this is more a math question but lets see:
I'm using HTML5 Canvas to draw a line chart. The chart is basically Position X Time. Each line represents a vehicle in a position (Y) in a given time (X). I only have information about when a vehicle passed through determined points in the road. So if a vehicle stops between two points I don't have the information that it actually stoped, but when it passes through the next point I will be able to draw a line that will be almost horizontal, because the average speed, i.e. the line slope, will be really small.
In these scenarios we have defined that if a vehicle moved below 10Km/h I should consider that it made a stop and should draw a horizontal smooth line.
Basically I have to transform this:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.lineWidth = 5;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(0, 30);
ctx.lineTo(20, 50);
ctx.lineTo(220, 70);
ctx.lineTo(240, 110);
ctx.stroke();
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
Into this:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.lineWidth = 5;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(0, 30);
ctx.lineTo(20, 50);
ctx.bezierCurveTo(
50, 70,
210, 50,
220, 70
)
ctx.lineTo(240, 110);
ctx.stroke();
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
The problem is: how do I chose good values for the bezier points? In the above example I have done it experimentally. I cannot find a way to programatically pick good point values so my lines don't look bad like these:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.lineWidth = 5;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(0, 30);
ctx.lineTo(20, 50);
ctx.bezierCurveTo(
20, 70,
180, 50,
220, 70
)
ctx.lineTo(240, 110);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, 80);
ctx.lineTo(20, 100);
ctx.bezierCurveTo(
20, 120,
220, 100,
220, 120
)
ctx.lineTo(280, 150);
ctx.stroke();
<canvas id="myCanvas" width="300" height="170" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
I'm looking for a computationally simple solution because this is redrawn everytime with a lot of lines, so I don't want this melting down my performance.
Thanks for any tips!
Upvotes: 2
Views: 1229
Reputation: 3225
I found a good solution for my problem: Using line interpolation.
Having the following segments and imagine I want to smooth things between B
and C
, how can I choose some bezier points that would garantee a smooth curve instead of broken one?
First I interpolate the segment AB
and find the point B'
, which is the point the line AB
would touch the Y coordinate for C
. Then I use the same process to find C'
:
The points B'
and C'
make good points for the bezier in order to smooth things up to a horizontal line:
This is also being computationally simple enough since finding the a line equation is rather simple.
Upvotes: 3