Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

AUnion.cpp

Go to the documentation of this file.
00001 /**
00002  * @file AUnion.cpp
00003  * Surface Modeling Library
00004  * CS497
00005  *
00006  * @author William Nagel
00007  */
00008 
00009 #include "AUnion.h"
00010 
00011 REGISTER_IMPLICIT(AUnion,"BinaryOp:Algebraic:Union");
00012 
00013 /**
00014  * Blending region is limited to f < r1, g < r2, f > 0, g > 0.
00015  */
00016 bool AUnion::indomain(double f, double g)
00017 {
00018   return f <= m_r1 && g <= m_r2 && f > 0 && g > 0;
00019 }
00020 
00021 bool AUnion::indomain(Intervald f, Intervald g)
00022 {
00023   Intervald r1(0.0,m_r1);
00024   Intervald r2(0.0,m_r2);
00025   return (f.overlaps(r1) && g.overlaps(r2));
00026 }
00027 
00028 /** 
00029  * Computes an elliptic union blend.
00030  * h(f,g) = -( (f - r1)^d/r1^d + (g - r2)^d/r2^d - 1).
00031  * Negated such that surface is negative inside.
00032  * Returns smaller of f or g if either is outside its
00033  * blending radius.
00034  *
00035  * When f = 0 and as g approaches r2, returns zero.
00036  * When g = 0 and as f approaches r1, returns zero.
00037  */
00038 double AUnion::h(double f, double g)
00039 {
00040   if (indomain(f,g))
00041     return 1.0 - pow(1.0 - f/m_r1, m_d) - 
00042                  pow(1.0 - g/m_r2, m_d);
00043   else
00044     return (f < g) ? f : g;
00045 }
00046 
00047 Intervald AUnion::h(Intervald f, Intervald g)
00048 {
00049   if (indomain(f,g))
00050     return Intervald(1.0) - 
00051           (Intervald(1.0) - f/Intervald(m_r1)).pow(Intervald(m_d)) - 
00052           (Intervald(1.0) - g/Intervald(m_r2)).pow(Intervald(m_d));
00053   else
00054     return (f < g) ? f : g;
00055 }
00056 
00057 /**
00058  * dh(f,g)/df = d f^(d-1)/r1
00059  */
00060 double AUnion::hf(double f, double g)
00061 {
00062   if (indomain(f,g))
00063     return m_d*pow(1.0 - f/m_r1,m_d-1.0)/m_r1;
00064   else
00065     return (f < g) ? 1.0 : 0.0;
00066 }
00067 
00068 Intervald AUnion::hf(Intervald f, Intervald g)
00069 {
00070   if (indomain(f,g))
00071     return Intervald(m_d) * 
00072           (Intervald(1.0) - f/Intervald(m_r1)).pow(Intervald(m_d-1.0)) / 
00073            Intervald(m_r1);
00074   else
00075     return (f < g) ? Intervald(1.0) : Intervald(0.0);
00076 }
00077 
00078 /**
00079  * dh(f,g)/dg = d g^(d-1)/r2
00080  */
00081 double AUnion::hg(double f, double g)
00082 {
00083   if (indomain(f,g))
00084     return m_d*pow(1.0 - g/m_r2,m_d-1.0)/m_r2;
00085   else
00086     return (f < g) ? 0.0 : 1.0;
00087 }
00088 
00089 Intervald AUnion::hg(Intervald f, Intervald g)
00090 {
00091   if (indomain(f,g))
00092     return Intervald(m_d) *
00093           (Intervald(1.0) - g/Intervald(m_r2)).pow(Intervald(m_d-1.0)) / 
00094            Intervald(m_r2);
00095   else
00096     return (f < g) ? Intervald(0.0) : Intervald(1.0);
00097 }
00098 
00099 /**
00100  * d2h(f,g)/df2 = d(d-1) f^(d-2)/r1.
00101  * m_d should be at least two.
00102  */
00103 double AUnion::hff(double f, double g)
00104 {
00105   if (indomain(f,g))
00106     return m_d*(m_d-1.0)*pow(1.0 - f/m_r1,m_d-2.0)/(m_r1*m_r1);
00107   else
00108     return 0.0;
00109 }
00110 
00111 Intervald AUnion::hff(Intervald f, Intervald g)
00112 {
00113   if (indomain(f,g))
00114     return Intervald(m_d) * Intervald(m_d-1.0) * 
00115           (Intervald(1.0) - f/Intervald(m_r1)).pow(Intervald(m_d-2.0)) / 
00116            Intervald(m_r1*m_r1);
00117   else
00118     return Intervald(0.0);
00119 }
00120 
00121 /**
00122  * d2h(f,g)/dg2 = d(d-1) g^(d-2)/r2
00123  */
00124 double AUnion::hgg(double f, double g)
00125 {
00126   if (indomain(f,g))
00127     return m_d*(m_d-1.0)*pow(1.0 - g/m_r2,m_d-2.0)/(m_r2*m_r2);
00128   else
00129     return 0.0;
00130 }
00131 
00132 Intervald AUnion::hgg(Intervald f, Intervald g)
00133 {
00134   if (indomain(f,g))
00135     return Intervald(m_d) * Intervald(m_d-1.0) *
00136           (Intervald(1.0) - g/Intervald(m_r2)).pow(Intervald(m_d-2.0)) / 
00137            Intervald(m_r2*m_r2);
00138   else
00139     return Intervald(0.0);
00140 }
00141 
00142 /** No mixed second derivatives.
00143  */
00144 double AUnion::hfg(double f, double g)
00145 {
00146   return 0.0;
00147 }
00148 
00149 Intervald AUnion::hfg(Intervald f, Intervald g)
00150 {
00151   return Intervald(0.0);
00152 }
00153 

Generated on Mon Jun 28 14:58:12 2004 for Advanced Surface Library by doxygen 1.3.4