I'm trying to figure out the max arc distance [SOLVED]

Hi, right now, I am working on a filter, and I need to know how to get predicted max distance. This is the gradient code. error_margin is predicted distance away from center due to rasterization error. It comes close enough even though it does not end on zero.

spiral
rep_mjw_rectangle2archimedeanspiral:

f "begin(
 const mult=10;
 const ww=w-1;
 const hh=h-1;
 const half_ww=ww/2;
 const half_hh=hh/2;
 const error_margin_x=ceil(half_ww)-half_ww;
 const error_margin_y=ceil(half_hh)-half_hh;
 const sd=max(ww,hh)/min(ww,hh);
 const lerp_factor=min(sd,1)/max(sd,1);
 const error_margin_avg=avg(error_margin_x,error_margin_y)/mult;
 const error_margin_sqrt=sqrt(sqr(error_margin_x)+sqr(error_margin_y))/mult;
 const error_margin=lerp(error_margin_sqrt,error_margin_avg,lerp_factor);
 const sx=w>h?sd:1;
 const sy=w>h?1:sd;
 const dpi=2*pi;
);
xx=(x-half_ww)/half_ww*sx;
yy=(y-half_hh)/half_hh*sy;
atan_ang=atan2(yy,xx);
rad=sqrt(sqr(xx)+sqr(yy))*mult;
spiral=(atan_ang+dpi)/dpi+rad;
spiral=spiral-int(spiral);
spirallength=1-.5*spiral+.5*rad;
spirallength/=mult;
error_margin;
spirallength-=error_margin;
sd;
"

The max distance is given by the maximum value.

A code to generate values that determines actual max distance
rep_find_max_dist_rect:
sw=$1
sh={$sw}
graph_data=0
repeat $sw-1
 $sw,$sh
 rep_mjw_rectangle2archimedeanspiral
 sh-=1
 if !$>
  graph_data={iM#-1}
 else
  temp_data={iM#-1}
  graph_data.=,
  graph_data.=$temp_data
 fi
 rm
done
v + echo $graph_data v -

As you can see, as one of the image dimension approaches zero, the max distance gets bigger and bigger.

My task is to find a equation that’ll allow me to find the max distance based on image ratio. From what I see, for some reason, the result reminds me of a logarithmic curve.

Also a reference I found which I have no idea what to do with it:

https://mathworld.wolfram.com/ArchimedesSpiral.html

And this - 1/2 * a * [t * sqrt(1 + t^2) + log(t + sqrt(1 + t^2))]

As in Arc length - Wikipedia?

Yes, that is what I’m thinking about. I really wanna know the arc length using exponential factor along exponential radial gradient, cropped spiral from atan+radial, angle, and the greatest length inside the cropped area.


I actually got something here. It’s not much.

The good news, spiral length is expected. The bad news. It doesn’t correspond with the spiral gradient on the left, and I would like to figure this out. To expand, I would like to know the value on the right side quadrant point of the left image.

r 100%,100%,1,2
f "begin(
 const mult=$1;
 const ww=w-1;
 const hh=h-1;
 const half_ww=ww/2;
 const half_hh=hh/2;
 const error_margin_x=ceil(half_ww)-half_ww;
 const error_margin_y=ceil(half_hh)-half_hh;
 const sd=max(ww,hh)/min(ww,hh);
 const lerp_factor=min(sd,1)/max(sd,1);
 const error_margin_avg=avg(error_margin_x,error_margin_y)/mult;
 const error_margin_sqrt=sqrt(sqr(error_margin_x)+sqr(error_margin_y))/mult;
 const error_margin=lerp(error_margin_sqrt,error_margin_avg,lerp_factor);
 const sx=w>h?sd:1;
 const sy=w>h?1:sd;
 const dpi=2*pi;
 const arc_ang=pi*1;
 const arc_length=.5*mult*(arc_ang*sqrt(1+sqr(arc_ang))+log(1+sqr(arc_ang)));
);
xx=(x-half_ww)/half_ww*sx;
yy=(y-half_hh)/half_hh*sy;
atan_ang=atan2(yy,xx);
rad=sqrt(sqr(xx)+sqr(yy))*mult;
spiral=(atan_ang+dpi)/dpi+rad;
spiral=spiral-int(spiral);
spirallength=1-.5*spiral+.5*rad;
spirallength-=error_margin;
[spirallength,arc_length];
"
s c


I checked with this finding:

“As the Archimedean spiral grows, its evolute asymptotically approaches a circle with radius
|v|/ω”

It is closer when I checked with the difference of two different angle.

Also, I find that instances of radian(90*n) do correspond to numbers I want. I will confirm a pattern. n is a integer.

Ok, I think I found the solution. I decided to find arc_length without using the mumbo jumbo on the above post. My solution was to use px,py, and then use the calc_spiral(a,b) macro to find the arc length. My test shows that scaling is consistent. Now all I need to do is to address some limitations.

Also, adding const to sl cause a error. Not sure why though.

rep_archimedean:

r 100%,100%,1,1
f "begin(
 const mult=$1;
 const ww=w-1;
 const hh=h-1;
 const half_ww=ww/2;
 const half_hh=hh/2;
 const error_margin_x=ceil(half_ww)-half_ww;
 const error_margin_y=ceil(half_hh)-half_hh;
 const sd=max(ww,hh)/min(ww,hh);
 const lerp_factor=min(sd,1)/max(sd,1);
 const error_margin_avg=avg(error_margin_x,error_margin_y)/mult;
 const error_margin_sqrt=sqrt(sqr(error_margin_x)+sqr(error_margin_y))/mult;
 const error_margin=lerp(error_margin_sqrt,error_margin_avg,lerp_factor);
 const sx=w>h?sd:1;
 const sy=w>h?1:sd;
 const dpi=2*pi;
 calc_spiral(atan_ang,rad)=(
  spiral=(atan_ang+dpi)/dpi+rad;
  spiral=spiral-int(spiral);
  spirallength=1-.5*spiral+.5*rad;
 );
 const px=atan2(0,1);
 const py=sqrt(1)*mult;
 sl=calc_spiral(px,py);
);
xx=(x-half_ww)/half_ww*sx;
yy=(y-half_hh)/half_hh*sy;
atan_ang=atan2(yy,xx);
rad=sqrt(sqr(xx)+sqr(yy))*mult;
spiral=calc_spiral(atan_ang,rad);
spiral/sl;
"

It is a function?

const basically means the value of the variable that follows can be determined at compile-time (when compiling the math expression into bytecode).
This means that every term after the equal sign must be a const value itself.
It’s not the case in your expression, because arguments atan_ang and rad are not const values (their values are not the same for every point (x,y)).

If I replace the macro expression variables with a,b, then it still wouldn’t work.

That being said, I got around that, and new bug: Just remove the ## block in the fill block, and then the output is not what it suppose to look like. The spiral is no longer there. Put the ## again, and then it’ll work. Why? It can be solved by dividing next to it instead of doing this, but nonetheless I think it’s a bug.

Reptorian's Archimedean
$ 500,500 rep_archimedean 1 

rep_archimedean:

#spl=spiral_point_location#
#sl=spiral_length#

f "begin(
 const ww=w-1;
 const hh=h-1;
 const half_ww=ww/2;
 const half_hh=hh/2;
 const error_margin_x=ceil(half_ww)-half_ww;
 const error_margin_y=ceil(half_hh)-half_hh;
 const sd=max(ww,hh)/min(ww,hh);
 const spl=abs($1);
 const sl=1+spl*.5;
 const dpi=2*pi;
 const hpi=pi/2;
 const spl_x=spl*cos(spl*dpi-hpi);
 const spl_y=spl*sin(spl*dpi-hpi);
 const spl_xy_ang=atan2(spl_y,spl_x);
 const lerp_factor=min(sd,1)/max(sd,1);
 const error_margin_avg=avg(error_margin_x,error_margin_y)/spl;
 const error_margin_sqrt=sqrt(sqr(error_margin_x)+sqr(error_margin_y))/spl;
 const pre_error_margin=lerp(error_margin_sqrt,error_margin_avg,lerp_factor);
 const sx=w>h?sd:1;
 const sy=w>h?1:sd;
 calc_spiral(a,b)=(
  spiral=(a+dpi)/dpi+b;
  new_spiral=spiral-int(spiral);
  spirallength=1-.5*new_spiral+.5*b;
 );
);
xx=(x-half_ww)/half_ww*sx*spl;
yy=(y-half_hh)/half_hh*sy*spl;
atan_ang=atan2(yy,xx);
rad=sqrt(sqr(xx)+sqr(yy));
spiral=calc_spiral(atan_ang,rad);
#spiral/=sl;#
"

Because fill set the value of the pixel according to the last term of the equation ?
If you remove the last term, then the values are different.