// Caption: Shape grid macro
// Version: 1.17
// Authors: Michael Horvath, with formulas by And and Tor Olav Kristensen
// Website: http://isometricland.net
// Created: 2008-06-22
// Updated: 2018-08-23
// This file is licensed under the terms of the CC-LGPL.
#version 3.7;
#include "math.inc"
#include "shapes.inc"
#include "MakeGradientMagnitudeFunction.inc" // http://news.povray.org/povray.binaries.images/message/%3Cweb.5b5e768edce0719a79917fa00%40news.povray.org%3E/#%3Cweb.5b5e768edce0719a79917fa00%40news.povray.org%3E
//--------------------------------------Debug
#declare SGrid_Debug_Flag = true;
#ifndef (SGrid_Debug_Flag) #declare SGrid_Debug_Flag = false; #end
#macro SGrid_Debug_Macro(In_Text)
#if (SGrid_Debug_Flag = true)
#debug In_Text
#end
#end
#declare point_count = 1;
#declare point_array = array[point_count];
#macro SGrid_Display_Points()
SGrid_Debug_Macro(concat("point_count = ", str(point_count,0,0), "\n"))
#for (i, 0, point_count-1)
#local xy_coords = point_array[i];
#debug concat("xy_coords: <", vstr(2,xy_coords,",",0,5), ">\n")
sphere
{
, 0.01
rotate y * 90
pigment {color rgb x+y}
}
#end
SGrid_Debug_Macro("\n")
#end
//--------------------------------------Line intersection, adapted from https://stackoverflow.com/questions/20677795
#macro SGrid_Line(p1, p2)
#local A = p1.y - p2.y;
#local B = p2.x - p1.x;
#local C = p1.x * p2.y - p2.x * p1.y;
#end
#macro SGrid_Line_Intersection(l1, l2)
#local D = l1.x * l2.y - l1.y * l2.x;
#local Dx = l1.z * l2.y - l1.y * l2.z;
#local Dy = l1.x * l2.z - l1.z * l2.x;
#if (D != 0)
#local out_x = Dx / D;
#local out_y = Dy / D;
#local out_value = ;
#else
#local out_value = <0,0,0>;
#end
out_value
#end
//--------------------------------------Ellipsoid latitudes
#macro SGrid_convert_geodetic_to_geocentric(radius_major, radius_minor, lat_geodetic)
#local ellipseF = (1 - radius_minor/radius_major) / 1;
atand(pow(1 - ellipseF, 2) * tand(lat_geodetic));
#end
#macro SGrid_convert_geodetic_to_reduced(radius_major, radius_minor, lat_geodetic)
#local ellipseF = (1 - radius_minor/radius_major) / 1;
atand((1 - ellipseF) * tand(lat_geodetic));
#end
//--------------------------------------Cone
#macro SGrid_Cone_Macro
(
SGrid_Cone_radii, // The number of radial divisions. (integer)
SGrid_Cone_longt, // The number of longitudinal divisions. (integer)
SGrid_Cone_latit, // The number of lattitudinal divisions. (integer)
SGrid_Cone_radius, // The radius of each cone. (float)
SGrid_Cone_height, // The height of each cone. (float)
SGrid_Cone_center, // The center coordinates of the double-cone. (vector)
SGrid_Cone_thickness, // The thickness of the grid lines. (float)
SGrid_Cone_offset, // Determines whether the divisions are offset by half the amount. Sometimes necessary when doing cut-aways. (boolian)
SGrid_Cone_endcap, // Determines whether borders are created at each end of the object. Ignored if the offset is turned on. (boolian)
)
#local SGrid_Cone_bounds = cone {0, SGrid_Cone_radius, <0,SGrid_Cone_height,0,>, 0}
union
{
#local SGrid_Cone_increment = 1/SGrid_Cone_radii;
#local SGrid_Cone_i = 0;
#local SGrid_Cone_start = 0;
#if (SGrid_Cone_offset = on)
#local SGrid_Cone_start = SGrid_Cone_increment/2;
#end
#while (SGrid_Cone_i < SGrid_Cone_radii)
#local SGrid_Cone_value = SGrid_Cone_radius * (SGrid_Cone_start + SGrid_Cone_i * SGrid_Cone_increment);
#local SGrid_Cone_angle = atan2d(SGrid_Cone_value, SGrid_Cone_height);
#local SGrid_Cone_offsl = SGrid_Cone_thickness/2 * 1/cosd(SGrid_Cone_angle);
#local SGrid_Cone_offsv = SGrid_Cone_thickness/2 * 1/cosd(90 - SGrid_Cone_angle);
difference
{
cone {0, SGrid_Cone_value + SGrid_Cone_offsl, <0,SGrid_Cone_height+SGrid_Cone_offsv,0,>, 0}
cone {0, SGrid_Cone_value - SGrid_Cone_offsl, <0,SGrid_Cone_height-SGrid_Cone_offsv,0,>, 0}
bounded_by {SGrid_Cone_bounds}
}
SGrid_Debug_Macro(concat("cone_radii_value = ", str(SGrid_Cone_value, 0, -1),"\n"))
#local SGrid_Cone_i = SGrid_Cone_i + 1;
#end
#local SGrid_Cone_increment = 1/SGrid_Cone_longt;
#local SGrid_Cone_i = 0;
#local SGrid_Cone_start = 0;
#if (SGrid_Cone_offset = on)
#local SGrid_Cone_start = SGrid_Cone_increment/2;
#end
#while (SGrid_Cone_i < SGrid_Cone_longt)
#local SGrid_Cone_value = 360 * (SGrid_Cone_start + SGrid_Cone_i * SGrid_Cone_increment);
box
{
<2*SGrid_Cone_radius, 2*SGrid_Cone_radius, SGrid_Cone_thickness/2,>,
<0, -2*SGrid_Cone_radius, -SGrid_Cone_thickness/2,>
rotate y * SGrid_Cone_value
bounded_by {SGrid_Cone_bounds}
}
SGrid_Debug_Macro(concat("cone_longt_value = ", str(SGrid_Cone_value, 0, -1),"\n"))
#local SGrid_Cone_i = SGrid_Cone_i + 1;
#end
#local SGrid_Cone_increment = 1/SGrid_Cone_latit;
#local SGrid_Cone_i = 0;
#if (SGrid_Cone_endcap = on)
#local SGrid_Cone_start = 0;
#local SGrid_Cone_finish = SGrid_Cone_radii + 1;
#else
#local SGrid_Cone_start = SGrid_Cone_increment;
#local SGrid_Cone_finish = SGrid_Cone_latit - 1;
#end
#if (SGrid_Cone_offset = on)
#local SGrid_Cone_start = SGrid_Cone_increment/2;
#local SGrid_Cone_finish = SGrid_Cone_latit;
#end
#while (SGrid_Cone_i < SGrid_Cone_finish)
#local SGrid_Cone_value = SGrid_Cone_height * (SGrid_Cone_start + SGrid_Cone_i * SGrid_Cone_increment);
box
{
,
<-SGrid_Cone_radius,-SGrid_Cone_thickness/2,-SGrid_Cone_radius,>
bounded_by {SGrid_Cone_bounds}
translate y * SGrid_Cone_value
}
SGrid_Debug_Macro(concat("cone_latit_value = ", str(SGrid_Cone_value, 0, -1),"\n"))
#local SGrid_Cone_i = SGrid_Cone_i + 1;
#end
translate SGrid_Cone_center
}
#end
//--------------------------------------Cylinder
#macro SGrid_Cylinder_Macro
(
SGrid_Cylinder_radii, // The number of radial divisions. (integer)
SGrid_Cylinder_longt, // The number of longitudinal divisions. (integer)
SGrid_Cylinder_latit, // The number of lattitudinal divisions. (integer)
SGrid_Cylinder_radius, // The radius of the cylinder. (float)
SGrid_Cylinder_height, // The height of the cylinder. (float)
SGrid_Cylinder_center, // The center coordinates of the cylinder. (vector)
SGrid_Cylinder_thickness, // The thickness of the grid lines. (float)
SGrid_Cylinder_offset, // Determines whether the divisions are offset by half the amount. Sometimes necessary when doing cut-aways. (boolian)
SGrid_Cylinder_endcap, // Determines whether borders are created at each end of the object. Ignored if the offset is turned on. (boolian)
)
#local SGrid_Cylinder_bounds = cylinder {0, <0,SGrid_Cylinder_height,0,>, SGrid_Cylinder_radius}
union
{
#local SGrid_Cylinder_increment = 1/SGrid_Cylinder_radii;
#local SGrid_Cylinder_i = 0;
#local SGrid_Cylinder_start = 0;
#if (SGrid_Cylinder_offset = on)
#local SGrid_Cylinder_start = SGrid_Cylinder_increment/2;
#end
#while (SGrid_Cylinder_i < SGrid_Cylinder_radii)
#local SGrid_Cylinder_value = SGrid_Cylinder_radius * (SGrid_Cylinder_start + SGrid_Cylinder_i * SGrid_Cylinder_increment);
difference
{
cylinder {0, y, SGrid_Cylinder_value + SGrid_Cylinder_thickness/2}
cylinder {0, y, SGrid_Cylinder_value - SGrid_Cylinder_thickness/2}
bounded_by {SGrid_Cylinder_bounds}
}
SGrid_Debug_Macro(concat("cylinder_radii_value = ", str(SGrid_Cylinder_value, 0, -1),"\n"))
#local SGrid_Cylinder_i = SGrid_Cylinder_i + 1;
#end
#local SGrid_Cylinder_increment = 1/SGrid_Cylinder_longt;
#local SGrid_Cylinder_i = 0;
#local SGrid_Cylinder_start = 0;
#if (SGrid_Cylinder_offset = on)
#local SGrid_Cylinder_start = SGrid_Cylinder_increment/2;
#end
#while (SGrid_Cylinder_i < SGrid_Cylinder_longt)
#local SGrid_Cylinder_value = 360 * (SGrid_Cylinder_start + SGrid_Cylinder_i * SGrid_Cylinder_increment);
box
{
<2*SGrid_Cylinder_radius, 2*SGrid_Cylinder_radius, SGrid_Cylinder_thickness/2,>,
<0, -2*SGrid_Cylinder_radius, -SGrid_Cylinder_thickness/2,>
rotate y * SGrid_Cylinder_value
}
SGrid_Debug_Macro(concat("cylinder_logt_value = ", str(SGrid_Cylinder_value, 0, -1),"\n"))
#local SGrid_Cylinder_i = SGrid_Cylinder_i + 1;
#end
#local SGrid_Cylinder_increment = 1/SGrid_Cylinder_latit;
#local SGrid_Cylinder_i = 0;
#if (SGrid_Cylinder_endcap = on)
#local SGrid_Cylinder_start = 0;
#local SGrid_Cylinder_finish = SGrid_Cylinder_latit + 1;
#else
#local SGrid_Cylinder_start = SGrid_Cylinder_increment;
#local SGrid_Cylinder_finish = SGrid_Cylinder_latit - 1;
#end
#if (SGrid_Cylinder_offset = on)
#local SGrid_Cylinder_start = SGrid_Cylinder_increment/2;
#local SGrid_Cylinder_finish = SGrid_Cylinder_latit;
#end
#while (SGrid_Cylinder_i < SGrid_Cylinder_finish)
#local SGrid_Cylinder_value = SGrid_Cylinder_height * (SGrid_Cylinder_start + SGrid_Cylinder_i * SGrid_Cylinder_increment);
box
{
<-2*SGrid_Cylinder_radius, -SGrid_Cylinder_thickness/2, -2*SGrid_Cylinder_radius,>,
<2*SGrid_Cylinder_radius, SGrid_Cylinder_thickness/2, 2*SGrid_Cylinder_radius,>
translate y * SGrid_Cylinder_value
bounded_by {SGrid_Cylinder_bounds}
}
SGrid_Debug_Macro(concat("cylinder_latit_value = ", str(SGrid_Cylinder_value, 0, -1),"\n"))
#local SGrid_Cylinder_i = SGrid_Cylinder_i + 1;
#end
translate SGrid_Cylinder_center
}
#end
//--------------------------------------Double cone
#macro SGrid_DblCone_Macro
(
SGrid_DblCone_radii, // The number of radial divisions. (integer)
SGrid_DblCone_longt, // The number of longitudinal divisions. (integer)
SGrid_DblCone_latit, // The number of lattitudinal divisions. (integer)
SGrid_DblCone_radius, // The radius of each cone. (float)
SGrid_DblCone_height, // The height of each cone. (float)
SGrid_DblCone_center, // The center coordinates of the double-cone. (vector)
SGrid_DblCone_thickness, // The thickness of the grid lines. (float)
SGrid_DblCone_offset, // Determines whether the divisions are offset by half the amount. Sometimes necessary when doing cut-aways. (boolian)
SGrid_DblCone_endcap, // Determines whether borders are created at each end of the object. Ignored if the offset is turned on. (boolian)
)
#local SGrid_DblCone_bounds = union
{
cone {0, SGrid_DblCone_radius, <0,+SGrid_DblCone_height,0,>, 0}
cone {0, SGrid_DblCone_radius, <0,-SGrid_DblCone_height,0,>, 0}
}
union
{
#local SGrid_DblCone_increment = 1/SGrid_DblCone_radii;
#local SGrid_DblCone_i = 0;
#local SGrid_DblCone_start = 0;
#if (SGrid_DblCone_offset = on)
#local SGrid_DblCone_start = SGrid_DblCone_increment/2;
#end
#while (SGrid_DblCone_i < SGrid_DblCone_radii)
#local SGrid_DblCone_value = SGrid_DblCone_radius * (SGrid_DblCone_start + SGrid_DblCone_i * SGrid_DblCone_increment);
#local SGrid_DblCone_angle = atan2d(SGrid_DblCone_value, SGrid_DblCone_height);
#local SGrid_DblCone_offsl = SGrid_DblCone_thickness/2 * 1/cosd(SGrid_DblCone_angle);
#local SGrid_DblCone_offsv = SGrid_DblCone_thickness/2 * 1/cosd(90 - SGrid_DblCone_angle);
difference
{
union
{
cone {0, SGrid_DblCone_value + SGrid_DblCone_offsl, <0,+SGrid_DblCone_height+SGrid_DblCone_offsv,0,>, 0}
cone {0, SGrid_DblCone_value + SGrid_DblCone_offsl, <0,-SGrid_DblCone_height-SGrid_DblCone_offsv,0,>, 0}
}
union
{
cone {0, SGrid_DblCone_value - SGrid_DblCone_offsl, <0,+SGrid_DblCone_height-SGrid_DblCone_offsv,0,>, 0}
cone {0, SGrid_DblCone_value - SGrid_DblCone_offsl, <0,-SGrid_DblCone_height+SGrid_DblCone_offsv,0,>, 0}
}
bounded_by {SGrid_DblCone_bounds}
}
SGrid_Debug_Macro(concat("radii_value = ", str(SGrid_DblCone_value, 0, -1),"\n"))
#local SGrid_DblCone_i = SGrid_DblCone_i + 1;
#end
#local SGrid_DblCone_increment = 1/SGrid_DblCone_longt;
#local SGrid_DblCone_i = 0;
#local SGrid_DblCone_start = 0;
#if (SGrid_DblCone_offset = on)
#local SGrid_DblCone_start = SGrid_DblCone_increment/2;
#end
#while (SGrid_DblCone_i < SGrid_DblCone_longt)
#local SGrid_DblCone_value = 360 * (SGrid_DblCone_start + SGrid_DblCone_i * SGrid_DblCone_increment);
box
{
<2*SGrid_DblCone_radius, 2*SGrid_DblCone_radius, SGrid_DblCone_thickness/2,>,
<0, -2*SGrid_DblCone_radius, -SGrid_DblCone_thickness/2,>
rotate y * SGrid_DblCone_value
bounded_by {SGrid_DblCone_bounds}
}
SGrid_Debug_Macro(concat("longt_value = ", str(SGrid_DblCone_value, 0, -1),"\n"))
#local SGrid_DblCone_i = SGrid_DblCone_i + 1;
#end
#local SGrid_DblCone_increment = 1/SGrid_DblCone_latit;
#local SGrid_DblCone_i = 0;
#if (SGrid_DblCone_endcap = on)
#local SGrid_DblCone_start = 0;
#local SGrid_DblCone_finish = SGrid_DblCone_latit + 1;
#else
#local SGrid_DblCone_start = SGrid_DblCone_increment;
#local SGrid_DblCone_finish = SGrid_DblCone_latit - 1;
#end
#if (SGrid_DblCone_offset = on)
#local SGrid_DblCone_start = SGrid_DblCone_increment/2;
#local SGrid_DblCone_finish = SGrid_DblCone_latit;
#end
#while (SGrid_DblCone_i < SGrid_DblCone_finish)
#local SGrid_DblCone_value = -SGrid_DblCone_height + 2*SGrid_DblCone_height * (SGrid_DblCone_start + SGrid_DblCone_i * SGrid_DblCone_increment);
box
{
,
<-SGrid_DblCone_radius,-SGrid_DblCone_thickness/2,-SGrid_DblCone_radius,>
bounded_by {SGrid_DblCone_bounds}
translate y * SGrid_DblCone_value
}
SGrid_Debug_Macro(concat("lattt_value = ", str(SGrid_DblCone_value, 0, -1),"\n"))
#local SGrid_DblCone_i = SGrid_DblCone_i + 1;
#end
translate SGrid_DblCone_center
}
#end
//--------------------------------------Double cone inverted
#macro SGrid_DblConeInv_Macro
(
SGrid_DblConeInv_radii, // The number of radial divisions. (integer)
SGrid_DblConeInv_longt, // The number of longitudinal divisions. (integer)
SGrid_DblConeInv_latit, // The number of lattitudinal divisions. (integer)
SGrid_DblConeInv_radius, // The radius of each cone. (float)
SGrid_DblConeInv_height, // The height of each cone. (float)
SGrid_DblConeInv_center, // The center coordinates of the double-cone. (vector)
SGrid_DblConeInv_thickness, // The thickness of the grid lines. (float)
SGrid_DblConeInv_offset, // Determines whether the divisions are offset by half the amount. Sometimes necessary when doing cut-aways. (boolian)
SGrid_DblConeInv_endcap, // Determines whether borders are created at each end of the object. Ignored if the offset is turned on. (boolian)
)
#local SGrid_DblConeInv_bounds = union
{
cone {0, 0, <0,+SGrid_DblConeInv_height,0,>, SGrid_DblConeInv_radius}
cone {0, 0, <0,-SGrid_DblConeInv_height,0,>, SGrid_DblConeInv_radius}
}
union
{
#local SGrid_DblConeInv_increment = 1/SGrid_DblConeInv_radii;
#local SGrid_DblConeInv_i = 0;
#local SGrid_DblConeInv_start = 0;
#if (SGrid_DblConeInv_offset = on)
#local SGrid_DblConeInv_start = SGrid_DblConeInv_increment/2;
#end
#while (SGrid_DblConeInv_i < SGrid_DblConeInv_radii)
#local SGrid_DblConeInv_value = SGrid_DblConeInv_radius * (SGrid_DblConeInv_start + SGrid_DblConeInv_i * SGrid_DblConeInv_increment);
#local SGrid_DblConeInv_angle = atan2d(SGrid_DblConeInv_value, SGrid_DblConeInv_height);
#local SGrid_DblConeInv_offsl = SGrid_DblConeInv_thickness/2 * 1/cosd(SGrid_DblConeInv_angle);
#local SGrid_DblConeInv_offsv = SGrid_DblConeInv_thickness/2 * 1/cosd(90 - SGrid_DblConeInv_angle);
difference
{
union
{
cone {<0,-SGrid_DblConeInv_offsv,0,>, 0, <0,+SGrid_DblConeInv_height,0,>, SGrid_DblConeInv_value + SGrid_DblConeInv_offsl}
cone {<0,+SGrid_DblConeInv_offsv,0,>, 0, <0,-SGrid_DblConeInv_height,0,>, SGrid_DblConeInv_value + SGrid_DblConeInv_offsl}
}
union
{
cone {<0,+SGrid_DblConeInv_offsv,0,>, 0, <0,+SGrid_DblConeInv_height,0,>, SGrid_DblConeInv_value - SGrid_DblConeInv_offsl}
cone {<0,-SGrid_DblConeInv_offsv,0,>, 0, <0,-SGrid_DblConeInv_height,0,>, SGrid_DblConeInv_value - SGrid_DblConeInv_offsl}
}
bounded_by {SGrid_DblConeInv_bounds}
}
SGrid_Debug_Macro(concat("radii_value = ", str(SGrid_DblConeInv_value, 0, -1),"\n"))
#local SGrid_DblConeInv_i = SGrid_DblConeInv_i + 1;
#end
#local SGrid_DblConeInv_increment = 1/SGrid_DblConeInv_longt;
#local SGrid_DblConeInv_i = 0;
#local SGrid_DblConeInv_start = 0;
#if (SGrid_DblConeInv_offset = on)
#local SGrid_DblConeInv_start = SGrid_DblConeInv_increment/2;
#end
#while (SGrid_DblConeInv_i < SGrid_DblConeInv_longt)
#local SGrid_DblConeInv_value = 360 * (SGrid_DblConeInv_start + SGrid_DblConeInv_i * SGrid_DblConeInv_increment);
box
{
<2*SGrid_DblConeInv_radius, 2*SGrid_DblConeInv_radius, SGrid_DblConeInv_thickness/2,>,
<0, -2*SGrid_DblConeInv_radius, -SGrid_DblConeInv_thickness/2,>
rotate y * SGrid_DblConeInv_value
bounded_by {SGrid_DblConeInv_bounds}
}
SGrid_Debug_Macro(concat("longt_value = ", str(SGrid_DblConeInv_value, 0, -1),"\n"))
#local SGrid_DblConeInv_i = SGrid_DblConeInv_i + 1;
#end
#local SGrid_DblConeInv_increment = 1/SGrid_DblConeInv_latit;
#local SGrid_DblConeInv_i = 0;
#if (SGrid_DblConeInv_endcap = on)
#local SGrid_DblConeInv_start = 0;
#local SGrid_DblConeInv_finish = SGrid_DblConeInv_latit + 1;
#else
#local SGrid_DblConeInv_start = SGrid_DblConeInv_increment;
#local SGrid_DblConeInv_finish = SGrid_DblConeInv_latit - 1;
#end
#if (SGrid_DblConeInv_offset = on)
#local SGrid_DblConeInv_start = SGrid_DblConeInv_increment/2;
#local SGrid_DblConeInv_finish = SGrid_DblConeInv_latit;
#end
#while (SGrid_DblConeInv_i < SGrid_DblConeInv_finish)
#local SGrid_DblConeInv_value = -SGrid_DblConeInv_height + 2*SGrid_DblConeInv_height * (SGrid_DblConeInv_start + SGrid_DblConeInv_i * SGrid_DblConeInv_increment);
box
{
,
<-SGrid_DblConeInv_radius,-SGrid_DblConeInv_thickness/2,-SGrid_DblConeInv_radius,>
bounded_by {SGrid_DblConeInv_bounds}
translate y * SGrid_DblConeInv_value
}
SGrid_Debug_Macro(concat("lattt_value = ", str(SGrid_DblConeInv_value, 0, -1),"\n"))
#local SGrid_DblConeInv_i = SGrid_DblConeInv_i + 1;
#end
translate SGrid_DblConeInv_center
}
#end
//--------------------------------------Sphere
#macro SGrid_Sphere_Macro
(
SGrid_Sphere_radii, // The number of radial divisions. (integer)
SGrid_Sphere_longt, // The number of longitudinal divisions. (integer)
SGrid_Sphere_latit, // The number of lattitudinal divisions. (integer)
SGrid_Sphere_radius, // The radius of the sphere. (float)
SGrid_Sphere_center, // The center coordinates of the sphere. (vector)
SGrid_Sphere_thickness, // The thickness of the grid lines. (float)
SGrid_Sphere_offset, // Determines whether the divisions are offset by half the amount. Sometimes necessary when doing cut-aways. (boolian)
SGrid_Sphere_endcap, // Determines whether borders are created at each end of the object. Ignored if the offset is turned on. (boolian)
SGrid_Sphere_hole, // Put a hole in the middle? (boolean)
)
#local SGrid_Sphere_bounds = sphere {0, SGrid_Sphere_radius}
union
{
// radii
#local SGrid_Sphere_increment = 1/SGrid_Sphere_radii;
#if (SGrid_Sphere_offset = off)
#local SGrid_Sphere_start = 0;
#else
#local SGrid_Sphere_start = SGrid_Sphere_increment/2;
#end
#for (SGrid_Sphere_i, 0, SGrid_Sphere_radii - 1)
#local SGrid_Sphere_value = SGrid_Sphere_radius * (SGrid_Sphere_start + SGrid_Sphere_i * SGrid_Sphere_increment);
difference
{
sphere {0, SGrid_Sphere_value + SGrid_Sphere_thickness/2}
sphere {0, SGrid_Sphere_value - SGrid_Sphere_thickness/2}
bounded_by {SGrid_Sphere_bounds}
}
SGrid_Debug_Macro(concat("radii_value = ", str(SGrid_Sphere_value, 0, -1),"\n"))
#end
// longitude
#local SGrid_Sphere_increment = 1/SGrid_Sphere_longt;
#if (SGrid_Sphere_offset = off)
#local SGrid_Sphere_start = 0;
#else
#local SGrid_Sphere_start = SGrid_Sphere_increment/2;
#end
#for (SGrid_Sphere_i, 0, SGrid_Sphere_longt - 1)
#local SGrid_Sphere_value = 360 * (SGrid_Sphere_start + SGrid_Sphere_i * SGrid_Sphere_increment);
box
{
<2*SGrid_Sphere_radius, 2*SGrid_Sphere_radius, SGrid_Sphere_thickness/2,>,
<0, -2*SGrid_Sphere_radius, -SGrid_Sphere_thickness/2,>
rotate y * SGrid_Sphere_value
// bounded_by {SGrid_Sphere_bounds}
}
SGrid_Debug_Macro(concat("longt_value = ", str(SGrid_Sphere_value, 0, -1),"\n"))
#end
// latitude
#local SGrid_Sphere_increment = 1/SGrid_Sphere_latit;
#if (SGrid_Sphere_endcap = on)
#local SGrid_Sphere_start = 0;
#local SGrid_Sphere_finish = SGrid_Sphere_latit + 1;
#local SGrid_Sphere_center_gap = 0;
#else
#local SGrid_Sphere_start = SGrid_Sphere_increment;
#local SGrid_Sphere_finish = SGrid_Sphere_latit - 1;
#end
#if (SGrid_Sphere_offset = on)
#local SGrid_Sphere_start = SGrid_Sphere_increment/2;
#local SGrid_Sphere_finish = SGrid_Sphere_latit;
#end
#for (SGrid_Sphere_i, 0, SGrid_Sphere_finish - 1)
#local SGrid_Sphere_value = 180 * (SGrid_Sphere_start + SGrid_Sphere_i * SGrid_Sphere_increment);
#if (SGrid_Sphere_i < (SGrid_Sphere_finish - 1)/2)
difference
{
cone
{
0, 0, 2*SGrid_Sphere_radius*y, 2*SGrid_Sphere_radius*abs(tand(SGrid_Sphere_value))
translate SGrid_Sphere_radius*-y * 1/abs(sind(SGrid_Sphere_value)) * SGrid_Sphere_thickness/2
}
cone
{
0, 0, 2*SGrid_Sphere_radius*y, 2*SGrid_Sphere_radius*abs(tand(SGrid_Sphere_value))
translate SGrid_Sphere_radius*+y * 1/abs(sind(SGrid_Sphere_value)) * SGrid_Sphere_thickness/2
}
bounded_by {SGrid_Sphere_bounds}
}
#elseif (SGrid_Sphere_i = (SGrid_Sphere_finish - 1)/2)
cylinder
{
<0,-SGrid_Sphere_thickness/2,0,>, <0,+SGrid_Sphere_thickness/2,0,>, 2*SGrid_Sphere_radius
bounded_by {SGrid_Sphere_bounds}
}
#else
difference
{
cone
{
0, 0, 2*SGrid_Sphere_radius*-y, 2*SGrid_Sphere_radius*abs(tand(SGrid_Sphere_value))
translate SGrid_Sphere_radius*+y * 1/abs(sind(SGrid_Sphere_value)) * SGrid_Sphere_thickness/2
}
cone
{
0, 0, 2*SGrid_Sphere_radius*-y, 2*SGrid_Sphere_radius*abs(tand(SGrid_Sphere_value))
translate SGrid_Sphere_radius*-y * 1/abs(sind(SGrid_Sphere_value)) * SGrid_Sphere_thickness/2
}
bounded_by {SGrid_Sphere_bounds}
}
#end
SGrid_Debug_Macro(concat("lattt_value = ", str(SGrid_Sphere_value, 0, -1),"\n"))
#end
translate SGrid_Sphere_center
}
#end
//--------------------------------------Ellipsoid (parametric)
#macro SGrid_Ellipsoid_Macro
(
SGrid_Ellipsoid_radii, // The number of radial divisions. (integer)
SGrid_Ellipsoid_longt, // The number of longitudinal divisions. (integer)
SGrid_Ellipsoid_latit, // The number of lattitudinal divisions. (integer)
SGrid_Ellipsoid_radius_major, // The radius of the sphere. (float)
SGrid_Ellipsoid_radius_minor, // The radius of the sphere. (float)
SGrid_Ellipsoid_center, // The center coordinates of the sphere. (vector)
SGrid_Ellipsoid_thickness, // The thickness of the grid lines. (float)
SGrid_Ellipsoid_offset, // Determines whether the divisions are offset by half the amount. Sometimes necessary when doing cut-aways. (boolian)
SGrid_Ellipsoid_endcap, // Determines whether borders are created at each end of the object. Ignored if the offset is turned on. (boolian)
)
#local SGrid_Ellipsoid_ratio = SGrid_Ellipsoid_radius_minor/SGrid_Ellipsoid_radius_major;
#local SGrid_Ellipsoid_bounds = sphere {0, SGrid_Ellipsoid_radius_major scale <1,SGrid_Ellipsoid_ratio,1>}
#local SGrid_Ellipsoid_focal_distance = cosd(asind(SGrid_Ellipsoid_ratio)) * SGrid_Ellipsoid_radius_major;
#local SGrid_Ellipsoid_H = 1e-4;
union
{
// radius
#local SGrid_Ellipsoid_increment = 1/SGrid_Ellipsoid_radii;
#local SGrid_Ellipsoid_i = 0;
#if (SGrid_Ellipsoid_offset = on)
#local SGrid_Ellipsoid_start = SGrid_Ellipsoid_increment/2;
#local SGrid_Ellipsoid_finish = SGrid_Ellipsoid_radii;
#elseif (SGrid_Ellipsoid_endcap = on)
#local SGrid_Ellipsoid_start = 0;
#local SGrid_Ellipsoid_finish = SGrid_Ellipsoid_radii + 1;
#else
#local SGrid_Ellipsoid_start = SGrid_Ellipsoid_increment;
#local SGrid_Ellipsoid_finish = SGrid_Ellipsoid_radii - 1;
#end
#while (SGrid_Ellipsoid_i < SGrid_Ellipsoid_finish)
// formula: x^2 / (c^2 + b^2) + y^2 / b^2 = 1
// formula: b = sinh(mu) * c
// to do: do something when endcap is enabled and SGrid_Ellipsoid_i = 0
#if (SGrid_Ellipsoid_i != 0)
#local SGrid_Ellipsoid_step = SGrid_Ellipsoid_start + SGrid_Ellipsoid_i * SGrid_Ellipsoid_increment;
#local SGrid_Ellipsoid_vert = sinh(SGrid_Ellipsoid_step) * SGrid_Ellipsoid_focal_distance;
#local SGrid_Ellipsoid_b_sq = pow(SGrid_Ellipsoid_vert,2);
#local SGrid_Ellipsoid_c_sq = pow(SGrid_Ellipsoid_focal_distance,2);
#undef SGrid_Ellipsoid_func_ellipsoid
#local SGrid_Ellipsoid_func_ellipsoid = function(x,y,z) {pow(x,2)/(SGrid_Ellipsoid_c_sq+SGrid_Ellipsoid_b_sq)+pow(y,2)/SGrid_Ellipsoid_b_sq+pow(z,2)/(SGrid_Ellipsoid_c_sq+SGrid_Ellipsoid_b_sq)-1}
#undef SGrid_Ellipsoid_func_gradient_magnitude
#local SGrid_Ellipsoid_func_gradient_magnitude = MakeGradientMagnitudeFunction_3b(SGrid_Ellipsoid_func_ellipsoid, SGrid_Ellipsoid_H)
#undef SGrid_Ellipsoid_func_normalized
#local SGrid_Ellipsoid_func_normalized = function(x,y,z) {SGrid_Ellipsoid_func_ellipsoid(x,y,z)/SGrid_Ellipsoid_func_gradient_magnitude(x,y,z)}
#local SGrid_Ellipsoid_Iso_1 = isosurface
{
function {SGrid_Ellipsoid_func_normalized(x,y,z)-SGrid_Ellipsoid_thickness/2}
accuracy 0.001
max_gradient 4
all_intersections
//evaluate P0, P1, min (P2, 1)
contained_by {sphere {0, SGrid_Ellipsoid_radius_major}}
}
#local SGrid_Ellipsoid_Iso_2 = isosurface
{
function {SGrid_Ellipsoid_func_normalized(x,y,z)+SGrid_Ellipsoid_thickness/2}
accuracy 0.001
max_gradient 4
all_intersections
//evaluate P0, P1, min (P2, 1)
contained_by {sphere {0, SGrid_Ellipsoid_radius_major}}
}
difference
{
object {SGrid_Ellipsoid_Iso_1}
object {SGrid_Ellipsoid_Iso_2}
bounded_by {SGrid_Ellipsoid_bounds}
}
#end
#local SGrid_Ellipsoid_i = SGrid_Ellipsoid_i + 1;
#end
// longitude
#local SGrid_Ellipsoid_increment = 1/SGrid_Ellipsoid_longt;
#local SGrid_Ellipsoid_i = 0;
#local SGrid_Ellipsoid_start = 0;
#if (SGrid_Ellipsoid_offset = on)
#local SGrid_Ellipsoid_start = SGrid_Ellipsoid_increment/2;
#end
#while (SGrid_Ellipsoid_i < SGrid_Ellipsoid_longt)
#local SGrid_Ellipsoid_value = 360 * (SGrid_Ellipsoid_start + SGrid_Ellipsoid_i * SGrid_Ellipsoid_increment);
box
{
<2*SGrid_Ellipsoid_radius_major, 2*SGrid_Ellipsoid_radius_major, SGrid_Ellipsoid_thickness/2,>,
<0, -2*SGrid_Ellipsoid_radius_major, -SGrid_Ellipsoid_thickness/2,>
rotate y * SGrid_Ellipsoid_value
bounded_by {SGrid_Ellipsoid_bounds}
}
SGrid_Debug_Macro(concat("longt_value = ", str(SGrid_Ellipsoid_value, 0, -1),"\n"))
#local SGrid_Ellipsoid_i = SGrid_Ellipsoid_i + 1;
#end
// latitude
#local SGrid_Ellipsoid_increment = 1/SGrid_Ellipsoid_latit;
#local SGrid_Ellipsoid_i = 0;
#if (SGrid_Ellipsoid_offset = on)
#local SGrid_Ellipsoid_start = SGrid_Ellipsoid_increment/2;
#local SGrid_Ellipsoid_finish = SGrid_Ellipsoid_latit;
#elseif (SGrid_Ellipsoid_endcap = on)
#local SGrid_Ellipsoid_start = 0;
#local SGrid_Ellipsoid_finish = SGrid_Ellipsoid_latit + 1;
#else
#local SGrid_Ellipsoid_start = SGrid_Ellipsoid_increment;
#local SGrid_Ellipsoid_finish = SGrid_Ellipsoid_latit - 1;
#end
#while (SGrid_Ellipsoid_i < SGrid_Ellipsoid_finish)
// formula: x^2 / a^2 - y^2 / (c^2 - a^2) = 1
// formula: a = cos(nu) * c
// to do: do something when endcap is enabled and SGrid_Ellipsoid_i = 0
#if (SGrid_Ellipsoid_i != 0)
#local SGrid_Ellipsoid_step = SGrid_Ellipsoid_start + SGrid_Ellipsoid_i * SGrid_Ellipsoid_increment;
#local SGrid_Ellipsoid_horz = cosd(90 * SGrid_Ellipsoid_step) * SGrid_Ellipsoid_focal_distance;
#local SGrid_Ellipsoid_a_sq = pow(SGrid_Ellipsoid_horz,2);
#local SGrid_Ellipsoid_c_sq = pow(SGrid_Ellipsoid_focal_distance,2);
#undef SGrid_Ellipsoid_func_hyperboloid
#local SGrid_Ellipsoid_func_hyperboloid = function(x,y,z) {pow(x,2)/SGrid_Ellipsoid_a_sq-pow(y,2)/(SGrid_Ellipsoid_c_sq-SGrid_Ellipsoid_a_sq)+pow(z,2)/SGrid_Ellipsoid_a_sq-1}
#undef SGrid_Ellipsoid_func_gradient_magnitude
#local SGrid_Ellipsoid_func_gradient_magnitude = MakeGradientMagnitudeFunction_3b(SGrid_Ellipsoid_func_hyperboloid, SGrid_Ellipsoid_H)
#undef SGrid_Ellipsoid_func_normalized
#local SGrid_Ellipsoid_func_normalized = function(x,y,z) {SGrid_Ellipsoid_func_hyperboloid(x,y,z)/SGrid_Ellipsoid_func_gradient_magnitude(x,y,z)}
#local SGrid_Ellipsoid_Iso_1 = isosurface
{
function {SGrid_Ellipsoid_func_normalized(x,y,z)-SGrid_Ellipsoid_thickness/2}
accuracy 0.001
max_gradient 4
all_intersections
//evaluate P0, P1, min (P2, 1)
contained_by {sphere {0, SGrid_Ellipsoid_radius_major}}
}
#local SGrid_Ellipsoid_Iso_2 = isosurface
{
function {SGrid_Ellipsoid_func_normalized(x,y,z)+SGrid_Ellipsoid_thickness/2}
accuracy 0.001
max_gradient 4
all_intersections
//evaluate P0, P1, min (P2, 1)
contained_by {sphere {0, SGrid_Ellipsoid_radius_major}}
}
difference
{
object {SGrid_Ellipsoid_Iso_1}
object {SGrid_Ellipsoid_Iso_2}
bounded_by {SGrid_Ellipsoid_bounds}
}
#end
#local SGrid_Ellipsoid_i = SGrid_Ellipsoid_i + 1;
#end
translate SGrid_Ellipsoid_center
}
#end
//--------------------------------------Ellipsoid (geodetic)
#macro SGrid_Geodetic_Macro
(
SGrid_Geodetic_radii, // The number of radial divisions. (integer)
SGrid_Geodetic_longt, // The number of longitudinal divisions. (integer)
SGrid_Geodetic_latit, // The number of lattitudinal divisions. (integer)
SGrid_Geodetic_radius_major, // The radius of the sphere. (float)
SGrid_Geodetic_radius_minor, // The radius of the sphere. (float)
SGrid_Geodetic_center, // The center coordinates of the sphere. (vector)
SGrid_Geodetic_thickness, // The thickness of the grid lines. (float)
SGrid_Geodetic_offset, // Determines whether the divisions are offset by half the amount. Sometimes necessary when doing cut-aways. (boolian)
SGrid_Geodetic_endcap, // Determines whether borders are created at each end of the object. Ignored if the offset is turned on. (boolian)
)
#local SGrid_Geodetic_ratio = SGrid_Geodetic_radius_minor/SGrid_Geodetic_radius_major;
#local SGrid_Geodetic_bounds = sphere {0, SGrid_Geodetic_radius_major scale <1,SGrid_Geodetic_ratio,1>}
#local f_spheroid = function(var1,var2,var3, a,b,c) {var1*var1/a/a+var2*var2/b/b+var3*var3/c/c-1}
#local f_spheroid_normalized = function(var1,var2,var3, a,b,c) {f_spheroid(var1,var2,var3, a,b,c)/sqrt(4*var1*var1/pow(a,4)+4*var2*var2/pow(b,4)+4*var3*var3/pow(c,4))}
union
{
// radius
#local SGrid_Geodetic_increment = 1/SGrid_Geodetic_radii;
#local SGrid_Geodetic_i = 0;
#local SGrid_Geodetic_start = 0;
#if (SGrid_Geodetic_offset = on)
#local SGrid_Geodetic_start = SGrid_Geodetic_increment/2;
#end
#while (SGrid_Geodetic_i < SGrid_Geodetic_radii)
#local SGrid_Geodetic_value_maj = SGrid_Geodetic_radius_major * (SGrid_Geodetic_start + SGrid_Geodetic_i * SGrid_Geodetic_increment);
#local SGrid_Geodetic_value_min = SGrid_Geodetic_radius_minor * (SGrid_Geodetic_start + SGrid_Geodetic_i * SGrid_Geodetic_increment);
#local SGrid_Iso_1 = isosurface
{
function {f_spheroid_normalized(x,y,z,SGrid_Geodetic_value_maj,SGrid_Geodetic_value_min,SGrid_Geodetic_value_maj)-SGrid_Geodetic_thickness/2}
accuracy 0.001
max_gradient 4
all_intersections
//evaluate P0, P1, min (P2, 1)
contained_by {sphere {0, SGrid_Geodetic_radius_major}}
}
#local SGrid_Iso_2 = isosurface
{
function {f_spheroid_normalized(x,y,z,SGrid_Geodetic_value_maj,SGrid_Geodetic_value_min,SGrid_Geodetic_value_maj)+SGrid_Geodetic_thickness/2}
accuracy 0.001
max_gradient 4
all_intersections
//evaluate P0, P1, min (P2, 1)
contained_by {sphere {0, SGrid_Geodetic_radius_major}}
}
difference
{
object {SGrid_Iso_1}
object {SGrid_Iso_2}
bounded_by {SGrid_Geodetic_bounds}
}
SGrid_Debug_Macro("\n")
SGrid_Debug_Macro(concat("radii_value_maj = ", str(SGrid_Geodetic_value_maj, 0, -1),"\n"))
SGrid_Debug_Macro(concat("radii_value_min = ", str(SGrid_Geodetic_value_min, 0, -1),"\n"))
#local SGrid_Geodetic_i = SGrid_Geodetic_i + 1;
#end
// longitude
#local SGrid_Geodetic_increment = 1/SGrid_Geodetic_longt;
#local SGrid_Geodetic_i = 0;
#local SGrid_Geodetic_start = 0;
#if (SGrid_Geodetic_offset = on)
#local SGrid_Geodetic_start = SGrid_Geodetic_increment/2;
#end
#while (SGrid_Geodetic_i < SGrid_Geodetic_longt)
#local SGrid_Geodetic_value = 360 * (SGrid_Geodetic_start + SGrid_Geodetic_i * SGrid_Geodetic_increment);
box
{
<2*SGrid_Geodetic_radius_major, 2*SGrid_Geodetic_radius_major, SGrid_Geodetic_thickness/2,>,
<0, -2*SGrid_Geodetic_radius_major, -SGrid_Geodetic_thickness/2,>
rotate y * SGrid_Geodetic_value
bounded_by {SGrid_Geodetic_bounds}
}
SGrid_Debug_Macro(concat("longt_value = ", str(SGrid_Geodetic_value, 0, -1),"\n"))
#local SGrid_Geodetic_i = SGrid_Geodetic_i + 1;
#end
// latitude
#local SGrid_Geodetic_increment = 1/SGrid_Geodetic_latit;
#local SGrid_Geodetic_i = 0;
#if (SGrid_Geodetic_endcap = on)
#local SGrid_Geodetic_start = 0;
#local SGrid_Geodetic_finish = SGrid_Geodetic_latit + 1;
#local SGrid_Geodetic_center_gap = 0;
#else
#local SGrid_Geodetic_start = SGrid_Geodetic_increment;
#local SGrid_Geodetic_finish = SGrid_Geodetic_latit - 1;
#end
#if (SGrid_Geodetic_offset = on)
#local SGrid_Geodetic_start = SGrid_Geodetic_increment/2;
#local SGrid_Geodetic_finish = SGrid_Geodetic_latit;
#end
#while (SGrid_Geodetic_i < SGrid_Geodetic_finish)
// all variable names are supposed to match those in the accompanying GeoGebra worksheet
#local SGrid_Geodetic_lat_geodet = 180 * (SGrid_Geodetic_start + SGrid_Geodetic_i * SGrid_Geodetic_increment) - 90; // theta_3
#local SGrid_Geodetic_lat_geocen = SGrid_convert_geodetic_to_geocentric(SGrid_Geodetic_radius_major, SGrid_Geodetic_radius_minor, SGrid_Geodetic_lat_geodet); // phi_3
#local SGrid_Geodetic_lat_reduce = SGrid_convert_geodetic_to_reduced(SGrid_Geodetic_radius_major, SGrid_Geodetic_radius_minor, SGrid_Geodetic_lat_geodet); // beta_3
#local SGrid_Geodetic_lat_oppose = asind(cosd(SGrid_Geodetic_lat_geodet));
#local SGrid_Geodetic_point_A = <0,0>;
#local SGrid_Geodetic_point_E = <0,+SGrid_Geodetic_radius_minor>;
#local SGrid_Geodetic_point_R = <0,-SGrid_Geodetic_radius_minor>;
#local SGrid_Geodetic_point_M = * SGrid_Geodetic_radius_major;
#local SGrid_Geodetic_point_K = * SGrid_Geodetic_radius_major;
#local SGrid_Geodetic_point_O = * SGrid_Geodetic_radius_major;
#local SGrid_Geodetic_line_i = SGrid_Line(SGrid_Geodetic_point_A, SGrid_Geodetic_point_M);
#local SGrid_Geodetic_line_n = SGrid_Line(SGrid_Geodetic_point_K, SGrid_Geodetic_point_O);
#local SGrid_Geodetic_point_F = SGrid_Line_Intersection(SGrid_Geodetic_line_i, SGrid_Geodetic_line_n);
#local SGrid_Geodetic_distance_IK = tand(SGrid_Geodetic_lat_oppose) * abs(SGrid_Geodetic_point_F.y);
#local SGrid_Geodetic_distance_AI = abs(SGrid_Geodetic_point_F.x) - SGrid_Geodetic_distance_IK;
#local SGrid_Geodetic_distance_AE = SGrid_Geodetic_radius_minor;
#local SGrid_Geodetic_distance_AR = SGrid_Geodetic_radius_minor;
#local SGrid_Geodetic_distance_AFocus1 = cosd(asind(SGrid_Geodetic_distance_AE));
#local SGrid_Geodetic_point_N = ;
#local SGrid_Geodetic_point_Q = ;
#local SGrid_Geodetic_point_I = ;
#local SGrid_Geodetic_line_b = SGrid_Line(SGrid_Geodetic_point_E, SGrid_Geodetic_point_N);
#local SGrid_Geodetic_line_p = SGrid_Line(SGrid_Geodetic_point_I, SGrid_Geodetic_point_F);
#local SGrid_Geodetic_point_G = SGrid_Line_Intersection(SGrid_Geodetic_line_b, SGrid_Geodetic_line_p);
#local SGrid_Geodetic_line_s = SGrid_Line(SGrid_Geodetic_point_R, SGrid_Geodetic_point_Q);
#local SGrid_Geodetic_point_S = SGrid_Line_Intersection(SGrid_Geodetic_line_s, SGrid_Geodetic_line_p);
#local SGrid_Geodetic_line_h = SGrid_Line(SGrid_Geodetic_point_A,SGrid_Geodetic_point_E);
#local SGrid_Geodetic_point_L = SGrid_Line_Intersection(SGrid_Geodetic_line_h, SGrid_Geodetic_line_p);
#local SGrid_Geodetic_distance_EG = abs(SGrid_Geodetic_point_G.x);
#local SGrid_Geodetic_distance_RS = abs(SGrid_Geodetic_point_S.x);
// #declare point_array[point_count] = SGrid_Geodetic_point_F;
// #declare point_count = point_count + 1;
#if (SGrid_Geodetic_lat_geodet = -60)
SGrid_Debug_Macro("\n")
SGrid_Debug_Macro(concat("SGrid_Geodetic_lat_geodet (theta_3): ", str(SGrid_Geodetic_lat_geodet,0,5), "\n"))
SGrid_Debug_Macro(concat("SGrid_Geodetic_lat_geocen (phi_3): ", str(SGrid_Geodetic_lat_geocen,0,5), "\n"))
SGrid_Debug_Macro(concat("SGrid_Geodetic_lat_reduce (beta_3): ", str(SGrid_Geodetic_lat_reduce,0,5), "\n"))
SGrid_Debug_Macro(concat("SGrid_Geodetic_lat_oppose: ", str(SGrid_Geodetic_lat_oppose,0,5), "\n"))
SGrid_Debug_Macro(concat("SGrid_Geodetic_point_F: <", vstr(3,SGrid_Geodetic_point_F,",",0,5), ">\n"))
SGrid_Debug_Macro(concat("SGrid_Geodetic_distance_IK: ", str(SGrid_Geodetic_distance_IK,0,5), "\n"))
SGrid_Debug_Macro(concat("SGrid_Geodetic_distance_AI: ", str(SGrid_Geodetic_distance_AI,0,5), "\n"))
SGrid_Debug_Macro(concat("SGrid_Geodetic_distance_AE: ", str(SGrid_Geodetic_distance_AE,0,5), "\n"))
SGrid_Debug_Macro(concat("SGrid_Geodetic_distance_AFocus1: ", str(SGrid_Geodetic_distance_AFocus1,0,5), "\n"))
SGrid_Debug_Macro(concat("SGrid_Geodetic_point_G: <", vstr(3,SGrid_Geodetic_point_G,",",0,5), ">\n"))
SGrid_Debug_Macro(concat("SGrid_Geodetic_point_L: <", vstr(3,SGrid_Geodetic_point_L,",",0,5), ">\n"))
SGrid_Debug_Macro(concat("SGrid_Geodetic_distance_EG: ", str(SGrid_Geodetic_distance_EG,0,5), "\n"))
SGrid_Debug_Macro("\n")
#end
#if (SGrid_Geodetic_i < (SGrid_Geodetic_finish - 1)/2)
difference
{
cone
{
SGrid_Geodetic_point_L * <1,1,0>, 0, SGrid_Geodetic_point_R * <1,1,0>, SGrid_Geodetic_distance_RS
translate +y * SGrid_Geodetic_radius_major/abs(sind(SGrid_Geodetic_lat_oppose)) * SGrid_Geodetic_thickness/2
}
cone
{
SGrid_Geodetic_point_L * <1,1,0>, 0, SGrid_Geodetic_point_R * <1,1,0>, SGrid_Geodetic_distance_RS
translate -y * SGrid_Geodetic_radius_major/abs(sind(SGrid_Geodetic_lat_oppose)) * SGrid_Geodetic_thickness/2
}
plane {-y, 0}
bounded_by {SGrid_Geodetic_bounds}
}
#elseif (SGrid_Geodetic_i = (SGrid_Geodetic_finish - 1)/2)
cylinder
{
<0,-SGrid_Geodetic_thickness/2,0,>, <0,+SGrid_Geodetic_thickness/2,0,>, 2*SGrid_Geodetic_radius_major
bounded_by {SGrid_Geodetic_bounds}
}
#elseif (SGrid_Geodetic_i > (SGrid_Geodetic_finish - 1)/2)
difference
{
cone
{
SGrid_Geodetic_point_L * <1,1,0>, 0, SGrid_Geodetic_point_E * <1,1,0>, SGrid_Geodetic_distance_EG
translate -y * SGrid_Geodetic_radius_major/abs(sind(SGrid_Geodetic_lat_oppose)) * SGrid_Geodetic_thickness/2
}
cone
{
SGrid_Geodetic_point_L * <1,1,0>, 0, SGrid_Geodetic_point_E * <1,1,0>, SGrid_Geodetic_distance_EG
translate +y * SGrid_Geodetic_radius_major/abs(sind(SGrid_Geodetic_lat_oppose)) * SGrid_Geodetic_thickness/2
}
plane {+y, 0}
bounded_by {SGrid_Geodetic_bounds}
}
#end
#local SGrid_Geodetic_i = SGrid_Geodetic_i + 1;
#end
translate SGrid_Geodetic_center
}
#end
//--------------------------------------Itten's color sphere
#macro SGrid_Itten_Macro
(
SGrid_Itten_radii, // The number of radial divisions. (integer)
SGrid_Itten_longt, // The number of longitudinal divisions. (integer)
SGrid_Itten_latit, // The number of lattitudinal divisions. (integer)
SGrid_Itten_radius, // The radius of the sphere. (float)
SGrid_Itten_center, // The center coordinates of the sphere. (vector)
SGrid_Itten_thickness, // The thickness of the grid lines. (float)
SGrid_Itten_offset, // Determines whether the divisions are offset by half the amount. Sometimes necessary when doing cut-aways. (boolian)
SGrid_Itten_endcap, // Determines whether borders are created at each end of the object. Ignored if the offset is turned on. (boolian)
)
#local SGrid_Itten_bounds = sphere {0, SGrid_Itten_radius}
union
{
#local SGrid_Itten_increment = 1/SGrid_Itten_radii;
#local SGrid_Itten_i = 0;
#local SGrid_Itten_start = 0;
#if (SGrid_Itten_offset = on)
#local SGrid_Itten_start = SGrid_Itten_increment/2;
#end
#while (SGrid_Itten_i < SGrid_Itten_radii)
#local SGrid_Itten_value = SGrid_Itten_radius * (SGrid_Itten_start + SGrid_Itten_i * SGrid_Itten_increment);
difference
{
object {Spheroid(0, )}
object {Spheroid(0, )}
bounded_by {SGrid_Itten_bounds}
}
SGrid_Debug_Macro(concat("radii_value = ", str(SGrid_Itten_value, 0, -1),"\n"))
#local SGrid_Itten_i = SGrid_Itten_i + 1;
#end
#local SGrid_Itten_increment = 1/SGrid_Itten_longt;
#local SGrid_Itten_i = 0;
#local SGrid_Itten_start = 0;
#if (SGrid_Itten_offset = on)
#local SGrid_Itten_start = SGrid_Itten_increment/2;
#end
#while (SGrid_Itten_i < SGrid_Itten_longt)
#local SGrid_Itten_value = 360 * (SGrid_Itten_start + SGrid_Itten_i * SGrid_Itten_increment);
box
{
<2*SGrid_Itten_radius, 2*SGrid_Itten_radius, SGrid_Itten_thickness/2,>,
<0, -2*SGrid_Itten_radius, -SGrid_Itten_thickness/2,>
bounded_by {SGrid_Itten_bounds}
rotate y * SGrid_Itten_value
}
SGrid_Debug_Macro(concat("longt_value = ", str(SGrid_Itten_value, 0, -1),"\n"))
#local SGrid_Itten_i = SGrid_Itten_i + 1;
#end
#local SGrid_Itten_increment = 1/SGrid_Itten_latit;
#local SGrid_Itten_i = 0;
#if (SGrid_Itten_endcap = on)
#local SGrid_Itten_start = 0;
#local SGrid_Itten_finish = SGrid_Itten_latit + 1;
#else
#local SGrid_Itten_start = SGrid_Itten_increment;
#local SGrid_Itten_finish = SGrid_Itten_latit - 1;
#end
#if (SGrid_Itten_offset = on)
#local SGrid_Itten_start = SGrid_Itten_increment/2;
#local SGrid_Itten_finish = SGrid_Itten_latit;
#end
#while (SGrid_Itten_i < SGrid_Itten_finish)
#local SGrid_Itten_value = -SGrid_Itten_radius + 2*SGrid_Itten_radius*(SGrid_Itten_start + SGrid_Itten_i * SGrid_Itten_increment);
box
{
,
<-SGrid_Itten_radius,-SGrid_Itten_thickness/2,-SGrid_Itten_radius,>
bounded_by {SGrid_Itten_bounds}
translate y * SGrid_Itten_value
}
SGrid_Debug_Macro(concat("lattt_value = ", str(SGrid_Itten_value, 0, -1),"\n"))
#local SGrid_Itten_i = SGrid_Itten_i + 1;
#end
translate SGrid_Itten_center
}
#end
//--------------------------------------Cube
#macro SGrid_Cube_Macro
(
SGrid_Cube_sectors, // The number of sections along each axis. (integer vector)
SGrid_Cube_width, // The width of the cuboid along each axis. (float vector)
SGrid_Cube_corner, // The coordinates of the bottom corner. (float vector)
SGrid_Cube_thickness, // The thickness of the grid lines. (float)
SGrid_Cube_offset, // Determines whether the divisions are offset by half the amount. Sometimes necessary when doing cut-aways. (boolian)
SGrid_Cube_endcap, // Determines whether borders are created at each end of the object. Ignored if the offset is turned on. (boolian)
)
#local SGrid_Cube_bounds = box {0, SGrid_Cube_width}
union
{
#local SGrid_Cube_increment = 1/SGrid_Cube_sectors.x;
#local SGrid_Cube_i = 0;
#local SGrid_Cube_start = 0;
#if (SGrid_Cube_endcap = on)
#local SGrid_Cube_start = 0;
#local SGrid_Cube_finish = SGrid_Cube_sectors.x + 1;
#else
#local SGrid_Cube_start = SGrid_Cube_increment;
#local SGrid_Cube_finish = SGrid_Cube_sectors.x - 1;
#end
#if (SGrid_Cube_offset = on)
#local SGrid_Cube_start = SGrid_Cube_increment/2;
#local SGrid_Cube_finish = SGrid_Cube_sectors.x;
#end
#while (SGrid_Cube_i < SGrid_Cube_finish)
#local SGrid_Cube_value = SGrid_Cube_width.x * (SGrid_Cube_start + SGrid_Cube_i * SGrid_Cube_increment);
box
{
<-SGrid_Cube_thickness/2, +2*SGrid_Cube_width.y, +2*SGrid_Cube_width.z,>,
<+SGrid_Cube_thickness/2, -1*SGrid_Cube_width.y, -1*SGrid_Cube_width.z,>
translate x * SGrid_Cube_value
bounded_by {SGrid_Cube_bounds}
}
SGrid_Debug_Macro(concat("sectorx_value = ", str(SGrid_Cube_value, 0, -1),"\n"))
#local SGrid_Cube_i = SGrid_Cube_i + 1;
#end
#local SGrid_Cube_increment = 1/SGrid_Cube_sectors.y;
#local SGrid_Cube_i = 0;
#local SGrid_Cube_start = 0;
#if (SGrid_Cube_endcap = on)
#local SGrid_Cube_start = 0;
#local SGrid_Cube_finish = SGrid_Cube_sectors.y + 1;
#else
#local SGrid_Cube_start = SGrid_Cube_increment;
#local SGrid_Cube_finish = SGrid_Cube_sectors.y - 1;
#end
#if (SGrid_Cube_offset = on)
#local SGrid_Cube_start = SGrid_Cube_increment/2;
#local SGrid_Cube_finish = SGrid_Cube_sectors.y;
#end
#while (SGrid_Cube_i < SGrid_Cube_finish)
#local SGrid_Cube_value = SGrid_Cube_width.y * (SGrid_Cube_start + SGrid_Cube_i * SGrid_Cube_increment);
box
{
<+2*SGrid_Cube_width.x, -SGrid_Cube_thickness/2, +2*SGrid_Cube_width.z,>,
<-1*SGrid_Cube_width.x, +SGrid_Cube_thickness/2, -1*SGrid_Cube_width.z,>
translate y * SGrid_Cube_value
bounded_by {SGrid_Cube_bounds}
}
SGrid_Debug_Macro(concat("sectory_value = ", str(SGrid_Cube_value, 0, -1),"\n"))
#local SGrid_Cube_i = SGrid_Cube_i + 1;
#end
#local SGrid_Cube_increment = 1/SGrid_Cube_sectors.z;
#local SGrid_Cube_i = 0;
#local SGrid_Cube_start = 0;
#if (SGrid_Cube_endcap = on)
#local SGrid_Cube_start = 0;
#local SGrid_Cube_finish = SGrid_Cube_sectors.z + 1;
#else
#local SGrid_Cube_start = SGrid_Cube_increment;
#local SGrid_Cube_finish = SGrid_Cube_sectors.z - 1;
#end
#if (SGrid_Cube_offset = on)
#local SGrid_Cube_start = SGrid_Cube_increment/2;
#local SGrid_Cube_finish = SGrid_Cube_sectors.z;
#end
#while (SGrid_Cube_i < SGrid_Cube_finish)
#local SGrid_Cube_value = SGrid_Cube_width.z * (SGrid_Cube_start + SGrid_Cube_i * SGrid_Cube_increment);
box
{
<+2*SGrid_Cube_width.x, +2*SGrid_Cube_width.y, -SGrid_Cube_thickness/2,>,
<-1*SGrid_Cube_width.x, -1*SGrid_Cube_width.y, +SGrid_Cube_thickness/2,>
translate z * SGrid_Cube_value
bounded_by {SGrid_Cube_bounds}
}
SGrid_Debug_Macro(concat("sectorz_value = ", str(SGrid_Cube_value, 0, -1),"\n"))
#local SGrid_Cube_i = SGrid_Cube_i + 1;
#end
translate SGrid_Cube_corner
}
#end