From 36974e6086e0aa5e90b48da45b1be5681bf66430 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Sep 17 2023 13:15:59 +0000 Subject: #assistants: fix fish eye grid --- diff --git a/toonz/sources/tnztools/assistants/assistantellipse.cpp b/toonz/sources/tnztools/assistants/assistantellipse.cpp index 4b24ac7..c7b5646 100644 --- a/toonz/sources/tnztools/assistants/assistantellipse.cpp +++ b/toonz/sources/tnztools/assistants/assistantellipse.cpp @@ -414,7 +414,7 @@ void TAssistantEllipse::drawParallelGrid( TAffine screenMatrixInv = screenMatrix.inv(); double pixelSize = sqrt(tglGetPixelSize2()); - double minStep = 10.0*pixelSize; + double minStep = (perspective ? 5 : 10)*pixelSize; TAffine ellipseMatrixInv = ellipseMatrix.inv(); const TAffine &em = ellipseMatrix; @@ -435,18 +435,38 @@ void TAssistantEllipse::drawParallelGrid( ranges.add( TAngleRangeSet::fromDouble(0.0), TAngleRangeSet::fromDouble(M_PI) ); if (perspective) { - // draw perspective (actually angular) - double a0 = asin(gs0); - double a1 = asin(gs1); - double da = fabs(a1 - a0); - if (fabs(sin(da)) < 2.0*actualMinStep) return; - for(double a = a0 + ceil((-M_PI_2 - a0)/da)*da; a < M_PI_2; a += da) + // draw perspective + if (!( fabs(gs0) < 1 - TConsts::epsilon + && fabs(gs1) < 1 - TConsts::epsilon + && fabs(gs1 - gs0) > TConsts::epsilon )) return; + + // the formula is: x = i/sqrt(1 + i*i) + + double ig0 = gs0/sqrt(1 - gs0*gs0); + double ig1 = gs1/sqrt(1 - gs1*gs1); + double di = fabs(ig1 - ig0); + double i0 = ig0 - round(ig0/di)*di; + + actualMinStep /= 2; + for(int j = 0; j < 2; ++j, di = -di, i0 += di) + for(double i = i0; i+di != i; i += di) { + double x = i/sqrt(1 + i*i); + + double curAlpha = 1; + if (fabs(i0) > TConsts::epsilon) { + double curStep = fabs( di*x*(1 - x*x)/i ); + curAlpha = (curStep - actualMinStep)/actualMinStep; + if (curAlpha < 0) { if (i == i0) continue; else break; } + if (curAlpha > 1) curAlpha = 1; + } + drawEllipseRanges( ranges, - ellipseMatrix*TAffine::scale(a < 0.0 ? -1.0 : 1.0, sin(a)), + ellipseMatrix*TAffine::scale(x < 0.0 ? -1.0 : 1.0, x), screenMatrixInv, pixelSize, - alpha ); + alpha * curAlpha ); + } } else { // draw linear double dx = fabs(gs1 - gs0);