/* higo_sweets.inc * * the HigoSweet() macro is a modernised + re-packaged version * of Tsutomu Higo's "Sweets" shapes. it uses a dictionary to * supply/control the available parameters. the macro returns * a 'union{}' of triangles shape, centred at origin. * * .Sweet int, req. range 1,..,6. * selects .. the variety. * * .Resolution int, opt, dflt '3'. range 1,..,10. * determines the number of triangles used to make * the "sweet". the value is multiplied by '24' * before use (ie, the '3' default equals TH's * original value of '72'). * * .Radius float, opt, dflt '100'. range .1,..,500. * a fixed value in TH's code. * * .Textured bool, opt, dflt 'true'. * added a metallic finish to TH's pigment. * * .VV float, opt. range 1,..,10. * corresponds to TH's 'Vsphe' variable. * * .VH float, opt. range 1,..,10. * corresponds to TH's 'Hsphe' variable. * * * ref http://www.asahi-net.or.jp/~nj2t-hg/ilpov21e.htm * * version 202204.1 */ #ifndef (th_sweets_include_temp) #declare th_sweets_include_temp = version; #version 3.8; #ifdef (View_POV_Include_Stack) #debug "including higo_sweets.inc\n" #end #macro th__isBool(v_) (0 = v_ | 1 = v_) #end #macro th__isInt(v_) (int(v_) = v_) #end /* make pairs of triangles */ #macro th__triangles(ah_,av_,aj_,ai_) #local pc_ = mod((ah_ - 1 + idict_.hmax_), idict_.hmax_); union { triangle { , , } triangle { , , } #if (idict_.textured_) texture { pigment {color rgb } finish { ambient .1 brilliance 6 diffuse .7 emission 0 metallic specular .8 roughness 1/120 reflection {.85} } } #end } #end /* create + populate the array */ #macro th__mkArr(d_) #local eps_ = 1e-6; #local d_.a_ = array [d_.hmax_] [(2 + d_.vmax_)] [4]; #for (k_,0,d_.vmax_+1) #for (j_,0,d_.hmax_-1) #for (i_,0,3) #local d_.a_[j_][k_][i_] = 0; #end #end #end #local i_ = 0; #while (i_ < d_.vmax_+2) #local j_ = 0; #while (j_ < d_.hmax_) #if (i_ = 0) #local smax_ = 0; #else #local smax_ = 0.999998*(i_-1)/d_.vmax_+eps_; #end #if (d_.ni_=0) #local d_.a_[j_][i_][3] = eps_ + d_.radius_ * (1 + (1 + cos(d_.vvs_ * 2 * pi * smax_ + pi)) * (1 + sin(d_.vhs_ * 2 * pi * j_/d_.hmax_ - pi / 3)) * sin(pi * smax_) / 4); #else #if (d_.nj_=1) #local d_.a_[j_][i_][3] = eps_ + 2 * d_.radius_ * (pow(abs(sin(2*pi*smax_-pi/4+pi/2-acos(1/sqrt(3)))),8/(d_.nj_+2)) * pow(abs(sin(2*pi-2*pi*j_/d_.hmax_+pi/4)),8/(d_.nj_+2)) + pow(abs(sin(2*pi-2*pi*smax_+pi/4-pi/2+acos(1/sqrt(3)))),8/(d_.nj_+2)) * pow(abs(sin(2*pi*j_/d_.hmax_+pi/4)),8/(d_.nj_+2))); #else #local d_.a_[j_][i_][3] = eps_ + 2 * d_.radius_ * pow(sin((d_.nj_+2) / 2 * pi * smax_), 8 / (d_.nj_+2)) * pow(sin((d_.nj_+2) / 2 * 2 * pi * j_/d_.hmax_), 8 / (d_.nj_+2)); #end #end #local d_.a_[j_][i_][0]=d_.a_[j_][i_][3]*sin(pi*smax_)*cos(2*pi*j_/d_.hmax_); #local d_.a_[j_][i_][1]=d_.a_[j_][i_][3]*sin(pi*smax_)*sin(2*pi*j_/d_.hmax_); #local d_.a_[j_][i_][2]=-d_.a_[j_][i_][3]*cos(pi*smax_); #local j_ = j_ + 1; #end #local i_ = i_ + 1; #end #end /* -------------------------------------------------------------------------- * * check all legal keys, supply defaults where needed, create corresponding * internal dictionary keys. * TH used a fixed "resolution" of '72' for calculations. instead use a * range of 1,..,10 and a multiplier of 24, but same default. * the '.v?s_' value calculations were copied. */ #macro th__chkRadius() #if (!defined(dict_.Radius)) #local r_ = 100; #elseif (.1 > dict_.Radius | 500 < dict_.Radius) #error "oops, out-of-range 'Radius' key (range .1-500)." #else #local r_ = dict_.Radius; #end r_ #end #macro th__chkResolution() #if (!defined(dict_.Resolution)) #local v_ = 3; #elseif (!th__isInt(dict_.Resolution)) #error "oops, bad 'Resolution' key, expect integer." #elseif (1 > dict_.Resolution | 10 < dict_.Resolution) #error "oops, out-of-range 'Resolution' key (range 1-10)." #else #local v_ = dict_.Resolution; #end (24 * v_) #end #macro th__chkSweet() #if (!defined(dict_.Sweet)) #error "oops, missing 'Sweet' key." #elseif (!th__isInt(dict_.Sweet)) #error "oops, bad 'Sweet' key, expect integer." #elseif (1 > dict_.Sweet | 6 < dict_.Sweet) #error "oops, out-of-range 'Sweet' key (range 1-6)." #end (dict_.Sweet - 1) #end #macro th__chkVHsph(v_) #if (1 > v_ | 10 < v_) #error "oops, out-of-range 'V?' key (range 1-10)." #end v_ #end #macro th__mkIdict(d_) #local d_.sweet_ = th__chkSweet(); #local d_.nj_ = mod(d_.sweet_,3); #local d_.ni_ = int(d_.sweet_ / 3); #local d_.resolution_ = th__chkResolution(); #local d_.vmax_ = d_.resolution_; #local d_.hmax_ = 2 * d_.vmax_; #local d_.radius_ = th__chkRadius(); #if (!defined(dict_.Textured)) #local d_.textured_ = true; #elseif (!th__isBool(dict_.Textured)) #error "oops, bad 'Textured' key, expect boolean." #else #local d_.textured_ = dict_.Textured; #end #if (!defined(dict_.VH)) #local d_.vhs_ = 3 + 3 * d_.nj_; #else #local d_.vhs_ = th__chkVHsph(dict_.VH); #end #if (!defined(dict_.VV)) #local d_.vvs_ = 1 + 2 * d_.nj_; #else #local d_.vvs_ = th__chkVHsph(dict_.VV); #end #end #macro HigoSweet(dict_) #local idict_ = dictionary; th__mkIdict(idict_) th__mkArr(idict_) #local j_ = 2; union { #while (j_ < idict_.vmax_ + 2) #local i_ = 0; #while (i_ < idict_.hmax_) th__triangles(i_,j_,idict_.nj_,idict_.ni_) #local i_ = i_ + 1; #end #local j_ = j_ + 1; #end } #end #version th_sweets_include_temp; #end /* --------------------------------------------------------------- * * the content above is covered by the GPLv3+, see file COPYING. * * copyright (c) 2022 jr . * * all rights reserved. * * --------------------------------------------------------------- */