|
![](/i/fill.gif) |
This is not a question but just the results of what I have been working on.
Below are 3 macros (and an example) of how to smoothly join a cylinder and a
sphere using nothing but CSG.
All you have to know is Pythagoras' Theorem (c^2 = a^2 + b^2) and the fact
that sin(angle) = opposite / hypotenuse.
The best part is that the angle in sin(angle) is irrelevant here.
This stuff was inspired by Tor Olav Kristenson's "CSG-Glass_Ball.jpg" from
his site.
I thought it looked awesome and I wanted to know how to do it.
This is what I have come up with and I am currently working on joining two
cylinders together at right angles to each other like the handle of a
coffee cup.
The only way I can think of to do it is to bend a torus in a circular arc
and cut that out of a slightly larger cylinder. The reason the torus needs
to be bent is to keep in line with the curvature of the large cylinder.
The only way I can think of to do this is an isosurface and I did in fact do
it but it didn't fit perfectly like the cylinder/sphere join. Oh well...
I hope this inspires others to do smooth CSG!!!
Nathan
// Returns a csg connector that connects a cylinder to the outside of a
larger sphere
// r - radius of sphere
// a - radius of cylinder
// d - distance of cylinder's cap from the centre of the sphere
// Notes:
// * the returned object is pointing directly up (in the +y direction)
// * the following rules must be observed: r>a>0 and d<r (I don't know if
d>a or something)
#macro Cyl_Sphere_Connector(r,a,d)
#local p=0.5*(d*d+a*a-r*r)/(r-a);
intersection
{
cylinder{0 d*y r*(a+p)/(r+p)}
torus{p+a p translate d*y inverse}
}
#end
// Returns an object to cut out of a sphere for a smooth inside join with a
smaller cylinder
// This macro is meant to be used in tandem with the
Cyl_SphereInside_Addon() macro
// r - radius of sphere
// a - radius of cylinder
// d - distance of cylinder's cap from the centre of the sphere
// Notes:
// * the returned object is pointing directly up (in the +y direction)
// * the following rules must be observed: r>a>0 and d<r (I don't know if
d>a or something)
#macro Cyl_SphereInside_Cutout(r,a,d)
#local p=-0.5*(d*d+a*a-r*r)/(r+a);
cylinder{2*r*y d*y r*(a+p)/(r-p)}
#end
// Returns an object to add on to a sphere for a smooth inside join with a
smaller cylinder
// This macro is meant to be used in tandem with the
Cyl_SphereInside_Cutout() macro
// You should first cut out the Cyl_SphereInside_Cutout() object and then
add this one on
// r - radius of sphere
// a - radius of cylinder
// d - distance of cylinder's cap from the centre of the sphere
// Notes:
// * the returned object is pointing directly up (in the +y direction)
// * the following rules must be observed: r>a>0 and d<r (I don't know if
d>a or something)
#macro Cyl_SphereInside_Addon(r,a,d)
#local p=-0.5*(d*d+a*a-r*r)/(r+a);
torus{p+a p translate d*y}
#end
// ******************************************* EXAMPLES
union
{
sphere{0 1}
object{Cyl_Sphere_Connector(1,0.2,2)}
object{Cyl_Sphere_Connector(1,0.2,2) rotate<0,0,-90>}
translate 2*x
texture{pigment{rgb<1,0,0.3>}finish{specular 0.3 roughness 0.1 reflection
0.3}}
}
union
{
difference
{
sphere{0 1}
object{Cyl_SphereInside_Cutout(1,0.2,0.5)}
object{Cyl_SphereInside_Cutout(1,0.2,0.5) rotate<-90,0,0>}
}
object{Cyl_SphereInside_Addon(1,0.2,0.5)}
object{Cyl_SphereInside_Addon(1,0.2,0.5) rotate<-90,0,0>}
translate -2*x
texture{pigment{rgb<0,0.3,1>}finish{specular 0.3 roughness 0.1 reflection
0.3}}
}
camera
{
location<0,4,-5>
look_at<0,0,0>
right (image_width/image_height)*x
}
light_source{<15,25,-25>rgb 1.2}
plane{y,-2 pigment{rgb 1}}
// END OF CODE
Post a reply to this message
|
![](/i/fill.gif) |