// Fractional Axis Labeling // Bill "Bald Eagle" Walker Oct 2025 #version 3.8; global_settings {assumed_gamma 1.0} // +a0.001 +am2 +r3 camera { right x*image_width/image_height up y location <0, 5, 0> look_at <0, 0, 0> } #declare Zoom = 10; //60; camera { orthographic location <90, 0, -10> right x*image_width/Zoom up y*image_height/Zoom look_at <90, 0, 0> } #declare Origin = <0, 0, 0>; //light_source {<0, 5, -1> rgb 1.0} light_source {<90, 0, -100> rgb 1 shadowless} //sky_sphere {pigment {rgb x+y+z*0.6}} sky_sphere {pigment {rgb 0.4}} #declare E = 0.00001; #macro gcd (a, b) #if (b = 0) #local Result = a; #else #local Result = gcd (b, mod (a, b)); #end Result #end #macro gcdlcm (a, b) #local GCD = gcd (a, b); #local LCM = (a*b)/GCD; #local Result = array [2] {GCD, LCM}; Result #end //------------------------------------------------------------------------------------------------------------------- #macro ComputeFraction (_N, _Frac, optional ValueSymbol, optional Unit) #ifndef (Unit) #local Unit = ""; #end #if (_N = 0) #local Fraction = "0"; #else #local _GCD = gcd (_N, _Frac); //#debug concat ("N=",str(_N, 0, 3), " _Frac=", str(_Frac, 0, 3), " _GCD=", str(_GCD, 0, 3), " _N/_Frac=", str(_N/_Frac, 0, 3), " _N/_GCD=", str(_N/_GCD, 0, 3), "\n") #if (_GCD = 1) #local Fraction = concat (str(_N, 0, 0), "/", str(_Frac, 0, 0)); #else #if (_Frac/_GCD = 1) #ifdef (ValueSymbol) #if (_N/_GCD = 1) #local Fraction = concat (ValueSymbol, " ", Unit); #else #local Fraction = concat (str(_N/_GCD, 0, 0), " ", ValueSymbol, " ", Unit); #end #else #local Fraction = concat (str(_N/_GCD, 0, 0), " ", Unit); #end #else #ifdef (ValueSymbol) #if (_N/_GCD = 1) #local Fraction = concat (ValueSymbol, "/", str(_Frac/_GCD, 0, 0), " ", Unit); #else #local Fraction = concat (str(_N/_GCD, 0, 0), " ", ValueSymbol, "/", str(_Frac/_GCD, 0, 0), " ", Unit); #end #else #local Fraction = concat (str(_N/_GCD, 0, 0), "/", str(_Frac/_GCD, 0, 0), " ", Unit); #end #end #end #end Fraction #end //------------------------------------------------------------------------------------------------------------------- #macro DrawGraduatedLine (MaxVal, Frac, Step, Line, Color, Rotate, Decimal, Unit, optional ValueSymbol, optional Multiplier, optional MinSize) // Draw a line segment from 0 to MaxVal // Divide that up into MaxVal/Frac segments // Loop by Step #ifndef (Multiplier) #local Multiplier = 1; #end #local Texture = texture {pigment {rgb Color} finish {emission 0.5}} union { cylinder {<0, 0, 0>, Line texture {Texture}} #for (N, 0, MaxVal, Step) cylinder {, Line texture {Texture}} #if (Rotate) #local label = ComputeFraction (N, Frac, ValueSymbol, Unit); #ifdef (MinSize) #local Text = text { ttf "arial.ttf", label, 0.02, 0.0 scale max((1/MaxVal)*Multiplier, MinSize)*<0.6, 1, 1> rotate z*90} #local Max = max(abs(min_extent (Text).x), abs(max_extent (Text).x)); #local Half = Max/2; object {Text translate pigment {rgb 0}} #else #local Text = text { ttf "arial.ttf", label, 0.02, 0.0 scale (1/MaxVal)*Multiplier*<0.4, 1, 1> rotate z*90} #local Max = max(abs(min_extent (Text).x), abs(max_extent (Text).x)); #local Half = Max/2; object {Text translate pigment {rgb 0}} #end #else #local label = ComputeFraction (N, Frac, ValueSymbol, Unit); #ifdef (MinSize) #local Text = text { ttf "arial.ttf", label, 0.02, 0.0 scale max((1/MaxVal)*Multiplier, MinSize)*<0.4, 1, 1>} #local Max = max_extent (Text).x; #local Half = Max/2; object {Text translate pigment {rgb 0}} #else #local Text = text { ttf "arial.ttf", label, 0.02, 0.0 scale (1/MaxVal)*Multiplier*<0.4, 1, 1>} #local Max = max_extent (Text).x; #local Half = Max/2; object {Text translate pigment {rgb 0}} #end #end #if (Decimal) #local label2 = str(N/MaxVal, 0, Decimal); #ifdef (MinSize) #local Text = text { ttf "arial.ttf", label2, 0.02, 0.0 scale max((1/MaxVal)*Multiplier, MinSize)*<0.6, 1, 1> rotate z*90} #local Max = max(abs(min_extent (Text).x), abs(max_extent (Text).x)); #local Half = Max/2; object {Text translate pigment {rgb 0}} #else #local Text = text { ttf "arial.ttf", label2, 0.02, 0.0 scale (1/MaxVal)*Multiplier*<0.4, 1, 1> rotate z*90} #local Max = max(abs(min_extent (Text).x), abs(max_extent (Text).x)); #local Half = Max/2; object {Text translate pigment {rgb 0}} #end #end #end } #end text { ttf "arial.ttf", "Fractional Axis Labeling Bill \"Bald Eagle\" Walker Oct 2025", 0.02, 0.0 scale 5 translate <10, 45, 0> pigment {rgb z*0.2}} // object {DrawGraduatedLine (32, 32, 1, 0.1, x, no, no, "", , 5, 3) translate y*40} #debug "==========================================================================================================\n" object {DrawGraduatedLine (11, 11, 1, 0.1, y, no, no, "", , 15, 4) translate y*30} #debug "==========================================================================================================\n" object {DrawGraduatedLine (5, 5, 1, 0.1, z, no, no, "", , 33, 1) translate y*20} #debug "==========================================================================================================\n" object {DrawGraduatedLine (64, 64, 1, 0.1, x+z, yes, 3, "", , 2.6, 2.25) translate y*10} #debug "==========================================================================================================\n" DrawGraduatedLine (tau, tau, pi/12, 0.1, y+z, no, no, "", "pi", 25, ) #debug "==========================================================================================================\n" object {DrawGraduatedLine (tau, tau, tau/12, 0.1, x+y, no, no, "", "tau", 25, ) translate -y*10} #debug "==========================================================================================================\n" object {DrawGraduatedLine (18, 18, 1, 0.1, 1, no, no, "", , 9, 3) translate -y*20} #debug "==========================================================================================================\n" object {DrawGraduatedLine (tau, pi, pi/2, 0.1, 0, no, no, "radians", "pi", 25, ) translate -y*30} //#error "No objects in scene"