Template:Shed with conic dormer; Povray code

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
#include "colors.inc"
#include "math.inc"


#version 3.6;  // needed for transparent background

global_settings { assumed_gamma 1.0 }


/////////////////////////////////////////////////////////////////////////////////////


#declare EdgeRadius = .02;

#declare Transparency = .1;

#declare WallsBox = box {
    <-5, 0, 0>, <5, 9, 6.5>
    pigment{color rgbt <1, .8, .3, Transparency>}  // wall color
}

#declare RoofAngle = atan2d(4, 6.5);  // slope of the roof

#declare RoofCutPlane =   plane {
  -y, 0
  rotate -RoofAngle * x
  translate 4 * y
  pigment{color rgbt <1, .2, .2, Transparency>}  // roof color
}

#declare RawHouse = difference{
  object{WallsBox}
  object{RoofCutPlane}
}


#declare LeftBottomFront = <-5, 0, 0>;
#declare LeftTopFront = <-5, 4, 0>;
#declare LeftBottomBack = <-5, 0, 6.5>;
#declare LeftTopBack = <-5, 8, 6.5>;

#declare RightBottomFront = <5, 0, 0>;
#declare RightTopFront = <5, 4, 0>;
#declare RightBottomBack = <5, 0, 6.5>;
#declare RightTopBack = <5, 8, 6.5>;


#declare RawHouseLines = union{
  sphere{LeftBottomFront, EdgeRadius}
  sphere{LeftTopFront, EdgeRadius}
  sphere{LeftBottomBack, EdgeRadius}
  sphere{LeftTopBack, EdgeRadius}
  
  sphere{RightBottomFront, EdgeRadius}
  sphere{RightTopFront, EdgeRadius}
  sphere{RightBottomBack, EdgeRadius}
  sphere{RightTopBack, EdgeRadius}

  cylinder{LeftBottomFront, RightBottomFront, EdgeRadius}
  cylinder{LeftBottomBack, RightBottomBack, EdgeRadius}
  cylinder{LeftTopFront, RightTopFront, EdgeRadius}
  cylinder{LeftTopBack, RightTopBack, EdgeRadius}
  
  cylinder{LeftBottomFront, LeftBottomBack, EdgeRadius}
  cylinder{LeftTopFront, LeftTopBack, EdgeRadius}
  cylinder{RightBottomFront, RightBottomBack, EdgeRadius}
  cylinder{RightTopFront, RightTopBack, EdgeRadius}
  
  cylinder{LeftBottomFront, LeftTopFront, EdgeRadius}
  cylinder{LeftBottomBack, LeftTopBack, EdgeRadius}
  cylinder{RightBottomFront, RightTopFront, EdgeRadius}
  cylinder{RightBottomBack, RightTopBack, EdgeRadius}
}


/////////////////////////////////////////////////////////////////////////////////////


#declare AZ = 0.8125;  // dormer offset, i.e. horizontal distance between front wall and dormer window
#declare AY = 6.5;
#declare A = <0, AY, AZ>;  // highest point of dormer window

#declare DormerCutPlane =   plane{
  z, AZ
  pigment{color rgbt <.3, .7, 1, Transparency>}  // window color
}

#declare BZ = 4.875;  // dormer depth, i.e. horizontal distance between front wall and intersection point of roof and dormer ridge
#declare BY = 7;
#declare B = <0, BY, BZ>;  // highest point of dormer mantle

#declare DormerAngle = atan2d(BY-AY, BZ-AZ);  // slope of the dormer ridge

#declare CZ = 11.5;
#declare CY = (BY-AY) / (BZ-AZ) * (CZ - AZ) + AY;
#declare C = <0, CY, CZ>;  // cone vertex

#declare DY = AY - 2;  // ordinate of the the dormer window base
#declare DZ = AZ;
#declare D = <0, DY, DZ>;  // center of dormer window base

#declare ConeAngle = 37.5;
#declare HalfConeAngle = ConeAngle / 2;
#declare Alpha = HalfConeAngle + DormerAngle;  // angle of the center line of the cone

#declare H = <0, CY, -99>;
#declare ConeRadius = tand(HalfConeAngle) * (99 + CZ);
#declare HorizontalCone = cone{
  C, 0, H, ConeRadius
  pigment{color rgbt <.65, .15, .15, Transparency>}  // cone color
};
#declare Cone = object{
  HorizontalCone
  translate -C
  rotate Alpha * -x
  translate C
}


/////////////////////////////////////////////////////////////////////////////////////


#declare Beta = DormerAngle / 2 - 45;  // negative angle of the angle bisection through A (leads to R)

#declare PY = CY - tand(Alpha) * CZ;
#declare QY = AY - AZ / tand(Beta);

#declare RZ = (PY-QY) / (tand(Beta)-tand(Alpha));
#declare RY = tand(Beta) * RZ + QY;

#declare Gamma = DormerAngle + ConeAngle;  // angle of the lower mantle line of the cone
#declare GY = -tand(Gamma) * (CZ-AZ) + CY;  // ordinate of the lowest point of the ellipse
#declare MY = (AY+GY) / 2;  // ordinate of the center of the ellipse

#declare Major = (AY-GY) / 2;  // major radius of the ellipse
#declare Linex = RY - MY;  // linear excentricity of the ellipse (distance of center and focal point)
#declare Minor = sqrt( pow(Major, 2) - pow(Linex, 2) );
#declare Minor = Minor + .037;  // WHY IS THIS CORRECTION NECESSARY?


// equation of the ellipse, with a = Major and b = Minor:
// x^2   (y-my)^2
// ——— + ———————— = 1
// a^2     b^2

// solved for x, DY as y:
#declare DormerHalfWidth = sqrt(
  pow(Minor, 2)   *   (    1    -   pow(DY - MY, 2) / pow(Major, 2)    )
);

#declare DL = D - DormerHalfWidth*x;
#declare DR = D + DormerHalfWidth*x;
#declare DormerBase = cylinder{DL, DR, EdgeRadius};


/////////////////////////////////////////////////////////////////////////////////////


#declare Dormer = intersection{
  difference{
    object{Cone}
    object{DormerCutPlane}
  }
  object{RoofCutPlane}
}


#declare Ellipse = union{
  #for (X, -DormerHalfWidth, DormerHalfWidth, .001)
      #declare Y = sqrt(
        pow(Major, 2)   *   (    1    -   pow(X, 2) / pow(Minor, 2)    )
      ) + MY;
      sphere{ <X, Y, AZ>, EdgeRadius }
  #end
}


/////////////////////////////////////////////////////////////////////////////////////


#declare Delta = (DormerAngle + RoofAngle) / 2 - 90;  // negative angle of the angle bisection through B (leads to S)

// center of hyperbola Dandelin sphere
#declare SZ = ( PY - BY + tand(Delta) * BZ )  /  ( tand(Delta) - tand(Alpha) );
#declare SY = tand(Alpha) * SZ + PY;

#declare Theta = RoofAngle - 90;  // negative angle of line between T (focus) and S (Dandelin sphere center)

// hyperbola focus
#declare TZ = ( 4 - SY + tand(Theta) * SZ )  /  ( tand(Theta) - tand(RoofAngle) );
#declare TY = tand(RoofAngle) * TZ + 4;

#declare DistBT = sqrt(  pow(BZ-TZ, 2)  +  pow(BY-TY, 2)  );

// opposite hyperbola vertex
#declare VZ = ( 4 - CY + tand(Gamma) * CZ ) / ( tand(Gamma) - tand(RoofAngle) );
#declare VY = tand(Gamma) * VZ + CY - tand(Gamma) * CZ;

// hyperbola center
#declare WZ = (BZ+VZ) / 2;
#declare WY = (BY+VY) / 2;

#declare DistDW = sqrt(  pow(WZ-DZ, 2)  +  pow(WY-DY, 2)  );

#declare HyperbolaVertexDist = sqrt(  pow(VZ-BZ, 2)  +  pow(VY-BY, 2)  );
#declare HyperbolaMajor = HyperbolaVertexDist / 2;
#declare HyperbolaLinex = HyperbolaMajor + DistBT;
#declare HyperbolaMinor = sqrt(  pow(HyperbolaLinex, 2)  -  pow(HyperbolaMajor, 2)  );

// equation of the hyperbola, with a = HyperbolaMajor and b = HyperbolaMinor:
// x^2   y^2
// ——— - ——— = 1
// a^2   b^2

#declare Hyperbola = union{
  #for (X, HyperbolaMajor, DistDW, .0001)
      #declare Y = sqrt(
        pow(HyperbolaMinor, 2)   *   (   pow(X, 2) / pow(HyperbolaMajor, 2)   -   1    )
      );
      sphere{ <X, Y, BZ>, EdgeRadius }
      sphere{ <X, -Y, BZ>, EdgeRadius }
  #end
  
  rotate 90*z
  translate (BY-HyperbolaMajor) * y
  translate -B
  rotate (- 90 - RoofAngle) * x
  translate B
}


/////////////////////////////////////////////////////////////////////////////////////


#declare Small = .12345;
#declare WindowCutter = union{
  box{<-3.5, 1, -Small>, <-2.5, 2.5, Small>}
  cylinder{<-3, 2.5, -Small>, <-3, 2.5, Small>, .5}
  pigment{color rgbt 1}
}

#declare SideWindowCutter = object{
  WindowCutter
  translate 3*x
  rotate 90*y
  translate <5, 0, 2>
}
#declare SideWindowCutter = union{
  object{SideWindowCutter}
  object{SideWindowCutter  translate 2.5*z}
}
#declare SideWindowCutter = union{
  object{SideWindowCutter}
  object{SideWindowCutter  translate -10*x}
}

#declare WindowCutter = union{
  object{WindowCutter}
  object{WindowCutter  translate 6*x}
  object{SideWindowCutter}
}


///////////////////////////////////////


#declare WindowArch = difference{
  torus{.5, EdgeRadius  rotate 90*x}
  plane{y, 0}
  translate <-3, 2.5, 0>
}

#declare WindowFrame = union{
  object{WindowArch}
  cylinder{<-3.5, 1, 0>, <-3.5, 2.5, 0>, EdgeRadius}
  cylinder{<-2.5, 1, 0>, <-2.5, 2.5, 0>, EdgeRadius}
  cylinder{<-3.5, 1, 0>, <-2.5, 1, 0>, EdgeRadius}
  sphere{<-3.5, 1, 0>, EdgeRadius}
  sphere{<-2.5, 1, 0>, EdgeRadius}
  pigment{color srgb .2}  // strong edge color
}

#declare Window = union{
  object{WindowFrame}
  union{
    difference{
      disc{<-3, 2.5, 0>, <-3.5, 2.5, 999>, .5}
      plane{y, 2.5}
    }
    polygon{5, <-3.5, 1, 0>, <-2.5, 1, 0>, <-2.5, 2.5, 0>, <-3.5, 2.5, 0>, <-3.5, 1, 0>}
    pigment{color rgbt <.3, .7, 1, Transparency>}  // window color
  }
}

#declare SideWindows = object{
  Window
  translate 3*x
  rotate 90*y
  translate <5, 0, 2>
}
#declare SideWindows = union{
  object{SideWindows}
  object{SideWindows  translate 2.5*z}
}
#declare SideWindows = union{
  object{SideWindows}
  object{SideWindows  translate -10*x}
}

#declare Windows = union{
  object{Window}
  object{Window  translate 6*x}
  object{SideWindows}
}


///////////////////////////////////////////////////////


#declare DoorCutter = difference{
  union{
    box{<-1, 0, -Small>, <1, 2, Small>}
    cylinder{<0, 2, -Small>, <0, 2, Small>, 1}
  }
  plane{y, 0  rotate -45*x}
  pigment{color rgbt 1}
}

#declare HouseWithoutDormer = difference{
  object{RawHouse}
  union{
    object{WindowCutter}
    object{DoorCutter}
  }
}


///////////////////////////////////////


#declare DoorArch = difference{
  torus{1, EdgeRadius  rotate 90*x}
  plane{y, 0}
  translate 2*y
}

#declare DoorFrame = union{
  object{DoorArch}
  cylinder{<-1, 0, 0>, <-1, 2, 0>, EdgeRadius}
  cylinder{<1, 0, 0>, <1, 2, 0>, EdgeRadius}
  pigment{color srgb .2}  // strong edge color
}

#declare Door = union{
  object{DoorFrame}
  union{
    difference{
      disc{<0, 2, 0>, <0, 2, 999>, 1}
      plane{y, 2}
    }
    polygon{5, <-1, 0, 0>, <1, 0, 0>, <1, 2, 0>, <-1, 2, 0>, <-1, 0, 0>}
    pigment{color rgbt <.55, .3, .15, Transparency>}  // door color
  }
}


/////////////////////////////////////////////////////////////////////////////////////


#declare HouseCenter = <0, 4, 3.25>;

#declare House = union{
  merge{
    object{HouseWithoutDormer}
    object{Dormer}
  }

  union{
    object{Ellipse}
    object{Hyperbola}
    object{DormerBase}
    
    object{RawHouseLines}
    
    pigment{color srgb .2}  // strong edge color
  }

  object{Windows}
  object{Door}
  
  translate -HouseCenter  // move house center to origin
}


/////////////////////////////////////////////////////////////////////////////////////


#declare Case = "standard";  // standard, front, side, top (vertical), roof (diagonal)

/*
CONSOLE COMMANDS:

standard:
povray house.pov +ua +fn +W4200 +H3640

roof:
povray house.pov +ua +fn +W4200 +H4100

else:
povray house.pov +ua +fn +W4200 +H3450
*/

// camera position based on case
#if (Case = "standard")
  #declare CameraPosition = vnormalize(<18, 10, -45>) * 23.6;
#end
#if (Case = "front" | Case = "side")
  #declare CameraPosition = -20*z;
#end
#if (Case = "top")
  #declare CameraPosition = 20*y;
#end
#if (Case = "roof")
  #declare RoofNormal = <0, (BZ-DZ)/(BY-DY), -1>;
  #declare CameraPosition = vnormalize(RoofNormal) * 20;
#end

// object based on case
#if (Case = "side")
  object{ House  rotate 90*y }
#else
  object{House}
#end


camera{
	  orthographic
    location CameraPosition
    right    x*image_width/image_height
	  angle 30
    look_at 0
}

light_source{ <-400, 500, -300> color White shadowless}
light_source{ <400, 200, 100> color White shadowless}
light_source{ CameraPosition  color rgb<0.9,0.9,1>*0.7 shadowless}
sky_sphere{ pigment{ White } }