POV-Ray : Newsgroups : povray.advanced-users : Awesome Smooth CSG Joins : Awesome Smooth CSG Joins Server Time
28 Jul 2024 14:23:00 EDT (-0400)
  Awesome Smooth CSG Joins  
From: Captain Chemistry
Date: 10 Dec 2004 20:40:00
Message: <web.41ba4eb29c50f4181f2540760@news.povray.org>
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

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.