Reworking continuous functions' rendering to make it faster.
Some checks failed
continuous-integration/drone/push Build is failing

+ Diminishing pixel precision from 1 to 10.
+ The change is barely noticable by the human eye in most functions.
+ Reworked domain checking to keep the pixel perfect precision.

The only visual degradations are functions with very high y variations for very small x variations (like cos and sin on log scale).
This commit is contained in:
Adsooi 2023-10-08 17:00:12 +02:00
parent 9f2b08b938
commit 7408520819
Signed by: Ad5001
GPG key ID: EF45F9C6AFE20160

View file

@ -115,9 +115,9 @@ class Function extends Common.ExecutableObject {
static drawFunction(canvas, ctx, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) { static drawFunction(canvas, ctx, expr, definitionDomain, destinationDomain, drawPoints = true, drawDash = true) {
// Reusable in other objects. // Reusable in other objects.
// Drawing small traits every 0.2px // Drawing small traits every 0.2px
var pxprecision = 1 var pxprecision = 10
var previousX = canvas.px2x(0) var previousX = canvas.px2x(0)
var previousY; var previousY = null;
if(definitionDomain instanceof MathLib.SpecialDomain && definitionDomain.moveSupported) { if(definitionDomain instanceof MathLib.SpecialDomain && definitionDomain.moveSupported) {
// Point based functions. // Point based functions.
previousX = definitionDomain.next(previousX) previousX = definitionDomain.next(previousX)
@ -147,17 +147,42 @@ class Function extends Common.ExecutableObject {
ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10) ctx.fillRect(canvas.x2px(previousX)-1, canvas.y2px(previousY)-5, 2, 10)
} }
} else { } else {
previousY = expr.execute(previousX) if(definitionDomain.includes(previousX))
for(var px = pxprecision; px < canvas.canvasSize.width; px += pxprecision) { // PreviousY at the start of the canvas
var currentX = canvas.px2x(px) previousY = expr.execute(previousX)
var currentY = expr.execute(currentX) for(let px = pxprecision; px < canvas.canvasSize.width; px += pxprecision) {
if((definitionDomain.includes(currentX) || definitionDomain.includes(previousX)) && let currentX = canvas.px2x(px)
(destinationDomain.includes(currentY) || destinationDomain.includes(previousY)) && if(!definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) {
Math.abs(previousY-currentY)<100) { // Should draw up to currentX, but NOT at previousX.
canvas.drawLine(ctx, canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY)) // Need to find the starting point.
let tmpPx = px-pxprecision
do {
tmpPx++;
previousX = canvas.px2x(tmpPx)
} while(!definitionDomain.includes(previousX))
// Recaclulate previousY
previousY = expr.execute(previousX)
} else if(!definitionDomain.includes(currentX)) {
// Next x is NOT in the definition domain.
// Augmenting the pixel precision until this condition is fulfilled.
let tmpPx = px
do {
tmpPx--;
currentX = canvas.px2x(tmpPx)
} while(!definitionDomain.includes(currentX) && currentX != previousX)
}
if(definitionDomain.includes(previousX) && definitionDomain.includes(currentX)) {
let currentY = expr.execute(currentX)
if(destinationDomain.includes(currentY)) {
if(previousY != null && destinationDomain.includes(previousY)) {
canvas.drawLine(ctx, canvas.x2px(previousX), canvas.y2px(previousY), canvas.x2px(currentX), canvas.y2px(currentY))
}
} }
previousX = currentX previousY = currentY
previousY = currentY } else {
previousY = null // Last y was invalid, so let's not draw anything from it.
}
previousX = canvas.px2x(px)
} }
} }
} }