#version 3.8; global_settings { assumed_gamma 1.0 } #include "math.inc" #include "shapes3.inc" #declare E = 0.000001; #declare Camera_Orthographic = false; // <----################################################################################ #declare Camera_Position = <0, 2, -5>; // front view #declare Camera_Look_At = <0, 2, 0> ; #declare Fraction = 20; // functions as a zoom for the orthographic view: 4 zooms in 4x, 8 zooms in 8x, etc. #declare Aspect = image_width/image_height; // ########################################### camera { #if (Camera_Orthographic = true) orthographic right x*image_width/(Fraction) up y*image_height/(Fraction) #else right x*image_width/image_height up y #end location Camera_Position look_at Camera_Look_At //rotate y*45 } // ########################################### sky_sphere {pigment {rgb 1}} light_source {<-10, 5, -5> color rgb 1} plane {y, 0 pigment {checker rgb 0, rgb 1}} #declare Line = 0.02; cylinder {-x*10, x*10, Line pigment {rgb x}} cylinder {0, y*10, Line pigment {rgb y}} cylinder {-z*10, z*10, Line pigment {rgb z}} //#declare Radius = 0.25; /* macros for implicit functions parametric functions polynomial functions */ // ################# MACROS FOR IMPLICIT FUNCTIONS ################# #macro Implicit_DrawCentralFunction (Start, End, Step, I_Function) // graph function union { #local GraphFlag = 0; #for (UU, Start, End, Step) #local X0 = ; sphere {X0, Line} #if (GraphFlag) cylinder {X0, LastPoint Line} #end #local LastPoint = X0; #local GraphFlag = 1; #end pigment {rgb y+z} } #end #macro Implicit_CalculatePhi (UU, I_Derivative) #local Phi = -atan2 (I_Derivative (UU)*UU, abs (UU+E)); // correct for flipping around x=0 #local Phi = select ((Phi+pi/2), Phi+pi, Phi); #local Phi = select (UU, -Phi, Phi, Phi ); //#debug concat( "UU = ", str(UU, 0, 12), " Phi = ", str(Phi, 0, 12), "\n") Phi #end #macro Implicit_GraphPhi (Start, End, Step, I_Function, I_Derivative) // graph function union { cylinder {, Line} cylinder {, Line} cylinder {, Line} text { ttf "timrom.ttf", " Plot of Curve Tangent Angle Phi vs X (for properly aligned tube sweep circle)", 0.02, 0.0 scale 0.25 translate } text { ttf "timrom.ttf", " pi", 0.02, 0.0 scale 0.25 translate } text { ttf "timrom.ttf", " 0 ", 0.02, 0.0 scale 0.25 translate } text { ttf "timrom.ttf", "-pi", 0.02, 0.0 scale 0.25 translate } #local GraphFlag = 0; #for (UU, Start, End, Step) #local Phi = Implicit_CalculatePhi (UU, I_Derivative); /* #local Phi = -atan2 (I_Derivative (UU)*UU, abs (UU+E)); // correct for flipping around x=0 #local Phi = select ((Phi+pi/2), Phi+pi, Phi); #local Phi = select (UU, -Phi, 0, Phi); */ // scale Phi for graphing #local Phi = Phi/(pi/2); #local X0 = ; sphere {X0, Line} #if (GraphFlag) cylinder {X0, LastPoint Line} #end #local LastPoint = X0; #local GraphFlag = 1; #end texture {pigment {rgb (2*x+y)/3} finish {emission 1}} } #end // Draw diagram #macro Implicit_DrawTbeCircleDiagram (I_Function, I_Derivative, PX0, Sides, Radius) union { //#for (UU, uStart, uEnd, DStep) #local UU = PX0; // point on curve #local XY0 = ; sphere {XY0, Line*2 pigment {rgb x+y}} sphere { Line*2 pigment {rgb 1}} cylinder { XY0+E Line/2 pigment {rgb 1}} #local Tangent = vnormalize (); #local Phi = Implicit_CalculatePhi (UU, I_Derivative); //#debug concat( " Phi = ", str(Phi, 0, 5), "\n") #local Normal = ; // -----------------DRAW CIRCLES----------------- // Draw default circle M #for (Theta, 0, tau, tau/Sides) #local QY = Radius * cos (Theta); #local QZ = Radius * sin (Theta); // function graph is in the xy plane // default circle is in the zy plane // so x is constant // addidng XY0 translates point from origin to that point on graph #local M0 = <0, QY, QZ> + XY0; sphere {M0, Line/2 pigment {rgb x}} #end #if (Phi < -E) // Draw rotated circle #for (Theta, 0, tau, tau/Sides) // These are the coordinates of the default circle #local QY = Radius * cos (Theta); #local QZ = Radius * sin (Theta); // Now we apply a rotation matrix around the z axis // Since the circle is in the zy plane and we are // rotating around z, everything is a function of y #local MX = QY * sin (Phi); #local MY = QY * cos (Phi); #local MZ = QZ; #local M0 = + XY0; sphere {M0, Line/2 pigment {rgb x+y}} #end #end // -----------------DRAW LINES----------------- // draw tangent line cylinder {XY0, (Tangent*Radius*1.5) + XY0+E Line/2 pigment {rgb y}} // draw line parallel to x-axis cylinder {XY0, XY0 + (x*Radius*1.5) Line/2 pigment {rgb y}} // draw normal vector of curve cylinder {XY0, (Normal*Radius*1.5) + XY0 Line/2 pigment {rgb x+y}} // -----------------DRAW ARCS----------------- // make a torus segment for angle Phi object { Segment_of_Torus ( Radius*1.5, // radius major, Line/2, // radius minor, degrees(Phi) // segment angle (in degrees) ) pigment {rgb y} rotate -x*90 translate XY0 } // show rotated circle rotation by angle Phi object { Segment_of_Torus ( Radius, // radius major, Line/2, // radius minor, degrees(Phi) // segment angle (in degrees) ) pigment {rgb y} rotate -x*90 rotate z*90 //rotate -z*degrees (Phi) translate XY0 } // Show normal vector to function curve at 90 deg to tangent vector object { Segment_of_Torus ( Radius*1.5, // radius major, Line/2, // radius minor, 90 // segment angle (in degrees) ) pigment {rgb x+y} rotate -y*90 rotate -x*90 rotate -z*degrees(Phi) translate XY0 } // Draw a little perpedicular symbol between the normal and the tangent vectors cylinder {XY0+(Normal*Radius*0.5), (Tangent*Radius*0.5)+(Normal*Radius*0.5) + XY0+E Line/2 pigment {rgb x+y}} cylinder {XY0+(Tangent*Radius*0.5), (Normal*Radius*0.5)+(Tangent*Radius*0.5) + XY0 Line/2 pigment {rgb x+y}} } #end // end macro Implicit_DrawTbeCircleDiagram #macro Implicit_DrawTube (Start, End, Step, I_Function, I_Derivative, Radius, Sides, Texture) union { // create mesh vertices #local Rings = (End-Start)/Step; #local Mesh = array [Rings+1][Sides+1]; #local Ring = 0; #local LastPhi = 0; #for (UU, Start, End, Step) #local XY0 = ; #local Phi = Implicit_CalculatePhi (UU, I_Derivative); #local Phi = (abs (UU) + XY0; /* sphere {M0, Line/2 pigment {rgb x+y}} //#debug concat( "Counter = ", str(Counter, 0, 0), "\n") #if (Counter > 0) cylinder {M0, LastPoint Line/2} #end */ #local LastPoint = M0; //#debug concat( "Ring = ", str(Ring, 0, 0), ", Counter = ", str(Counter, 0, 0), "\n") #local Mesh [Ring][Counter] = M0; #local Counter = Counter + 1; #end #local Ring = Ring + 1; #local LastPhi = Phi; #end #local RR = dimension_size (Mesh, 1)-1; #local VV = dimension_size (Mesh, 2)-1; // Draw tube mesh #for (R, 1, RR) #for (V, 1, VV) //#debug concat( "R = ", str(R, 0, 0), ", V = ", str(V, 0, 0), "\n") #local V1 = mod (V+1, Sides); //cylinder {Mesh[R][V], Mesh[R][V1] Line pigment {rgb z}} triangle {Mesh [R][V-1], Mesh [R-1][V], Mesh [R-1][V-1]} triangle {Mesh [R][V] , Mesh [R-1][V], Mesh [R] [V-1]} #end #end texture {Texture} } #end // end macro Implicit_DrawTube // ################################################################# // ################# MACROS FOR IMPLICIT FUNCTIONS ################# union { #undef Function #undef Derivative #declare Function = function (U) {U*U+1} #declare Derivative = function (U) {2*U} //Implicit_DrawCentralFunction (-2, 2, 0.05, Function) //Implicit_DrawTbeCircleDiagram (Function, Derivative, 1.5, 180, 0.1) Implicit_DrawTube (-1.5, 1.5, 0.05, Function, Derivative, 0.1, 180, texture {pigment {rgb z} finish {specular 0.4}}) scale 0.25 translate <-2.5, 3, 0> } union { #undef Function #undef Derivative #declare Function = function (U) {0.4 * cos (U) * (-pow (U, 2) + 3 ) -1} #declare Derivative = function (U) {0.4 * (pow (U, 2) - 3 )* sin (U) - 0.8 * U * cos (U)} Implicit_DrawTube (-4, 4, 0.05, Function, Derivative, 0.1, 180, texture {pigment {rgb x+z} finish {specular 0.4}}) scale 0.5 translate < 0, 1, 0> } union { #undef Function #undef Derivative #declare Function = function (U) {U*U*U} #declare Derivative = function (U) {3*U*U} //Implicit_DrawCentralFunction (-2, 2, 0.05, Function) //Implicit_DrawTbeCircleDiagram (Function, Derivative, 1.5, 180, 0.1) Implicit_DrawTube (-1.5, 1.5, 0.05, Function, Derivative, 0.1, 180, texture {pigment {rgb y/2} finish {specular 0.4}}) scale 0.25 translate < 2.5, 3, 0> } // sind //#declare Function = function (U) {U * sin (tau/U)+1} //#declare Derivative = function (U) {sin (tau/U) - (tau*cos(tau/U))/U} // Stepped sine wave //#declare Function = function (U) {(floor(5* sin (U)))/5 +1} //#declare Derivative = function (U) {cos (U)} union { // hyperbolic tangent (tanh) #undef Function #undef Derivative #declare Function = function (U) {4 * (sinh (U) / cosh (U)) + 4} #declare Derivative = function (U) {pow (1/cosh(U), 2)} //Implicit_DrawCentralFunction (-2, 2, 0.05, Function) //Implicit_DrawTbeCircleDiagram (Function, Derivative, 1.5, 180, 0.1) Implicit_DrawTube (-3, 3, 0.05, Function, Derivative, 0.1, 180, texture {pigment {rgb x/2} finish {specular 0.4}}) Implicit_GraphPhi (-3.05, 3, 0.05, Function, Derivative) scale 0.25 translate < 2.5, 0, -0.5> } union { // hyperbolic tangent (tanh) #undef Function #undef Derivative #declare Function = function (U) {8*(U/(abs(U)+1))} #declare Derivative = function (U) {pow (1/(abs(x)+1), 2)} //Implicit_DrawCentralFunction (-2, 2, 0.05, Function) //Implicit_DrawTbeCircleDiagram (Function, Derivative, 1.5, 180, 0.1) Implicit_DrawTube (-8, 8, 0.05, Function, Derivative, 0.1, 180, texture {pigment {rgb x/2} finish {specular 0.4}}) Implicit_GraphPhi (-8, 8, 0.05, Function, Derivative) scale 0.25 translate < 0, 2, -0.5> }