 |
 |
|
 |
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
I am trying to figure out, because my geometry is weak, how to create a
Gothic trefoil design (http://www.newyorkcarver.com/geometry/Trifoil.htm)
fitting "comfortably" within another equilateral arch
(http://www.newyorkcarver.com/geometry/equilarch.htm).
Or, put another way, how to fit three mutually equidistant congruent circles
such that each circle is tangent to two adjacent sides of an equilateral
triangle.
Maybe someone could help me express the numeric relationships based on an
eq. triangle with one side = "x"?
Thanks!
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: Jellby
Subject: Re: Fitting a gothic trefoil into an equilateral triangle
Date: 12 Jun 2003 18:09:41
Message: <3ee8fa24@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Among other things, LibraryMan wrote:
> I am trying to figure out, because my geometry is weak, how to create a
> Gothic trefoil design (http://www.newyorkcarver.com/geometry/Trifoil.htm)
> fitting "comfortably" within another equilateral arch
> (http://www.newyorkcarver.com/geometry/equilarch.htm).
>
> Or, put another way, how to fit three mutually equidistant congruent
> circles such that each circle is tangent to two adjacent sides of an
> equilateral triangle.
> Maybe someone could help me express the numeric relationships based on an
> eq. triangle with one side = "x"?
- Circles with radius R.
- Centers of circles form a equilateral triangle ABC of side L
- All 3 circles are tangent to a "circumscribed" triangle abc of side l
- Circle centered in A touches abc in P and Q.
- aPA is a triangle with angles of 30, 90 and 60 degrees, one leg (PA) is R,
the other leg (aP) should be easy to calculate: sin(30)/R=sin(60)/aP
- The outer's triangle side (ab) is: aP+AB+Sb = 2*aP+L
- The relationship between R and L should be easy too: sin(60)=L/(2*R)
- I may be mistaken.
--
light_source{9+9*x,1}camera{orthographic look_at(1-y)/4angle 30location
9/4-z*4}light_source{-9*z,1}union{box{.9-z.1+x clipped_by{plane{2+y-4*x
0}}}box{z-y-.1.1+z}box{-.1.1+x}box{.1z-.1}pigment{rgb<.8.2,1>}}//Jellby
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
// Hi LibraryMan,
//
// here is some code for you to play with; the radius of the circles
// can be specified:
//
// Side * (sqrt(3)-1)/4 circles are mutually touching
// Side * sqrt(3)/9 circles intersect in midpoint ("true gothic")
// Side * sqrt(3)/6 circles have max. size (all are equal)
//
// The distance of the centers (distance AB as named in your link) is
//
// Side-2*sqrt(3)*Radius
//
//
//
// Sputnik
//
//
// ----------------------------
// Frank 'Sputnik' Rothfuß
// fr### [at] computermuseum fh-kiel de
// ----------------------------
// +W640 +H480 -F +D +A0.1
// macro for trefoil ====================================================
#macro Trefoil (Side, Radius) // lower left corner at origin
#local R = 0.005; // "Linewidth"/2
#local Height = sqrt(3)/2*Side;
#local Corner1 = <Side/2, Height, 0>; // top corner
#local Corner2 = 0; // bottom left corner
#local Corner3 = Side*x; // bottom right corner
#local Center = <Side/2, Height/3, 0>; // triangle
#local Center1 = <Side/2, Height-2*Radius, 0>; // top circle
#local Center2 = <sqrt(3)*Radius, Radius, 0>; // bottom left circle
#local Center3 = <Side-sqrt(3)*Radius, Radius, 0>; // bottom right circle
union {
union {
sphere { Corner1, R }
sphere { Corner2, R }
sphere { Corner3, R }
cylinder { Corner1, Corner2, R }
cylinder { Corner2, Corner3, R }
cylinder { Corner3, Corner1, R }
texture { pigment { color green 1 } finish { ambient 1 } }
}
union {
torus { Radius, R rotate 90*x translate Center1 }
torus { Radius, R rotate 90*x translate Center2 }
torus { Radius, R rotate 90*x translate Center3 }
texture { pigment { color red 1 } finish { ambient 1 } }
}
// "}" omitted to allow application of transformations
#end//macro Trefoil
// simple scene with trefoils ===========================================
Trefoil ( 1 , 1*(sqrt(3)-1)/4 ) translate <-1.6, 0.2 , 1> } // small
Trefoil ( 2 , 2*sqrt(3)/9 ) translate <-1 , -1 , 1> } // gothic
Trefoil ( 1 , 1*sqrt(3)/6 ) translate < 0.6, 0.2 , 1> } // large
light_source { <-1500, 2500, -2000>, color rgb 1 }
camera { orthographic up 3*y right 4*x }
// END ==================================================================
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: LinuxLibrarian
Subject: Re: Fitting a gothic trefoil into an equilateral triangle
Date: 13 Jun 2003 08:59:00
Message: <3ee9ca94@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Jellby wrote:
>
> - Circles with radius R.
> - Centers of circles form a equilateral triangle ABC of side L
> - All 3 circles are tangent to a "circumscribed" triangle abc of side l
> - Circle centered in A touches abc in P and Q.
> - aPA is a triangle with angles of 30, 90 and 60 degrees, one leg (PA) is R,
> the other leg (aP) should be easy to calculate: sin(30)/R=sin(60)/aP
> - The outer's triangle side (ab) is: aP+AB+Sb = 2*aP+L
> - The relationship between R and L should be easy too: sin(60)=L/(2*R)
> - I may be mistaken.
>
Looks great, and thanks, but... What's the "S" in Sb? :-}
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: LinuxLibrarian
Subject: Re: Fitting a gothic trefoil into an equilateral triangle
Date: 13 Jun 2003 09:01:27
Message: <3ee9cb27@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Frank 'Sputnik' Rothfuß wrote:
> // Hi LibraryMan,
> //
> // here is some code for you to play with; the radius of the circles
> // can be specified:
> //
> // Side * (sqrt(3)-1)/4 circles are mutually touching
> // Side * sqrt(3)/9 circles intersect in midpoint ("true gothic")
> // Side * sqrt(3)/6 circles have max. size (all are equal)
> //
> // The distance of the centers (distance AB as named in your link) is
> //
> // Side-2*sqrt(3)*Radius
> //
> //
> //
> // Sputnik
> //
> //
> // ----------------------------
> // Frank 'Sputnik' Rothfuß
> // fr### [at] computermuseum fh-kiel de
> // ----------------------------
>
>
> // +W640 +H480 -F +D +A0.1
>
> // macro for trefoil ====================================================
>
> #macro Trefoil (Side, Radius) // lower left corner at origin
>
> #local R = 0.005; // "Linewidth"/2
>
> #local Height = sqrt(3)/2*Side;
>
> #local Corner1 = <Side/2, Height, 0>; // top corner
> #local Corner2 = 0; // bottom left corner
> #local Corner3 = Side*x; // bottom right corner
>
> #local Center = <Side/2, Height/3, 0>; // triangle
>
> #local Center1 = <Side/2, Height-2*Radius, 0>; // top circle
> #local Center2 = <sqrt(3)*Radius, Radius, 0>; // bottom left circle
> #local Center3 = <Side-sqrt(3)*Radius, Radius, 0>; // bottom right circle
>
> union {
> union {
> sphere { Corner1, R }
> sphere { Corner2, R }
> sphere { Corner3, R }
> cylinder { Corner1, Corner2, R }
> cylinder { Corner2, Corner3, R }
> cylinder { Corner3, Corner1, R }
> texture { pigment { color green 1 } finish { ambient 1 } }
> }
> union {
> torus { Radius, R rotate 90*x translate Center1 }
> torus { Radius, R rotate 90*x translate Center2 }
> torus { Radius, R rotate 90*x translate Center3 }
> texture { pigment { color red 1 } finish { ambient 1 } }
> }
> // "}" omitted to allow application of transformations
>
> #end//macro Trefoil
>
>
> // simple scene with trefoils ===========================================
>
> Trefoil ( 1 , 1*(sqrt(3)-1)/4 ) translate <-1.6, 0.2 , 1> } // small
> Trefoil ( 2 , 2*sqrt(3)/9 ) translate <-1 , -1 , 1> } // gothic
> Trefoil ( 1 , 1*sqrt(3)/6 ) translate < 0.6, 0.2 , 1> } // large
>
> light_source { <-1500, 2500, -2000>, color rgb 1 }
>
> camera { orthographic up 3*y right 4*x }
>
>
> // END ==================================================================
>
>
Thanks, I'll play with this too! (not to confuse people, but LibraryMan
and LinuxLibrarian are the same person, but LibraryMan is my screen name
for when I'm posting via the web interface to the newsgroup)
--LinuxLibrarian
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: Jellby
Subject: Re: Fitting a gothic trefoil into an equilateral triangle
Date: 13 Jun 2003 10:38:19
Message: <3ee9e1db@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Among other things, LinuxLibrarian wrote:
> Jellby wrote:
>>
>> - Circles with radius R.
>> - Centers of circles form a equilateral triangle ABC of side L
>> - All 3 circles are tangent to a "circumscribed" triangle abc of side l
>> - Circle centered in A touches abc in P and Q.
>> - aPA is a triangle with angles of 30, 90 and 60 degrees, one leg (PA) is
>> R, the other leg (aP) should be easy to calculate: sin(30)/R=sin(60)/aP
>> - The outer's triangle side (ab) is: aP+AB+Sb = 2*aP+L
>> - The relationship between R and L should be easy too: sin(60)=L/(2*R)
>> - I may be mistaken.
>>
>
> Looks great, and thanks, but... What's the "S" in Sb? :-}
It would be one the point where the circle centered on B touches the ab
side. Have you drawn it?
--
light_source{9+9*x,1}camera{orthographic look_at(1-y)/4angle 30location
9/4-z*4}light_source{-9*z,1}union{box{.9-z.1+x clipped_by{plane{2+y-4*x
0}}}box{z-y-.1.1+z}box{-.1.1+x}box{.1z-.1}pigment{rgb<.8.2,1>}}//Jellby
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Jellby wrote:
>It would be one the point where the circle centered on B touches the ab
>side. Have you drawn it?
I thought that was what you might mean, but wanted to make sure, since you
assigned letters to all the other points you specifically referenced....
:-)
--Mark
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: LinuxLibrarian
Subject: Re: Fitting a gothic trefoil into an equilateral triangle
Date: 17 Jun 2003 19:56:40
Message: <3eefaab8@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Frank 'Sputnik' Rothfuß wrote:
> // Hi LibraryMan,
> //
> // here is some code for you to play with; the radius of the circles
> // can be specified:
> //
> // Side * (sqrt(3)-1)/4 circles are mutually touching
> // Side * sqrt(3)/9 circles intersect in midpoint ("true gothic")
> // Side * sqrt(3)/6 circles have max. size (all are equal)
> //
> // The distance of the centers (distance AB as named in your link) is
> //
> // Side-2*sqrt(3)*Radius
> //
> //
> //
> // Sputnik
> //
> //
> // ----------------------------
> // Frank 'Sputnik' Rothfuß
> // fr### [at] computermuseum fh-kiel de
> // ----------------------------
>
>
> // +W640 +H480 -F +D +A0.1
>
> // macro for trefoil ====================================================
>
> #macro Trefoil (Side, Radius) // lower left corner at origin
>
> #local R = 0.005; // "Linewidth"/2
>
> #local Height = sqrt(3)/2*Side;
>
> #local Corner1 = <Side/2, Height, 0>; // top corner
> #local Corner2 = 0; // bottom left corner
> #local Corner3 = Side*x; // bottom right corner
>
> #local Center = <Side/2, Height/3, 0>; // triangle
>
> #local Center1 = <Side/2, Height-2*Radius, 0>; // top circle
> #local Center2 = <sqrt(3)*Radius, Radius, 0>; // bottom left circle
> #local Center3 = <Side-sqrt(3)*Radius, Radius, 0>; // bottom right circle
>
> union {
> union {
> sphere { Corner1, R }
> sphere { Corner2, R }
> sphere { Corner3, R }
> cylinder { Corner1, Corner2, R }
> cylinder { Corner2, Corner3, R }
> cylinder { Corner3, Corner1, R }
> texture { pigment { color green 1 } finish { ambient 1 } }
> }
> union {
> torus { Radius, R rotate 90*x translate Center1 }
> torus { Radius, R rotate 90*x translate Center2 }
> torus { Radius, R rotate 90*x translate Center3 }
> texture { pigment { color red 1 } finish { ambient 1 } }
> }
> // "}" omitted to allow application of transformations
>
> #end//macro Trefoil
>
>
> // simple scene with trefoils ===========================================
>
> Trefoil ( 1 , 1*(sqrt(3)-1)/4 ) translate <-1.6, 0.2 , 1> } // small
> Trefoil ( 2 , 2*sqrt(3)/9 ) translate <-1 , -1 , 1> } // gothic
> Trefoil ( 1 , 1*sqrt(3)/6 ) translate < 0.6, 0.2 , 1> } // large
>
> light_source { <-1500, 2500, -2000>, color rgb 1 }
>
> camera { orthographic up 3*y right 4*x }
>
>
> // END ==================================================================
>
>
Following up after your explanation about the unintentional personal
reply, I appreciate your offer to give further explanation. I realized
after my original posting of the question that it's theoretically
possible to have numerous (even infinite?) possibilities for circles
within a triangle which fit the parameters I mentioned. The circles
could be infinitely small and still fit, being tangent to both sides
surrounding a vertex.
The 2nd configuration you listed, with the radius equal to Side *
sqrt(3)/9 , was of course the one I had in mind, but how did you figure
out the math? Just curious -- I rendered it and it works, sure, so I'm
not "looking a gift horse in the mouth"
Thanks,
Mark
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Hi Mark,
here is "The Making of '#macro Trefoil'"; names starting with an
uppercase letter refer to variables in the code of my last post.
(don't underestimate the importance of the first two of the following
points!)
1. Find out the given and wanted elements (lengths, angles, ...)
and choose descriptive names for them
You asked for inscribing circles into an equilateral triangle, so all
of its angles are 60 degrees. The length of its sides is given; this
length got the name 'Side'. Obviously the triangle is to be erected
over a horizontal line, so it has a top corner ('Corner1'), a bottom
left corner ('Corner2') and a bottom right corner ('Corner3').
Because the problem has an infinite number of solutions, I decided
to use the radius 'Radius' of the circles as independent variable
and to calculate their midpoints 'Center1', ... , 'Center3'.
2. Choose a coordinate system
Usually the math is easier when many coordinates are 0 or 1: multiplying
by 1 is trivial, by 0 even more; adding of 0 is trivial; squaring 0 or 1
is the same as doing nothing; and so on.
If there is a mirror symmetry with respect to a line/point, then very often
(but not always) this line/point is well suited as coordinate axis/origin.
Sometimes it is easier to solve a standard problem and then transform
it to the required proportions; for example (in POV style): instead
of sphere{C,R ... } use sphere{0,1 ... scale R translate C}.
The trefoil is a problem in plane geometry, so I only use x- and y-
coordinates and set all z=0 (I will leave them out here, but had written
these zeros in the code).
Because circles are to be put into the *corners* of the outer triangle,
I decided to use a corner (Corner2) as origin, so
Corner2=<0,0>
Corner3 sits on the x-axis, so
Corner3=<Side,0>.
3. Make a drawing of the geometric situation
In most cases, an approximate scetch without large obvious errors will
suffice. Use thick lines for every known element. Don't believe everything
you see! The drawing can't prove anything, its sole purpose is to trigger
the intuition and to keep track of the known and the not-yet-known
elements. Do this even for very simple situations.
(Please do this *now* to make it easy to follow the following explanations!)
4. Look for properties that allow application of geometric theorems
Very often symmetries, right angles, congruent triangles and parallels
are the key for a solution. If you have none, create them by erecting
perpendiculars, drawing parallels etc.
This is the inspiration part of the solution of geometric problems.
5. Find out relevant elements (coordinates, lengths, angles, ...) until all
wanted elements are known
This is the transpiration part of the solution of geometric problems.
[ top corner ]
The first step in the trefoil problem is to find the top corner. Due to
the triangle's mirror symmetry with respect to the perpendicular from
the top corner,
Corner1.x=Side/2.
The y-coordinate is the Height of the triangle, found by the law of
pythagoras in the right-angled triangle
top point -- bottom left point -- midpoint of base line
so we get
Height^2 + (Side/2)^2 = Side^2
Solving for Height gives
Height = sqrt( Side^2 + Side^2/4 ) = sqrt(3)/2*Side
[ centers ]
Now look at the midpoint 'Center2' of a circle touching the sides
emanating from Corner2. Due to symmetry of this circle and the triangle
with respect to the line through Corner2 and Center2, the angle between
this line and the x-axis is 30 degrees (60/2). Now imagine a new point:
the mirror image 'M' of Center1 with respect to the x-axis. The triangle
Corner2 -- Center1 -- M
has 30+30 degrees at Corner1 (x-axis symmetry), its other two angles are
equal (same symmetry). So all angles are 60 degrees, i.e. this triangle
is equilateral. The vertical side obviously has a length=2*Radius, and
because of the equilaterality, the other sides have the same length. The
part of the x-axis within this triangle is a height of this triangle, and
as seen above with the outer triangle, height=sqrt(3)/2*length_of_side.
But this height of the small triangle is the x-coordinate of Center2!
So we have
Center2.x = sqrt(3)/2 * 2*Radius = sqrt(3)*Radius
and obviously
Center2.y = Radius
By symmetry with respect to the perpendicular from the top corner onto
the x-axis:
Center3.x = Side - sqrt(3)*Radius
Center3.y = Radius
As seen above,
distance between Center2 and Corner2
= length_of_side of the small triangle
= 2*Radius
Because the three circles are equal,
distance between Center1 and Corner1 = 2*Radius
I.e. Center1 is 2*Radius below Corner1, so we get
Center1 = <Side/2, Height-2*Radius>
[ maximal Radius, minimal Radius ]
Because all triangles should lie completely inside the outer triangle,
the maximal Radius is the radius of the incircle. Then (symmetry!)
center2_for_max_Radius.x = Side/2
Above we found
Center2.x = sqrt(3)*Radius
For the maximal circle we get
center2_for_max_Radius.x = sqrt(3)*max_radius
So
Side/2 = sqrt(3)*max_radius
i.e.
max_Radius = Side/2/sqrt(3) = Side * sqrt(3)/6
The minimal Radius obviously is zero, so all values in the range
0 .. Side*sqrt(3)/6
are possible radii.
[ Radius of mutually touching circles ]
The circles are touching when the distance of their centers = 2*Radius.
The situation is easily analyzed by looking at Center2 and Center3:
Center3.x - Center2.x = 2*touch_Radius [y-coordinates are equal!]
The coordinates of these centers are known:
Side-sqrt(3)*touch_Radius - sqrt(3)*touch_Radius = 2*touch_Radius
A little calculation solves this for touch_Radius:
Side = (2*sqrt(3)-2) * touch_Radius
touch_Radius = Side / (2*sqrt(3)-2) [now expand by (2*sqrt(3)+2):]
= Side * (sqrt(3)-1)/4
[ center of triangle ]
This point isn't needed for the problem, but I suggest to calculate
almost everything you can: it often gives deeper insight in the
problem, reveals unexpected relations and simplifies other steps.
In the trefoil problem, it helps finding the "true gothic" Radius.
Again because of symmetry,
Center.x = Side/2
The bisectors of a triangle (which in this case also are angular
bisectors and heights) intersect in its center of gravity and
are divided by this point in a 2:1 ratio. This gives us
Center.y = Height/3
[ "true gothic" Radius ]
In a "true gothic" situation, all circles meet at the Center, so
their distance from this Center = Radius. In this case, the situation
at the top is most easy:
gothic_Center1.y - Center.y = gothic_Radius [x-coordinates are equal!]
Because
Center1.y = Height-2*Radius
we have the special case
gothic_Center1.y = Height-2*gothic_Radius = sqrt(3)/2*Side-2*gothic_Radius
We already found in the previous section
Center.y = Height/3 = sqrt(3)/6*Side
Putting all this together and solving for gothic_Radius, we find
sqrt(3)/2*Side-2*gothic_Radius - sqrt(3)/6*Side = gothic_Radius
sqrt(3)/3*Side = 3*gothic_Radius
gothic_Radius = sqrt(3)/9*Side
6. During the paragraph 5 implement everything at once in POV-Ray
This will reveal calculation errors and gives an exact drawing of the
situation reached so far. And it's fun!
.....
I don't know your mathematical background, so maybe this was a little bit
lengthy, but I hope this explanation will contribute to your ability to
successfully attack similar (and more complex) problems.
Sputnik
--
----------------------------
Frank 'Sputnik' Rothfuß
fr### [at] computermuseum fh-kiel de
----------------------------
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
INVALID_ADDRESS wrote:
>I don't know your mathematical background, so maybe this was a little bit
>lengthy, but I hope this explanation will contribute to your ability to
>successfully attack similar (and more complex) problems.
>
> Sputnik
>
>
>--
>----------------------------
>Frank 'Sputnik' Rothfuß
>fr### [at] computermuseum fh-kiel de
>----------------------------
>
I am absolutely amazed but grateful that you took so much time out from your
own coding to write such an extensive reply! I haven't had a chance to
look through it yet, but I wanted to make sure I thanked you before I got
distracted! Thanks SO much!
Yet another example of why this group is so great!
--Mark
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
INVALID_ADDRESS wrote:
>Now look at the midpoint 'Center2' of a circle touching the sides
>emanating from Corner2. Due to symmetry of this circle and the triangle
>with respect to the line through Corner2 and Center2, the angle between
>this line and the x-axis is 30 degrees (60/2). Now imagine a new point:
>the mirror image 'M' of Center1 with respect to the x-axis. The triangle
> Corner2 -- Center1 -- M
>has 30+30 degrees at Corner1 (x-axis symmetry),
I was following just fine until this point (no pun intended).
On *my* diagram, Center1 corresponds to Corner1, Center2 to Corner2, etc.
I wondered if perhaps you meant to say that the point 'M' was the mirror
image of Center2, rather than Center1. If I make point 'M' a mirror image
(with respect to the x-axis) of Center1, I end up with an isosceles
triangle whose longest side is the vertical line Center1 -- M . This
leaves me with point 'M' having a y-value which is the negative of
Center1.y, and the angle at Corner2 is 120°
The only way I can come up with the equilateral triangle you reference is by
substituting one vertex so that the vertices of the triangle are now
Corner2 -- Center2 -- M.
(Please forgive crude "drawing"):
| <-- y-axis
| (.) Corner1
|
| (.) Center1
|
| (.)Center2
|
..Corner2______________ (x-axis)
|
|
| (.) 'M'
|
|
|
Maybe I'm being dense in the head?....
Thanks,
mark
Post a reply to this message
|
 |
|  |
|  |
|
 |
From:
Subject: Re: Fitting a gothic trefoil into an equilateral triangle
Date: 25 Jun 2003 17:47:56
Message: <3efa188c@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Hi Mark,
obviously *I* am dense and you found my 3 errors. The section about
the centers should begin as follows:
[ centers ]
Now look at the midpoint 'Center2' of a circle touching the sides
emanating from Corner2. Due to symmetry of this circle and the triangle
with respect to the line through Corner2 and Center2, the angle between
this line and the x-axis is 30 degrees (60/2). Now imagine a new point:
the mirror image 'M' of Center2 with respect to the x-axis. The triangle
Corner2 -- Center2 -- M
has 30+30 degrees at Corner2 (x-axis symmetry), its other two angles are
<continues as before>
Sorry for creating this confusion.
> If I make point 'M' a mirror image
> (with respect to the x-axis) of Center1, I end up with an isosceles
> triangle whose longest side is the vertical line Center1 -- M . This
> leaves me with point 'M' having a y-value which is the negative of
> Center1.y, and the angle at Corner2 is 120°
If this "angle at Corner2" is meant to be
angle ( Center1, Corner2, x-axis mirror image of Center1 )
then "120°" is wrong: let
M1 = x-axis mirror image of Center1
Because Center1 is inside the triangle Corner1 -- Corner2 -- Corner3,
angle ( Center1, Corner2, x-axis)
< angle ( Corner1, Corner2, x-axis)
= 60°
Now
"angle at Corner2"
= 2 * angle ( Center1, Corner2, x-axis) [x-axis symmetry]
< 2*60° = 120°
So the "angle at Corner2" < 120°; equal only when Radius=0; in this
case the "longest" side has the same length as the other sides!
Is the rest of my previous post understandable (with the above
corrections)?
Sputnik
P.S.
Why "INVALID_ADDRESS" at the beginning of your last post?
--
----------------------------
Frank 'Sputnik' Rothfuß
fr### [at] computermuseum fh-kiel de
----------------------------
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: LinuxLibrarian
Subject: Re: Fitting a gothic trefoil into an equilateral triangle
Date: 25 Jun 2003 20:43:23
Message: <3efa41ab@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Frank 'Sputnik' Rothfuß wrote:
> Hi Mark,
>
> obviously *I* am dense and you found my 3 errors. The section about
> the centers should begin as follows:
>
> [ centers ]
> Now look at the midpoint 'Center2' of a circle touching the sides
> emanating from Corner2. Due to symmetry of this circle and the triangle
> with respect to the line through Corner2 and Center2, the angle between
> this line and the x-axis is 30 degrees (60/2). Now imagine a new point:
> the mirror image 'M' of Center2 with respect to the x-axis. The triangle
> Corner2 -- Center2 -- M
> has 30+30 degrees at Corner2 (x-axis symmetry), its other two angles are
> <continues as before>
>
> Sorry for creating this confusion.
>
>
>
>>If I make point 'M' a mirror image
>>(with respect to the x-axis) of Center1, I end up with an isosceles
>>triangle whose longest side is the vertical line Center1 -- M . This
>>leaves me with point 'M' having a y-value which is the negative of
>>Center1.y, and the angle at Corner2 is 120°
>
>
> If this "angle at Corner2" is meant to be
> angle ( Center1, Corner2, x-axis mirror image of Center1 )
> then "120°" is wrong: let
> M1 = x-axis mirror image of Center1
> Because Center1 is inside the triangle Corner1 -- Corner2 -- Corner3,
> angle ( Center1, Corner2, x-axis)
> < angle ( Corner1, Corner2, x-axis)
> = 60°
> Now
> "angle at Corner2"
> = 2 * angle ( Center1, Corner2, x-axis) [x-axis symmetry]
> < 2*60° = 120°
> So the "angle at Corner2" < 120°; equal only when Radius=0; in this
> case the "longest" side has the same length as the other sides!
>
>
> Is the rest of my previous post understandable (with the above
> corrections)?
>
> Sputnik
>
>
> P.S.
> Why "INVALID_ADDRESS" at the beginning of your last post?
>
I don't know, it's how *your* address appears in the postings on the
web-based interface to news.povray.org (see for yourself at
http://news.povray.org -- maybe you never read the newsgroups that way,
so you didn't realize your address was being (or rather, not) displayed
that way.
BTW, I also wondered about how you solved for the height. I quote:
"The y-coordinate is the Height of the triangle, found by the law of
pythagoras in the right-angled triangle
top point -- bottom left point -- midpoint of base line
so we get
Height^2 + (Side/2)^2 = Side^2
Solving for Height gives
Height = sqrt( Side^2 + Side^2/4 ) = sqrt(3)/2*Side"
Shouldn't the last line read:
Height = sqrt( Side^2 - (Side/2)^2) ?
Or is that really the same thing? I'm a little fuzzy on my exponents
where fractions & diving are concerned.
But for the rest of it, I'm going off line now to study your
"revised edition." ;-) THanks for all your indulgence! Sorry to be
such a persnickety pain-in-the-ass!
--Mark
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Hi Mark,
(Side/2)^2 = Side^2/4
The rule applied here is
(A/B) ^ C = (A^C) / (B^C)
You can see this by replacing exponentiation by repeated multiplication,
for example with C=5: (use an non-proportional font to read this)
(A/B)^5
A A A A A
= - * - * - * - * -
B B B B B
A*A*A*A*A
= ---------
B*B*B*B*B
A^5
= ---
B^5
= (A^5) / (B^5)
= A^5/B^5
The last equation is true because "^" has higher priority than "/" (and
"*"). (This is a convention to save some parantheses, not a mathematical
necessity!)
In the trefoil Height formula,
(Side/2)^2 = Side^2 / 2^2 = Side^2 / 4
so the Height is calculated as follows:
[law of pythagoras]
Height^2 + (Side/2)^2 = Side^2
[subtract (Side/2)^2 on both sides of equation]
Height^2 = Side^2 - (Side/2)^2
[power (here: sqare) of quotient as above]
Height^2 = Side^2 - Side^2 / 4
["*1 doesn't change anything; "/ 4" = "* 1/4"]
Height^2 = Side^2 * 1 - Side^2 * 1/4
[Side^2 is common factor]
Height^2 = Side^2 * (1-1/4) = Side^2 * 3/4
[square root on both sides of equation; sqrt(A*B) = sqrt(A)*sqrt(B)]
sqrt(Height^2) = sqrt( Side^2 * 3/4 ) = sqrt(Side^2) * sqrt(3) / sqrt(4)
[sqrt(A^2) = A (when A>=0)]
Height = Side * sqrt(3)/2
Probably you have noticed that at some places in my explanation post I have
removed square roots from the denominator, because generally root-less
denominators are (aesthetically) preferred. The following examples show
how this can be done. Of course this is not required for POV-Ray's
calculations, I've done it only for humans :)
A, B, ... are arbitrary expressions; if the denominator contains more than
one root, these methods will have to be repeatedly applied.
[case 1: nothing added to the root]
A A * sqrt(C) A * sqrt(C) A
--------- = ------------------- = ----------- = --- * sqrt(C)
B*sqrt(C) B*sqrt(C) * sqrt(C) B*C B*C
[case 2: denominator is a sum]
A A * (B*sqrt(C)-D)
------------- = -----------------------------
B*sqrt(C) + D (B*sqrt(C)+D) * (B*sqrt(C)-D)
[in denominator: (X+Y)*(X-Y) = X*X-X*Y+Y*X-Y*Y = X^2 - Y^2]
A*B*sqrt(C) - A*D A*B*sqrt(C) - A*D
= ------------------- = -----------------
(B*sqrt(C))^2 - D^2 B^2*C - D^2
How far can you proceed now in understanding the trefoil calculations?
Sputnik
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
INVALID_ADDRESS wrote:
> Of course this is not required for POV-Ray's
>calculations, I've done it only for humans :)
Or in my case, chimpanzees... But maybe that's being insulting to the
supposedly lower primates...
Thanks, I follow you now!
I bet you didn't realize you'd end up as an online math tutor...
Again, your patience is verging on the superhuman!
Many thanks again!
--Mark
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: Mark M Wilson
Subject: Re: Fitting a gothic trefoil into an equilateral triangle
Date: 29 Jun 2003 22:35:47
Message: <3effa203@news.povray.org>
|
|
 |
|  |
|  |
|
 |
I made a couple of modifications to your original, now that I have some
understanding of what was going on. Basically, I moved the definition
of 'R' to after Radius, and made R=0.10*Radius
I also removed the part in the middle where the tori overlap.
// macro for trefoil ====================================================
#macro Trefoil (Side, Radius) // lower left corner at origin
#local Height = sqrt(3)/2*Side;
#local Corner1 = <Side/2, Height, 0>; // top corner
#local Corner2 = 0; // bottom left corner
#local Corner3 = Side*x; // bottom right corner
#local Center = <Side/2,
Height/3, 0>; // triangle
#local Center1 = <Side/2, Height-2*Radius, 0>; // top circle
#local Center2 = <sqrt(3)*Radius, Radius, 0>; // bottom left circle
#local Center3 = <Side-sqrt(3)*Radius, Radius, 0>; // bottom right
circle
#local R = Radius*0.1; //
union {
/*union {
sphere { Corner1, R }
sphere { Corner2, R }
sphere { Corner3, R }
cylinder { Corner1, Corner2, R }
cylinder { Corner2, Corner3, R }
cylinder { Corner3, Corner1, R }
texture { pigment { color green
1 } finish { ambient 1 } }
}*/
difference {
union {
torus { Radius, R rotate 90*x translate Center1
clipped_by {
plane { <0, -1, 0> 0 rotate -z*30 translate <(Side/2),
Center1.y-(Radius), 0> }
}
clipped_by {
plane { <0, -1, 0> 0 rotate z*30 translate <(Side/2),
Center1.y-(Radius), 0> }
}
}
torus { Radius, R rotate 90*x translate Center2
clipped_by {
plane { <0, 1, 0>, 0 rotate -z*30 translate <(Side/2),
(Center1.y-(Radius)), 0>
}}
clipped_by {
plane { <1, 0, 0>, 0 translate <Side/2, (Center1.y-(Radius)), 0> }
}}
torus { Radius, R rotate 90*x translate Center3
clipped_by {
plane { <-1, 0, 0>, 0 translate <Side/2, (Center1.y-Radius), 0> }
}
clipped_by {
plane { <0, 1, 0> 0 rotate z*30 translate <(Side/2),
(Center1.y-Radius), 0>}
}
}
texture { pigment { color red 1 } finish { ambient 1 } }
}
sphere { <Side/2, (Center1.y-Radius), 0> 2*R }
}
// "}" omitted to allow application of transformations
#end//macro Trefoil
// simple scene with trefoils ===========================================
//Trefoil ( 1 , 1*(sqrt(3)-1)/4 ) translate <-1.6, 0.2 , 1> } // small
Trefoil ( 0.46 , 0.46*sqrt(3)/9 ) translate <-0.5 , 0 , 1> } //
gothic
//Trefoil ( 1 , 1*sqrt(3)/6 ) translate < 0.6, 0.2 , 1> } // large
light_source { <-1500, 2500, -1000>, color rgb 1 }
camera { //orthographic
up y right 1.3*x
location <-0.23, 0.2, -0.09>
look_at <-0.23, 0.2, 0>
}
// END ==================================================================
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Hi Mark,
my little scene was meant as an illustration of a geometric problem -- nice
to see it evolve into something really useable. I suggest to supply the
"linewidth" as an additional parameter instead of a constant fraction of
Radius. If you decide to change this value, it's much easier to have POV-
Ray doing all the calculations instead of "re-inventing the wheel again and
again by hand-calculation". And you can't animate the "linewidth" when
this relationship is fixed. The calculations have to be done anyway,
there is almost no difference between using "0.1*Radius" and "Linewidth",
so give this parameter to POV-Ray and let it do the boring numerical work.
Having a "linewidth factor" parameter also would be possible; the actual
value for this parameter would be 0.1 to reproduce what you've done, but
can easily be changed at will.
Because the thin circles have become rings with some linewidth now, there
arises a new problem: What is a "true gothic" constellation?
Of course the outer border/circle of the rings must touch the triangle.
But how large should these rings be?
1. The outer circles intersect at the triangle's midpoint
This is the easiest case: outer circle is as before; some linewidth
is added towards the circle's centers.
2. The inner circles intersect at the triangle's midpoint
I don't think this is looking good with a large linewidth, so
the calculation isn't worth it.
3. The "mid-circles" with radius=(inner_radius+outer_radius)/2 intersect
at the triangle's midpoint.
I suppose this will look "most gothic", but will require some
calculation ... (maybe I'll do this).
You should also try to remove the inner parts of the rings by difference-ing
with a cylinder around Center, having a radius = Radius.
Next tasks :)
- replace the torii by cylindrical rings (difference of a cylinder and a
thinner, but slightly longer [to avois coincident surfaces] cylinder,
the Thickness being a new parameter). You have to do a little calculation
involving Linewidth (or LinewidthFactor or whatever), but then changing
this Linewidth is no pain: no new hand-calculation is neccessary, POV-Ray
does it all. I suggest to write a macro Ring ( Radius, Linewidth ) that
"behaves" similar to torus { Minor, Major ... }, this makes it easy to
change all torus{} objects to Ring objects. The trick of omitting the
closing "}" of the object created by Ring will help (look at the end
of the Trefoil macro where I used this trick).
- create your *own* stone texture
- arrange some trefoils, light source(s) and a camera to create a pleasing
scene; perhaps add some bricks, columns, decorative elements, windows,
floor tiles, stone carvings, stairs, roof tiles, ...
- at least *try* to find a solution for "true gothic" case 3.
Sputnik
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
INVALID_ADDRESS wrote:
>Of course the outer border/circle of the rings must touch the triangle.
>But how large should these rings be?
> 1. The outer circles intersect at the triangle's midpoint
> This is the easiest case: outer circle is as before; some linewidth
> is added towards the circle's centers.
> 2. The inner circles intersect at the triangle's midpoint
> I don't think this is looking good with a large linewidth, so
> the calculation isn't worth it.
> 3. The "mid-circles" with radius=(inner_radius+outer_radius)/2 intersect
> at the triangle's midpoint.
> I suppose this will look "most gothic", but will require some
> calculation ... (maybe I'll do this).
Yes, realistically the stone trifoil tracery would not be merely tangent to
a circle which frames it, but would look like it was being "blobbed" into
it. (Else, how could it the tracery be physically held in place?)
For instance, the hexafoils framing the stained glass in the upper part of
this image from Bourges Cathedral:
http://www.bc.edu/bc_org/avp/cas/fnart/arch/gothic/bourges/bourges_int09.jpg
>
>You should also try to remove the inner parts of the rings by difference-ing
>with a cylinder around Center, having a radius = Radius.
I didn't know if it really mattered exactly what sort of primitive was being
used to difference out the parts of the rings. Would there be a benefit in
terms of tracing/parsing time?
>Next tasks :)
> - replace the torii by cylindrical rings (difference of a cylinder and a
> thinner, but slightly longer [to avois coincident surfaces] cylinder,
> the Thickness being a new parameter). You have to do a little calculation
> involving Linewidth (or LinewidthFactor or whatever), but then changing
> this Linewidth is no pain: no new hand-calculation is neccessary, POV-Ray
> does it all. I suggest to write a macro Ring ( Radius, Linewidth ) that
> "behaves" similar to torus { Minor, Major ... }, this makes it easy to
> change all torus{} objects to Ring objects. The trick of omitting the
> closing "}" of the object created by Ring will help (look at the end
> of the Trefoil macro where I used this trick).
I thought of this, but the edges looked a little too squared off for what I
remember being authentic (and I've been poring over A LOT of books &
websites about cathedrals & Gothic style).
> - create your *own* stone texture
jaw drops, mouth goes dry, limbs gradually go numb... ;-)
> - arrange some trefoils, light source(s) and a camera to create a pleasing
> scene; perhaps add some bricks, columns, decorative elements, windows,
> floor tiles, stone carvings, stairs, roof tiles, ...
> - at least *try* to find a solution for "true gothic" case 3.
>
The 2nd of these last two tasks seems to be the easier!
I have thus far a floor, columns & footings, empty windows waiting for
inspired "glass" (maybe just borrowed images converted to a format that
will allow me to play with the transparency/translucency). I also have the
nave ceiling ribbing and vaulting, piers at the 'crossing', a west wall &
portal. All of these are still quite primitive looking, but they're the
most my skills (and limited time to work ) allow.
I went thorough a lot of trouble to get the vault ribbing to look like it
was composed of individual component pieces (again, as in the image cited
above).
I'd post it on the images group as a WIP, but I'm still too embarrassed at
how little progress I've made, when I think of how long I've actually been
at it.
But then again, I really didn't spend a lot of time on spheres & checkered
planes before I dove in over my head. Boring!
Thanks again for all your input!
--Mark
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
INVALID_ADDRESS wrote:
>
>Next tasks :)
The trick of omitting the closing "}" of the object created by Ring will
help (look at the end of the Trefoil macro where I used this trick).
>
Yes, that closing "}" really confused me. I didn't really understand why it
was necessary, especially when I couldn't find the opening "{".
(Did it have anything to do with your commented-out statement about the
closing "}" being omitted for to allow for translations? )
I'd never before noticed any other examples of macro calling with {}'s.
()'s, yes!
I suppose I'd better go study macros some more. (But then, that's part of
my problem about slow progress: Every scene component I attempt to add
involves an episode of "that doesn't do AT ALL what I wanted/expected," and
I have to reverse myself and do so much doc-reading (which introduces me to
yet more confusing concepts, spawning yet more tangents..)
--Mark
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Hi Mark,
I suggested to clip with a "center cylinder" to get rid of the sharp "inner
spikes", just for aesthetical reasons.
> > - create your *own* stone texture
>
> jaw drops, mouth goes dry, limbs gradually go numb... ;-)
Why this?
Experiment with some stone textures from stones1.inc and stones2.inc, modify
the colors in the color_map (and convert the color_maps to the new syntax!)
use other wave_types, play around with different patterns, scaling (even and
uneven) and rotation, modify the modifiers. Then finish, normal, layered
textures, ...
A perfect stone texture is difficult, but an acceptable stone texture isn't.
> I went thorough a lot of trouble to get the vault ribbing to look like it
> was composed of individual component pieces
Why "look like"? You could use truly individual components! (Don't forget
the mortar between them!)
Now I reveal: The trick of the missing "}"
Assume you want a macro for a simple ring:
#macro Ring(Size)
difference {
cylinder { -0.05*y, 0.05*y, 0.5 }
cylinder { -0.051*y, 0.051*y, 0.4 }
scale Size
}
#end//of macro Ring
Now you can use this macro to create a ring at the origin with the default
texture:
Ring(3)
This is equivalent to the body of the macro with parameter names replaced
by the supplied value, i.e. this represents a complete difference statement.
But if you want to apply a texture, translate it or such, you have to write
object { Ring(3) texture { MyRingTex } translate <1, 2, 3> }
I prefer to leave out the line with the single "}" in the macro. (It is
legal to have unmatched parentheses in a macro.) Now Ring(3) delivers
difference {
cylinder { -0.1*y, 0.1*y, 0.5 }
cylinder { -0.11*y, 0.11*y, 0.4 }
scale 3
and you can append whatever is possible with a difference. At the end the
matching "}" for the "difference {" must be supplied. So for example
Ring(3) texture { MyRingTex } translate <1, 2, 3> }
is the same as
difference {
cylinder { -0.1*y, 0.1*y, 0.5 }
cylinder { -0.11*y, 0.11*y, 0.4 }
scale 3
texture { MyRingTex } translate <1, 2, 3> }
In short: the "}" is not supplied in the macro, but in the SDL after the
invocation of the macro.
Don't worry about slow progress: this only means your work is improving
your POV-Ray expertise instead of your scene -- you should be happy
about this!
Sputnik
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: LinuxLibrarian
Subject: Re: Fitting a gothic trefoil into an equilateral triangle
Date: 6 Jul 2003 18:55:08
Message: <3F08A8D9.4090905@att.net>
|
|
 |
|  |
|  |
|
 |
Frank 'Sputnik' Rothfuß wrote:
> Don't worry about slow progress: this only means your work is improving
> your POV-Ray expertise instead of your scene -- you should be happy
> about this!
>
> Sputnik
>
>
I look at things like
http://www.irtc.org/ftp/pub/stills/2003-04-30/mtdomine.jpg
and I just think "never mind, forget it..."
--Mark
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
/*
Hi Mark,
did you recognize that the picture of your link has only a small number
of *different* elements? The rest is repetition: a task for POV-Ray's
#while-statement.
> I have thus far a floor, columns & footings, empty windows waiting for
> inspired "glass" (maybe just borrowed images converted to a format that
> will allow me to play with the transparency/translucency). I also have the
> nave ceiling ribbing and vaulting, piers at the 'crossing', a west wall &
> portal.
Fine -- repeat them, put them together, apply your stone texture, post in
p.b.i, improve after you've read the comments and suggestions, then post
again, ...
If you can't create a complete building, make a ruin! :-))
Here is some inspiration for you: "The power of repetition"
The scene consists almost entirely of repetitions of one simple box!
Sputnik
*/
//=== BEGIN ==============================================================
// +SP8 +EP8 -A +W800 +H600 -FN
// +SP8 +EP8 +A0.001 +AM2 +R3 +W800 +H600 -FN
#declare oClock = 360/12; // for direction as ... o'clock
#declare PicHeight = 21;
#declare PicWidth = 4/3*PicHeight;
#declare PicDist = 1.5*PicWidth;
#declare Focus = 0;
#declare FocusDist = 2000;
#declare CamDirection = 5*oClock; // horizontal position of cam,
// looking in opposite direction
#declare CamHeight = 33; // degrees
#declare CamRollLeft = 0; // degrees
camera {
location -FocusDist*z
right PicWidth/2*x
up PicHeight/2*y
sky y
direction PicDist/2*z
look_at 0
rotate CamRollLeft*z
rotate <CamHeight, CamDirection-180, 0>
translate Focus
}
light_source { <-1, 4, -2>*10000, rgb 1 }
#declare VerySimpleStoneTex = texture {
pigment { granite scale 3 }
finish { ambient .3 diffuse .7 }
}
#declare StairWidth = 300;
#declare StairHeight = 15;
#declare StairDepth = 20;
#declare StairOverlap = 10;
#macro Stair ()
box { 0, <StairDepth+StairOverlap, StairHeight, StairWidth>
// no "}" for "box {" as usual ...
#end//macro Stair
#macro Stairs (Steps)
union {
#declare Step = 0;
#while (Step<Steps)
Stair () translate Step*<StairDepth, StairHeight, 0> }
#declare Step = Step+1;
#end//while Step
texture { VerySimpleStoneTex }
// "}" for "union {" omitted
#end//macro Stairs
Stairs (25) rotate -80*y translate <450, 0, -400> }
#declare S = 8;
union {
Stairs (S) }
union {
box { 0, <StairWidth, StairHeight, StairWidth>
texture { VerySimpleStoneTex }
}
Stairs (4)
rotate 90*y
translate <0, StairHeight, StairOverlap>
}
Stairs (6)
translate -StairWidth*z
rotate -90*y
translate <0, StairHeight, StairWidth-StairOverlap>
}
translate S*<StairDepth, StairHeight, 0>
}
rotate -130*y
translate <-150, 0, 100>
}
#declare S = 5;
union {
Stairs (S-1) }
Stairs (S)
scale <-1, 1, 1>
translate ((2*S-1)*StairDepth+StairOverlap)*x
}
rotate -60*y
translate <-50, 0, -600>
}
plane { y, 0
texture { checker
texture { VerySimpleStoneTex scale 1/50 },
texture { pigment { color rgb .8 } finish { ambient .3 diffuse .7 } }
scale 50
}
}
//=== END ================================================================
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
INVALID_ADDRESS wrote:
>
>#macro Stairs (Steps)
> union {
> #declare Step = 0;
> #while (Step<Steps)
> Stair () translate Step*<StairDepth, StairHeight, 0> }
> #declare Step = Step+1;
> #end//while Step
> texture { VerySimpleStoneTex }
> // "}" for "union {" omitted
> #end//macro Stairs
>
(This thread is probably now so old you're ignoring it and may not get this,
unless you sort your news by date or something)
Here's yet another boneheaded question:
In the above macro, the variable "Step" is declared, and given a integer or
float value. I don't understand at what point it could ever change its
value to "Steps," which is a string. Just to be sure, I parsed through the
message looking for buried occurrences of "Steps," in case I missed where
you may have put something like
#declare Steps = Some number greater than 0
Excuse my cranial density...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Hi Mark!
(This thread isn't old: my last post is only 10 days ago! For me "old"
means "months ago" if it's a thread I've started or replied to.)
Steps is neither a string nor a "normal" variable: it is a macro parameter.
When POV-Ray sees, for example,
Stairs (4) /* some transformations */ }
then Stairs is recognized as the name of a macro because it was defined by
#macro Stairs (Steps)
// rest of macro skipped here
This tells POV-Ray to create a new variable named Steps which is local
to the macro (i.e. destroyed at exit of the macro) and to store the
parameter value (in this example 4) in it. The effect is the same as
if the line
#local Steps = 4;
were executed at entry into the macro. Now the loop
#declare Step = 0;
#while (Step<Steps)
Stair () translate Step*<StairDepth, StairHeight, 0> }
#declare Step = Step+1;
#end//while Step
starts with Step=0, which is <Steps (=4 here), so makes a Stair,
increments Step to 1, this is <Steps, so makes another Stair,
increments Step to 2, this is <Steps, so makes another Stair,
increments Step to 3, this is <Steps, so makes another Stair,
increments Step to 4, this is not <Steps, so exits.
At the next invocation of Stairs the old value of Steps is forgotten;
a new Steps variable is created containing the new parameter value.
More generally, a macro defined by, for example,
#macro MyMacro (A_Number, A_String, An_Object)
// ...
#end
and invoked by
MyMacro ( 42, "Whoa!", sphere { <1,2,3>, 4 } )
will create new variables
A_Number with value 42
A_String with value "Whoa!"
An_Object with value sphere { <1,2,3>, 4 }
as if
#local A_Number = 42;
#local A_String = "Whoa!"
#local An_Object= sphere { <1,2,3>, 4 }
were executed, then the macro body (everything between
"#macro MyMacro (A_Number, A_String, An_Object)" and the "#end" that
belongs to #macro, indicated by "// ..." above) will be parsed by POV-Ray,
then the local variables A_Number, A_String, An_Object are destroyed, and
parsing continues after the invocation. A macro without parameters is
sort of "copy and paste" operation (like my Stair()-macro which simply
delivers a box). Parameters allow introduction of varying elements
(everything that is allowed on the right side of the "=" of a #local
statement is allowed as parameter).
<ADVANCED STUFF>
The macro body may even modify the parameters, and when a macro invocation
gives a single declared (or "#local"ed) variable (not an expression) as
parameter value, then this variable gets the value of its associated local
parameter variable at exit of the macro. If for example the above macro is
invoked as
MyMacro (MyNumber, MyString, MyObject)
then the variables MyNumber, MyString, MyObject reflect the values of
A_Number, A_String, An_Object just before exit of the macro as if
#declare MyNumber = A_Number;
#declare MyString = A_String
#declare MyObject = An_Object
were executed just before exit of the macro.
A simple example:
#macro Add (Value, Sum)
#local Sum = Sum+Value;
#end
#declare Result = 0; // start with 0 as current value of Result
Add (5, Result) // add 5 to the current value of Result, giving 5
Add (7, Result) // add 7 to the current value of Result, giving 12
Add (3, Result) // add 3 to the current value of Result, giving 15
#debug str(Result, 5, 0) // output Result to message window
#debug "\n" // start a new line in message window
The invocation "Add (5, Result)" is replaced by POV-Ray by
#local Value = 5; // get first parameter, store it in local variable
#local Sum = Result; // get second parameter, store it in local variable
#local Sum = Sum+Value; // body of macro, uses the local variables
// associated to the parameters
#declare Result = Sum; // return the value of the second parameter's
// local variable to the variable given for
// this second parameter
// The first parameter "5" is not a variable, so nothing is returned
// ( "#declare 5 = Value;" is nonsense )
#undef Value // the local variable Value is destroyed
#undef Sum // the local variable Sum is destroyed
In short: 5 is used for Value, Result is used for Sum. 5 can't get a new
value, but Result can.
Similar with the other invocations.
Of course,
#declare A_different_Result = 1762345;
Add (76235, A_different_Result)
Add (87656, A_different_Result)
also is possible, even intermixed with the above invocations of Add,
because Add is "told" which variable to use.
<END OF ADVANCED STUFF>
I hope this helps in understanding my macros (and macros in general).
You might want to read "6.2.8 User Defined Macros" for more information
(or ask again!).
Sputnik
P.S. Why did you think Steps is a string?
P.P.S. You meant "Steps" , not "Steps," , didn't you?
P.P.P.S. String comparison is not possible with "<" etc., look for
strcmp in "6.1.3.6 Float Functions".
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
INVALID_ADDRESS wrote:
>
>P.S. Why did you think Steps is a string?\
I guess I thought all variable identifiers *had* to be strings.
>
>P.P.S. You meant "Steps" , not "Steps," , didn't you?
Probably. I no longer remember what I wrote!
I understand the logic of all you explained -- it helped me to re-examine
your code. THEN,
I finally realized, as the cranial density began to lessen, that "Steps"
didn't *have* to have a value pre-assigned to it *until the macro was
actually called*.
As I looked farther down your code, I saw:
Stairs (S) (after S was declared to = 8)
then
Stairs (4), then
Stairs (8)
At that point the fog { } began to lift. :-) THanks!
--Mark
P. S. You're a very patient person. Are you a teacher, by any chance?
Perhaps you should be!
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Are you a teacher, by any chance?
Formally: No. In practice: Yes, sometimes.
I'm working for a computer museum (actually only a collection);
currently only sort of hobby, presenting old computers and explaining
the principles of their operation. A glimpse at a small fraction of
this collection (text currently only in german):
http://www.computermuseum.fh-kiel.de/images/medium_zuse_rundblick.jpg
http://www.computermuseum.fh-kiel.de/besichtigungen/info.htm
> Perhaps you should be!
I am! Look at "Fitting a gothic trefoil into an equilateral triangle"
in povray.general! :-D
Sputnik
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: David Wallace
Subject: Re: Fitting a gothic trefoil into an equilateral triangle
Date: 2 Aug 2003 08:53:47
Message: <3f2bb45b@news.povray.org>
|
|
 |
|  |
|  |
|
 |
"Frank 'Sputnik' Rothfuß" <fr### [at] computermuseum fh-kiel de> wrote in message
news:3ef793d2$1@news.povray.org...
> Hi Mark,
>
> here is "The Making of '#macro Trefoil'"; names starting with an
> uppercase letter refer to variables in the code of my last post.
>
> (don't underestimate the importance of the first two of the following
> points!)
>
>
> 1. Find out the given and wanted elements (lengths, angles, ...)
> and choose descriptive names for them
>
> You asked for inscribing circles into an equilateral triangle, so all
> of its angles are 60 degrees. The length of its sides is given; this
> length got the name 'Side'. Obviously the triangle is to be erected
> over a horizontal line, so it has a top corner ('Corner1'), a bottom
> left corner ('Corner2') and a bottom right corner ('Corner3').
> Because the problem has an infinite number of solutions, I decided
> to use the radius 'Radius' of the circles as independent variable
> and to calculate their midpoints 'Center1', ... , 'Center3'.
>
>
> 2. Choose a coordinate system
>
> Usually the math is easier when many coordinates are 0 or 1: multiplying
> by 1 is trivial, by 0 even more; adding of 0 is trivial; squaring 0 or 1
> is the same as doing nothing; and so on.
> If there is a mirror symmetry with respect to a line/point, then very
often
> (but not always) this line/point is well suited as coordinate axis/origin.
> Sometimes it is easier to solve a standard problem and then transform
> it to the required proportions; for example (in POV style): instead
> of sphere{C,R ... } use sphere{0,1 ... scale R translate C}.
>
> The trefoil is a problem in plane geometry, so I only use x- and y-
> coordinates and set all z=0 (I will leave them out here, but had written
> these zeros in the code).
> Because circles are to be put into the *corners* of the outer triangle,
> I decided to use a corner (Corner2) as origin, so
> Corner2=<0,0>
> Corner3 sits on the x-axis, so
> Corner3=<Side,0>.
>
>
> 3. Make a drawing of the geometric situation
>
> In most cases, an approximate scetch without large obvious errors will
> suffice. Use thick lines for every known element. Don't believe everything
> you see! The drawing can't prove anything, its sole purpose is to trigger
> the intuition and to keep track of the known and the not-yet-known
> elements. Do this even for very simple situations.
> (Please do this *now* to make it easy to follow the following
explanations!)
>
>
> 4. Look for properties that allow application of geometric theorems
>
> Very often symmetries, right angles, congruent triangles and parallels
> are the key for a solution. If you have none, create them by erecting
> perpendiculars, drawing parallels etc.
> This is the inspiration part of the solution of geometric problems.
>
>
> 5. Find out relevant elements (coordinates, lengths, angles, ...) until
all
> wanted elements are known
>
> This is the transpiration part of the solution of geometric problems.
>
> [ top corner ]
> The first step in the trefoil problem is to find the top corner. Due to
> the triangle's mirror symmetry with respect to the perpendicular from
> the top corner,
> Corner1.x=Side/2.
> The y-coordinate is the Height of the triangle, found by the law of
> pythagoras in the right-angled triangle
> top point -- bottom left point -- midpoint of base line
> so we get
> Height^2 + (Side/2)^2 = Side^2
> Solving for Height gives
> Height = sqrt( Side^2 + Side^2/4 ) = sqrt(3)/2*Side
>
> [ centers ]
> Now look at the midpoint 'Center2' of a circle touching the sides
> emanating from Corner2. Due to symmetry of this circle and the triangle
> with respect to the line through Corner2 and Center2, the angle between
> this line and the x-axis is 30 degrees (60/2). Now imagine a new point:
> the mirror image 'M' of Center1 with respect to the x-axis. The triangle
> Corner2 -- Center1 -- M
> has 30+30 degrees at Corner1 (x-axis symmetry), its other two angles are
> equal (same symmetry). So all angles are 60 degrees, i.e. this triangle
> is equilateral. The vertical side obviously has a length=2*Radius, and
> because of the equilaterality, the other sides have the same length. The
> part of the x-axis within this triangle is a height of this triangle, and
> as seen above with the outer triangle, height=sqrt(3)/2*length_of_side.
> But this height of the small triangle is the x-coordinate of Center2!
> So we have
> Center2.x = sqrt(3)/2 * 2*Radius = sqrt(3)*Radius
> and obviously
> Center2.y = Radius
> By symmetry with respect to the perpendicular from the top corner onto
> the x-axis:
> Center3.x = Side - sqrt(3)*Radius
> Center3.y = Radius
> As seen above,
> distance between Center2 and Corner2
> = length_of_side of the small triangle
> = 2*Radius
> Because the three circles are equal,
> distance between Center1 and Corner1 = 2*Radius
> I.e. Center1 is 2*Radius below Corner1, so we get
> Center1 = <Side/2, Height-2*Radius>
>
> [ maximal Radius, minimal Radius ]
> Because all triangles should lie completely inside the outer triangle,
> the maximal Radius is the radius of the incircle. Then (symmetry!)
> center2_for_max_Radius.x = Side/2
> Above we found
> Center2.x = sqrt(3)*Radius
> For the maximal circle we get
> center2_for_max_Radius.x = sqrt(3)*max_radius
> So
> Side/2 = sqrt(3)*max_radius
> i.e.
> max_Radius = Side/2/sqrt(3) = Side * sqrt(3)/6
> The minimal Radius obviously is zero, so all values in the range
> 0 .. Side*sqrt(3)/6
> are possible radii.
>
> [ Radius of mutually touching circles ]
> The circles are touching when the distance of their centers = 2*Radius.
> The situation is easily analyzed by looking at Center2 and Center3:
> Center3.x - Center2.x = 2*touch_Radius [y-coordinates are equal!]
> The coordinates of these centers are known:
> Side-sqrt(3)*touch_Radius - sqrt(3)*touch_Radius = 2*touch_Radius
> A little calculation solves this for touch_Radius:
> Side = (2*sqrt(3)-2) * touch_Radius
> touch_Radius = Side / (2*sqrt(3)-2) [now expand by (2*sqrt(3)+2):]
> = Side * (sqrt(3)-1)/4
>
> [ center of triangle ]
> This point isn't needed for the problem, but I suggest to calculate
> almost everything you can: it often gives deeper insight in the
> problem, reveals unexpected relations and simplifies other steps.
> In the trefoil problem, it helps finding the "true gothic" Radius.
> Again because of symmetry,
> Center.x = Side/2
> The bisectors of a triangle (which in this case also are angular
> bisectors and heights) intersect in its center of gravity and
> are divided by this point in a 2:1 ratio. This gives us
> Center.y = Height/3
>
> [ "true gothic" Radius ]
> In a "true gothic" situation, all circles meet at the Center, so
> their distance from this Center = Radius. In this case, the situation
> at the top is most easy:
> gothic_Center1.y - Center.y = gothic_Radius [x-coordinates are equal!]
> Because
> Center1.y = Height-2*Radius
> we have the special case
> gothic_Center1.y = Height-2*gothic_Radius =
sqrt(3)/2*Side-2*gothic_Radius
> We already found in the previous section
> Center.y = Height/3 = sqrt(3)/6*Side
> Putting all this together and solving for gothic_Radius, we find
> sqrt(3)/2*Side-2*gothic_Radius - sqrt(3)/6*Side = gothic_Radius
> sqrt(3)/3*Side = 3*gothic_Radius
> gothic_Radius = sqrt(3)/9*Side
>
>
> 6. During the paragraph 5 implement everything at once in POV-Ray
>
> This will reveal calculation errors and gives an exact drawing of the
> situation reached so far. And it's fun!
>
>
> .....
>
> I don't know your mathematical background, so maybe this was a little bit
> lengthy, but I hope this explanation will contribute to your ability to
> successfully attack similar (and more complex) problems.
>
> Sputnik
>
>
> --
> ----------------------------
> Frank 'Sputnik' Rothfuß
> fr### [at] computermuseum fh-kiel de
> ----------------------------
>
>
I didn't get to see the original post, so I'm not sure what a gothic trefoil
is. If you are looking for incircles, however:
#macro LineIntersect(p1, d1, p2, d2)
#local pSep = p2-p1;
#local pdCross = vcross(d1,d2);
#local pdLen = vlength(pdCross);
#local lDist = vdot(pSep,pdCross);
#local dist = vdot(vcross(pSep,d2),pdCross)/(pdLen*pdLen);
#local pnt = p1+d1*dist;
pnt
#end
#macro TriangleNorm(p1, p2, p3)
#local nrm = vnormalize(vcross(p2-p1,p3-p1));
nrm
#end
#macro icRad(p1, p2, p3) // Inscribed circle radius
#local ln1 = vlength(p2-p1);
#local ln2 = vlength(p3-p1);
#local ln3 = vlength(p3-p2);
#local hPer = (ln1+ln2+ln3)*0.5;
#local area = sqrt(hPer*(hPer-ln1)*(hPer-ln2)*(hPer-ln3));
#declare rad = area/hPer;
rad
#end
#macro icCen(p1, p2, p3) // Inscribed circle center
#local dr1 = vnormalize(p3-p2);
#local dr2 = vnormalize(p3-p1);
#local dr3 = vnormalize(p2-p1);
#local drb1 = vnormalize(-dr2-dr3); // Bisects angle through p1
#local drb2 = vnormalize(dr3-dr1); // Bisects angle through p2
#declare cen = LineIntersect(p1, drb1, p2, drb2);
cen
#end
#macro ccRad(p1, p2, p3) // Circumscribed circle radius
#local ln1 = vlength(p2-p1);
#local ln2 = vlength(p3-p1);
#local ln3 = vlength(p3-p2);
#local hPer = (ln1+ln2+ln3)*0.5;
#local area = sqrt(hPer*(hPer-ln1)*(hPer-ln2)*(hPer-ln3));
#declare rad = ln1*ln2*ln3*0.25/area;
rad
#end
#macro ccCen(p1, p2, p3) // Circumscribed circle center
#local pNrm = TriangleNorm(p1, p2, p3); // Unit triangle plane normal
#local mp1 = (p2+p3)*.5; // Midpoint of line opposite p1
#local mp2 = (p1+p3)*.5; // Midpoint of line opposite p2
#local dr1 = vnormalize(vcross(p3-p2,pNrm)); // Perpendicular to line opp.
p1
#local dr2 = vnormalize(vcross(p3-p1,pNrm)); // Perpendicular to line opp.
p2
#declare cen = LineIntersect(mp1, dr1, mp2, dr2);
cen
#end
#macro Pythag(a,b)
#local py = sqrt(a*a+b*b);
py
#end
#macro odfRing(pos, nrm, rad, wid, thk) difference {
cylinder { -nrm*wid, nrm*wid, rad }
cylinder { -nrm*wid*2, nrm*wid*2, rad-thk }
translate pos
} #end
#declare odfbSizIn = 2.85;
#declare odfbSizOut = 3.15;
#declare odfbSizEdge = 0.5*(odfbSizOut-odfbSizIn);
#declare odfbWid = 0.030;
#declare odfbWid2 = odfbWid*0.75;
#declare odfbThk = 0.01;
#declare odfbFrame = union {
difference {
box { <0, -odfbSizIn-odfbThk,-odfbWid>, <odfbSizIn+odfbThk, 0, odfbWid> }
box { <odfbThk, -odfbSizIn,-odfbWid*2>, <odfbSizIn,-odfbThk, odfbWid*2> }
}
box { <0, -odfbSizOut-odfbThk,-odfbWid>, <odfbSizOut, -odfbSizOut,
odfbWid> }
matrix <1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0>
clipped_by { plane { y, 0 } }
}
// Primary incircle
#declare odfiP1 = < odfbThk,-odfbThk, 0>;
#declare odfiP2 = < odfbSizIn,-odfbThk, 0>;
#declare odfiP3 = < odfbThk,-odfbSizIn, 0>;
#declare odfiNrm = TriangleNorm( odfiP1, odfiP2, odfiP3 );
#declare odfiRad0 = icRad( odfiP1, odfiP2, odfiP3 );
#declare odfiRad0a = odfiRad0+odfbThk;
#declare odfiCen0 = icCen( odfiP1, odfiP2, odfiP3 );
#declare odfiRing0 = odfRing(odfiCen0, odfiNrm, odfiRad0+odfbThk, odfbWid2,
odfbThk)
// Secondary incircle at p1
#declare odfiDr1 = vnormalize(odfiP1-odfiCen0);
#declare odfiP1a = odfiCen0+odfiRad0a*odfiDr1;
#declare odfiDr1p = vnormalize(vcross(odfiDr1, odfiNrm));
#declare odfiP12 = LineIntersect(odfiP1a, odfiDr1p, odfiP1, odfiP2-odfiP1);
#declare odfiP13 = LineIntersect(odfiP1a, odfiDr1p, odfiP1, odfiP3-odfiP1);
#declare odfiRad1 = icRad( odfiP1, odfiP12, odfiP13 );
#declare odfiCen1 = icCen( odfiP1, odfiP12, odfiP13 );
#declare odfiRing1 = odfRing(odfiCen1, odfiNrm, odfiRad1+odfbThk, odfbWid*4,
odfbThk)
// Secondary incircle at p2
#declare odfiDr2 = vnormalize(odfiP2-odfiCen0);
#declare odfiP2a = odfiCen0+odfiRad0a*odfiDr2;
#declare odfiDr2p = vnormalize(vcross(odfiDr2, odfiNrm));
#declare odfiP21 = LineIntersect(odfiP2a, odfiDr2p, odfiP2, odfiP1-odfiP2);
#declare odfiP23 = LineIntersect(odfiP2a, odfiDr2p, odfiP2, odfiP3-odfiP2);
#declare odfiRad2 = icRad( odfiP2, odfiP21, odfiP23 );
#declare odfiCen2 = icCen( odfiP2, odfiP21, odfiP23 );
#declare odfiRing2 = odfRing(odfiCen2, odfiNrm, odfiRad2+odfbThk, odfbWid2,
odfbThk)
// Secondary incircle at p3
#declare odfiDr3 = vnormalize(odfiP3-odfiCen0);
#declare odfiP3a = odfiCen0+odfiRad0a*odfiDr3;
#declare odfiDr3p = vnormalize(vcross(odfiDr3, odfiNrm));
#declare odfiP31 = LineIntersect(odfiP3a, odfiDr3p, odfiP3, odfiP1-odfiP3);
#declare odfiP32 = LineIntersect(odfiP3a, odfiDr3p, odfiP3, odfiP2-odfiP3);
#declare odfiRad3 = icRad( odfiP3, odfiP31, odfiP32 );
#declare odfiCen3 = icCen( odfiP3, odfiP31, odfiP32 );
#declare odfiRing3 = odfRing(odfiCen3, odfiNrm, odfiRad3+odfbThk, odfbWid2,
odfbThk)
#declare odfbRingPos = 0.5*(odfbSizIn+odfbSizOut);
#declare odfrRad = odfbSizEdge*sqrt(0.5);
#declare odfbRadEdge = odfrRad*1.10;
#declare odfrDist = odfbSizEdge-odfbThk*.5;
#declare odfrStep = <odfrDist,odfrDist,0>;
#declare odfrNum = int(odfbRingPos/odfrDist)-1;
#declare odfrOrig = (<odfbRingPos,-odfbRingPos,0>-odfrStep*(odfrNum-1))*0.5;
#declare odfbMiniRing = odfRing(0, odfiNrm, odfrRad, odfbWid2, odfbThk)
#declare odfbEdge = union {
difference {
cylinder { -z*odfbWid, z*odfbWid, odfbRadEdge }
cylinder { -z*odfbWid*2, z*odfbWid*2, odfbRadEdge-odfbThk }
plane { x, 0 }
translate y*(odfbSizEdge-odfbRadEdge)
}
box { <0,-odfbSizEdge,-odfbWid>, <odfbThk,
odfbSizEdge+odfbThk-odfbRadEdge*2, odfbWid> }
}
#declare odfBrace = union {
object { odfbFrame }
object { odfbEdge translate -y*odfbRingPos }
object { odfbEdge rotate -z*90 rotate y*180 translate x*odfbRingPos }
object { odfiRing0 }
object { odfiRing1 }
object { odfiRing2 }
object { odfiRing3 }
box { < 0.00,-odfbThk,-odfbWid>, < odfbSizIn+odfbThk, 0.00, odfbWid> }
ObjLine( odfbMiniRing, odfrOrig, odfrStep, odfrNum )
texture { colWLamp }
}
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Hi David,
a gothic trefoil is basically an equilateral triangle with circles
inscribed into the corners that meet in the triangle's midpoint.
Mark (aka LibraryMan aka LinuxLibrarian) asked for the construction
of these circles (thread started 12 June 2003). I described this
to him, so *I* know about incircles and all the other stuff :-)
In your macros you always create a variable to return the result --
this is not neccessary, simply return the expression that gives
the result. Enclose this expression in parentheses if neccessary
to avoid unwanted precedences. For example your
#macro Pythag(a,b)
#local py = sqrt(a*a+b*b);
py
#end
might be rewritten as
#macro Pythag(a,b)
sqrt(a*a+b*b)
#end
Here parentheses are required:
#macro Successor(N)
(N+1)
#end
else the expression 2*Successor(N) would result in 2*N+1 which is
interpreted as (2*N)+1 due to the priority of * over +.
Using all-lowercase identifiers is a bit dangerous. If you want
"future-proof" macros, no such variables should be used to avoid
conflicts with current or future keywords and with keywords of
unofficial versions of POV-Ray.
Sputnik
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|
 |