// Last edited on 2024-05-27 23:36:07 by stolfi #macro nut_slicepoly(V, E, Nr, kr_start_o, kr_start_i, subfig) // The edges and vertices of the slice outline. Parameters: // {V} Array of vertex coordinates {V[1..Nv]}. // {E} Array of edges {E[1..Ne]}, each a pair "" of indices into {V}. // {kr_start_o} Rotation index of starting outer quine. // {kr_start_i} Rotation index of starting inner quine. // {subfig} Which sub-figure we are generating. #local Nv = dimension_size(V, 1) - 1; #local Ne = dimension_size(E, 1) - 1; #if (subfig = 0) #local spol = object{ nothing scale 1.75 } // For now. #else #local spol = union{ #if (((subfig >= 1) & (subfig <= 4)) | (subfig = 8)) // Plot the outer polygon: #if ((subfig >= 1) & (subfig <= 3)) #local nr_plot_o = subfig - 1; #else #local nr_plot_o = Nr; #end nut_slicepoly_plot(E, V, Nr, kr_start_o, nr_plot_o, +1, nut_tx_opoly) #end #if (((subfig >= 5) & (subfig <= 7)) | (subfig = 8)) // Plot the inner polygon: #if ((subfig >= 5) & (subfig <= 6)) #local nr_plot_i = subfig - 5; #else #local nr_plot_i = Nr; #end nut_slicepoly_plot(E, V, Nr, kr_start_i, nr_plot_i, -1, nut_tx_ipoly) #end // Dummy objects to avoid stupid Pov-Ray warning: object{ nothing } object{ nothing scale 2 } } #end spol #end #macro nut_slicepoly_plot(E, V, Nr, kr_start, nr_plot, dir, tx) // Generates the first {nr_plot} edges of a slice polygon: // outer if {dir = +1}, inner if {dir = -1}. // Also generates the required vertices of the polygon. // Assumes that the polygon has {Nr} vertices total which are the midpoints of the // quine edges whose indices are {Ke[0..Nr-1]}. The vertices plotted start // with the midpoint of edge {E[Ke[kr_start]]} and proceeds in the direction {dir} // in the {Ke} list, wrapping around. #debug "!! Generating the sliced polygon ...\n" // Collect all quines, in rotation order: #local inner = (dir = -1); #local Ke = nut_collect_quines(E, inner) #if (dimension_size(Ke,1) != Nr) kaboom("poly: {Ke} does not have {Nr} edges") #end #for (dr, 0, nr_plot) #local kr_this = mod(Nr + kr_start + dir*dr, Nr); #local kr_next = mod(kr_this + Nr + dir, Nr); // #debug concat("!! slicepoly_plot: dir = ", str(dir,0,0), " kr_this = ", str(kr_this,0,0), " kr_next = ", str(kr_next,0,0), "\n") #if (dr < Nr) nut_slicepoly_vert(E, V, Ke[kr_this], tx) #end #if (dr < nr_plot) nut_slicepoly_edge(E, V, Ke[kr_this], Ke[kr_next], tx) #end #end #end #macro nut_slicepoly_vert(E, V, ke, tx) #local vrad = 2.0; #local Vp = nut_slicepoly_compute_vert(E, V, ke); sphere{ Vp, vrad texture{ tx }} #end #macro nut_slicepoly_edge(E, V, ke_this, ke_next, tx) #local erad = 0.8; #local Vp_this = nut_slicepoly_compute_vert(E, V, ke_this); #local Vp_next = nut_slicepoly_compute_vert(E, V, ke_next); object{ gen_arrow(Vp_this, Vp_next, erad, 0.75,12.0*erad, 0.50,0) texture{ tx } } // cylinder{ Vp_this, Vp_next, erad texture{ tx }} #end #macro nut_slicepoly_compute_vert(E, V, ke) #local Vorg = V[E[ke].x]; // Origin vertex. #local Vdst = V[E[ke].y]; // Destination vertex. #local Vp = (Vorg + Vdst)/2; Vp #end