// Last edited on 2024-07-25 18:08:46 by stolfi #debug "!! Loading fan_choose_planes.inc ...\n" #macro fan_choose_planes(V, Neo,Nei,oshape,show_planes) // Chooses the {Z} coordinates of the slicing planes. Parameters: // // {V[1..Nv]} The verices. // {Neo} Number of edges in the outer chain of each plaza. // {Nei} Number of edges in the inner chain of each plaza. // {oshape} Shape of outer chain. // {show_planes} Should we show the planes? // // Assumes that {V[1..Neo+1]} are the vertices of the outer chain of plaza [0]. // Assumes that {V[Neo+2..Neo+Nei+2]} are the vertices of the inner chain of plaza [0]. // // Returns array {Z[1..Np]} of {Z}-coordinates. #debug "!! Choosing {Z} of slicing planes ...\n" #local Nv = dimension_size(V, 1) - 1; #if (mod(Nei,2) != 0) kaboom("{Nei} is not even") #end #local kvo_ini = 1; // Index of first vertex on outer chain of plaza [0]. #local kvi_ini = Neo+2; // Index of first vertex on inner chain of plaza [0]. #if (show_planes = 0) // No slicing planes: #local Np = 0; #local Zp = array[Np+1]; #elseif (oshape = 0) // Convex outer chain, concave inner chain. // One slicing plane through each outer chain edge: #local Np = Neo; #local Zp = array[Np+1]; #for (kp,1,Np) #local V0 = V[kp]; // fan_debug_vertex("V0", kp, V0) #local V1 = V[kp+1]; // fan_debug_vertex("V1", kp+1, V1) #local Zp[kp] = (V0.z + V1.z)/2; #end #elseif (oshape = 1) // Slightly dented outer chain, concave inner chain. // One slicing plane through every other outer chain edge: #local Np = int(Neo/2); #if (Neo != Np*2) kaboom("Number of outer chain edges must be even") #end #local Zp = array[Np+1]; #for (kp,1,Np) #local V0 = V[2*kp]; // fan_debug_vertex("V0", 2*kp, V0) #local V1 = V[2*kp+1]; // fan_debug_vertex("V1", 2*kp+1, V1) #local Zp[kp] = (V0.z + V1.z)/2; #end #elseif ((oshape = 2) | ( oshape = 3)) // Concave or deeply dented chains: // Pick {Neo-1} equally spaced slicing planes that avoid inner and outer chains: #local Zomin = +999999; // Min {Z} of outer chain vertices. #for (iv,0,Neo) #local kvo = kvo_ini + iv; #local Zok = V[kvo].z; #if (Zok < Zomin) #local Zomin = Zok; #end #end #local Zimax = -999999; // Max {Z} of inner chain vertices. #for (iv,0,Nei) #local kvi = kvi_ini + iv; #local Zik = V[kvi].z; #if (Zik > Zimax) #local Zimax = Zik; #end #end #local Np = #if (oshape = 2) Neo-1; #else Neo/2; #end #local Zp = array[Np+1]; #for (kp,1,Np) #local s = (kp + 2)/(Np + 3); #local Zp[kp] = (1-s)*Zimax + s*Zomin; #end #else kaboom("invalid oshape") #end #local Zp[0] = -1; // Unused element. Zp #end