# Unable to get coordinates and angles on Ogee curve

I am trying to do some CAD designing with an Ogee curve. My Ogee is slightly more general than the typical one (where R1 = R2 = 1/2 W). In my Ogee the opening width (W) does not have to equal 2 * R1, and the Radius of the upper curve (R2) and the lower curve (R1) are not necessarily the same.

Someone else gave me some equations (which seem to me to be wrong) they are (t = thickness of the curve):

• the center of the lower circle C1 = [ W / 2 + t - r1, 0]
• the center of the upper circle C2 = [ r2, r2*sin(a)+r1*sin(a) ]
• the concordance point CP = [C1[0] + r1*cos(a), C21 - r2*sin(a)]
• the concordance angle a = acos((r2 - W/2 - t - r1)/( r1 + r2 ))

I can tell this is wrong because for the classic example (where R1 = R2 = W/2 and t = 0) the concordance angle should be 60 degrees but the angle from that formula is 120 degrees

Then I tried my own stab at the geometry but am also getting incorrect results (so far I'm ignoring thickness setting it to t = 0 but eventually I'll need to plug that in). Also the following assumes that the line from the center of the lower circle to the center of the upper circle passes through the concordance point

• centerLowerCirclex = W/2 - R1
• concordancex = centerLowerCirclex + R1 * cos(a)
• concordancey = W/2 + R1 * sin(a)
• centerUpperCirclex = R2
• concordancex = centerUpperCirclex - R2 * sin(90 - a)
• concordancey = centerUpperCircley - R2 * cos(90 - a)
• centerUpperCircley = R1 * sin(a) + R2 * cos(90 - a)

but if I put the first two together I get nonsense

• R1 * cos(a) = R1 - W/2
• cos(a) = (R1 - W/2) / R1

at this point I can see an obvious flaw; in the classic case R1 = 1/2 W we get cos(a) = 0 which means a = 90 degrees which is wrong again

Can someone point me in the right direction?

I'm including a picture of the classic ogee (no X-Y coordinate lines in that graph), where the radii of the upper circle and the lower circle are the same and the opening width is twice the radius. The ogee is the S like curve made by the arcs of the circles. I am starting to suspect that the concordance point is only collinear with the circle centers (A & C, or B & A on the other side) if the opening width (which is the same as the distance from B to C, but only when R1 = R2 = W/2) is twice the lower radius.

If you follow the S shape, the concordance point is the inflection where you leave one circle arc and follow the other one. It is also where the two circles touch.

The the NON-classic ogee is in the graph with the X-Y bars. Pay attention to the s curves Y < 0. W < 1/2 R2 because the lower circle is offset (so instead of a half circle the lower curve is a roman arch shape, in the fourth quadrant I am showing how two circles of R1 are making a Width that is less than 2*R1). Also R1 != R2.

This is the classic ogee R1=R2=1/2*W

In my ogees W will at most be 2 * R1, sometimes it will be less; R1 and R2 do not have to be equal

• I think you should re-format your question using MathJax to make it easy-to-read and attract somone to answer – Jaideep Khare Feb 4 '18 at 20:49
• Please provide a diagram (or a link to one) showing how the "upper radius", "lower radius", and "opening width" are defined. – Blue Feb 5 '18 at 1:25
• Jaideep I looked at the MathJax but am not seeing how to use it I tried using _ for subscript but preview showed a _ – Dan S Feb 5 '18 at 18:42
• You seem to be writing "half" where you mean "twice". In your final paragraph, you write "the opening width is half the [lower] radius", but I think you mean "the opening width is twice the lower radius". Likewise, in your first paragraph, you contrast your custom Ogee with the standard one where "R1 = R2 = 1/2 O" by writing that, in your configuration, "O does not have to equal 1/2 R1"; I think you mean "O does not have to equal 2 R1". (BTW: It's a little unsettling to have a width labelled "O", which looks a lot like a zero. :) Why not W?) – Blue Feb 5 '18 at 22:04
• Can you provide more specific description of your figure? (1) What is the "concordance point"? (2) Is it required that the upper arcs are tangent at their meeting point? (Equivalently, is it required that $B$, $C$, and the meeting point are collinear?) (3) Writing $\overline{HJ}$ for the diameter of the bottom circle (with $H$ on the left), is it required that $\overline{BH}$ be perpendicular to $\overline{HJ}$? – Blue Feb 5 '18 at 22:23

Let's consider two examples of an Ogee curve with thickness (i.e., consisting of two Ogee curves in parallel):

In the above illustration, let's say the curve starts from lower left to upper right, so the blue part is part $1$, and the red part is part $2$. Let $r_1$ be the inner radius of the blue circular arc, $r_2$ the inner radius of the red circular arc, and $t$ "thickness" of the arc (separation between the parallel concentric arcs). So, the outer radius of the blue part is $r_1 + t$, and the outer radius of the red part is $r_2 + t$.

The distance between the centers is $r_1 + t + r_2$. The first inner arc is $C^1$-continuous with the second outer arc, and the first outer arc is $C^1$-continuous with the second inner arc.

The red curve in the center is the zero-thickness Ogee curve. In the blue part, its radius is $r_1 + t/2$; in the red part, its radius is $r_2 + t/2$.

Because the two circular arcs always join where their tangents are parallel, the join is always on the line between the centers of the arc. (This is true, because the tangent on a circular arc is always perpendicular to its radius. So, when the tangents of two different circular arcs match at the same point, then that point must be on the radius of both arcs, and thus must be on the line between the two arcs' centers.)

When two Ogee curves are joined symmetrically at one endpoint, as in OP's illustration, the shape is called an Ogee arch.

The inflection point, where the red and blue arcs meet, is at \begin{aligned} x_i &= r_1 + t - (r_1 + t) \cos\varphi = (r_1 + t)(1 - \cos\varphi) \\ y_i &= (r_1 + t) \sin\varphi \end{aligned} The center of the upper (blue) arc is at \begin{aligned} x_u &= r_1 + t - (r_1 + t + r_2) \cos\varphi \\ y_u &= (r_1 + t + r_2) \sin\varphi \end{aligned} The apex is at $(x, y)$, \begin{aligned} x &= x_u + r_2 \cos \theta_2 \\ y &= y_u - r_2 \sin \theta_2 \end{aligned} \iff \begin{aligned} x &= r_1 + t - (r_1 + t + r_2) \cos\varphi + r_2 \cos\theta_2 \\ y &= (r_1 + t + r_2) \sin\varphi - r_2 \sin\theta_2 \end{aligned}

The arch may optionally have a triangular (or quadrangular) cap with maximum width $b$, and height $c$ above a capless arch:

If you know the apex angle $\beta$ ($= 2 \theta_2$) and the width of the cap $b$, the height $c$ is $$c = \frac{b}{2 \tan \theta_2} = \frac{b}{2 \tan\frac{\beta}{2}}$$ If there is no cap, then $b = c = d = 0$.

The $d$ part extends into the arches, and is not counted in the cap height. However, it is useful to note that $$d = \frac{b^2}{4 c} = \frac{b}{2}\tan\frac{\beta}{2}$$ since $d = h_5 - h_4$ in the illustration below.

(SVG version.)

The total width of the Ogee arch $w$ is $2 x + b$, and height $h$ is $y + c$: \bbox[#FFFFF7, 1em, border: 1px solid black] { \left\lbrace \begin{aligned} \displaystyle w &= b + 2 (r_1 + t) - 2 (r_1 + t + r_2) \cos\varphi + 2 r_2 \cos\frac{\beta}{2} \\ \displaystyle h &= (r_1 + t + r_2) \sin\varphi - r_2 \sin\frac{\beta}{2} + \frac{b}{2 \tan\frac{\beta}{2}} \end{aligned} \right. } \tag{1}\label{NA1} where the final term for $h$ (corresponding to cap height $c$) is omitted $\beta = 0$.

It is important to note that the above holds for all valid Ogee arches. If it does not, then an arch with such properties ($w$, $h$, $t$, $r_1$, $r_2$, $b$, $\beta$, $\varphi$) is not possible.

The detailed parameters using $w$, $h$, $r$, $r_1$, $r_2$, $b$, $\beta$, and $\varphi$ can be calculated as follows: \begin{aligned} x_1 &= \frac{w}{2} - t - r_1 \\ w_1 &= \frac{b}{2} \\ w_2 &= x_1 + r_1 \cos\varphi = \frac{w}{2} - t + r_1 (1 - \cos\varphi) \\ w_3 &= x_1 + (r_1 + t) \cos\varphi = \frac{w}{2} + (r_1 + t)(1 - \cos\varphi) \\ x_2 &= x_1 + (r_1 + t + r_2) \cos\varphi \\ \; &= w_1 + r_2 \cos\theta_2 = \frac{b}{2} + r_2 \cos\frac{\beta}{2} \\ y_2 &= (r_1 + t + r_2) \sin\varphi \\ h_5 &= y_2 - r_2 \sin\theta_2 = (r_1 + t + r_2) \sin\varphi - r_2 \sin\frac{\beta}{2} \\ h_4 &= h_5 - d = (r_1 + t + r_2) \sin\varphi - r_2 \sin\frac{\beta}{2} - \frac{b}{2}\tan\frac{\beta}{2} \\ h_2 &= (r_1 + t) \sin\varphi \\ h_1 &= r_1 \sin\varphi \end{aligned}

Note that although $\eqref{NA1}$ can be solved for many pairs of unknowns, in most cases the solutions can only be found numerically. This is because the width and height are very nonlinear functions of their arguments. If we rewrite $\eqref{NA1}$ as $$\begin{cases} \displaystyle W = b + 2 (r_1 + t) - 2 (r_1 + t + r_2) \cos\varphi + 2 r_2 \cos\frac{\beta}{2} - w = 0 \\ \displaystyle H = (r_1 + t + r_2) \sin\varphi - r_2 \sin\frac{\beta}{2} + \frac{b}{2 \tan\frac{\beta}{2}} - h = 0 \end{cases}, \; \; b \gt 0, \beta \gt 0$$ or $$\begin{cases} \displaystyle W = 2 (r_1 + t) - 2 (r_1 + t + r_2) \cos\varphi + 2 r_2 \cos\frac{\beta}{2} - w = 0 \\ \displaystyle H = (r_1 + t + r_2) \sin\varphi - r_2 \sin\frac{\beta}{2} - h = 0 \end{cases}, \; \; b = 0$$ depending on whether or not there is an end cap ($b$), we can use root-finding algorithms to find the solutions ($W = 0$, $H = 0$) numerically.

The partial derivatives of $W$ and $H$, in case they are useful for finding the roots, are \begin{aligned} \frac{d\,W}{d\,\varphi} &= 2 ( r_1 + t + r_2 ) \sin\varphi \\ \frac{d\,W}{d\,\beta} &= -r_2 \sin\frac{\beta}{2} \\ \frac{d\,W}{d\,b} &= 1 \\ \frac{d\,W}{d\,t} &= 2 - 2 \cos\varphi \\ \frac{d\,W}{d\,r_1} &= 2 - 2 \cos\varphi \\ \frac{d\,W}{d\,r_2} &= 2 \cos\frac{\beta}{2} - 2 \cos\varphi \end{aligned} \quad \mid \quad \begin{aligned} \frac{d\,H}{d\,\varphi} &= (r_1 + t + r_2) \cos\varphi \\ \frac{d\,H}{d\,\beta} &= \begin{cases} -\frac{r_2}{2 \cos\frac{\beta}{2}} - b \frac{\left(\tan\frac{\beta}{2}\right)^2 + 1}{4 \left(\tan\frac{\beta}{2}\right)^2}, & b \gt 0, \; \beta \gt 0 \\ -\frac{r_2}{2 \cos\frac{\beta}{2}}, & b = 0 \end{cases} \\ \frac{d\,H}{d\,b} &= \frac{1}{2\tan\frac{\beta}{2}} \\ \frac{d\,H}{d\,t} &= \sin\varphi \\ \frac{d\,H}{d\,r_1} &= \sin\varphi \\ \frac{d\,H}{d\,r_2} &= \sin\varphi - \sin\frac{\beta}{2} \\ \end{aligned}

Below are some of the cases where I found an algebraic solution.

When the arch width, height, cap width, apex angle, and the angle the lower arc extends ($w$, $h$, $b$, $\beta$, $\varphi$, respectively) are all defined, we can solve the arc radii from $\eqref{NA1}$. Using $$\begin{array}{cc} s_\beta = \sin\frac{\beta}{2} & s_\varphi = \sin\varphi \\ c_\beta = \cos\frac{\beta}{2} & c_\varphi = \cos\varphi \\ t_\beta = \tan\frac{\beta}{2} & \; \end{array}$$ for shorthand, if $\beta \gt 0$ and $b \gt 0$, we get \left\lbrace\begin{aligned} r_1 &= \frac{ \left( t_\beta (s_\varphi - s_\beta) (w - b - 2 t) + \frac{1}{2} (c_\varphi - c_\beta) (2 h t_\beta - b) \right) - t_\beta (c_\varphi s_\beta - c_\beta s_\varphi) t }{t_\beta \left( c_\varphi s_\beta - c_\beta s_\varphi - s_\beta + s_\varphi \right)} \\ r_2 &= \frac{ t_\beta h - \frac{1}{2}\left( b - s_\varphi t_\beta (w - b) - c_\varphi (2 h t_\beta - b) \right) }{t_\beta \left( c_\varphi s_\beta - c_\beta s_\varphi - s_\beta + s_\varphi \right)} \end{aligned}\right. Otherwise, $b = 0$, and \left\lbrace\begin{aligned} r_1 &= \frac{t (c_\beta s_\varphi + s_\beta - s_\varphi) - \frac{w}{2} (s_\beta - s_\varphi) - h c_\beta - (t s_\beta - h) c_\varphi}{ c_\varphi s_\beta - c_\beta s_\varphi - s_\beta + s_\varphi } \\ r_2 &= \frac{h (1 - c_\varphi) - \frac{w}{2} s_\varphi}{c_\varphi s_\beta - c_\beta s_\varphi - s_\beta + s_\varphi} \end{aligned}\right.

When the arch width $w$, the arc radii $r_1$ and $r_2$, the thickness $t$, and the desired apex width $b$ and angle $\beta$ are known, there is an algebraic solution: \begin{aligned} \varphi &= \pi - \arccos\left(\frac{ \frac{w - b}{2} - r_1 - t - r_2 \cos\frac{\beta}{2} }{r_1 + t + r_2}\right) \\ x_1 &= \frac{w}{2} - t - r_1 \\ x_2 &= x_1 + (r_1 + t + r_2) \cos\varphi \\ y_2 &= (r_1 + t + r_2) \sin\varphi \\ w_1 &= \frac{b}{2} \\ w_2 &= x_1 + r_1 \cos\varphi \\ w_3 &= x_1 + (r_1 + t) \cos\varphi \\ h_1 &= r_1 \sin\varphi \\ h_2 &= (r_1 + t) \sin\varphi \\ \theta_1 &= \arccos \frac{x_2}{r_2 + t} \\ h_3 &= y_2 - (r_2 + t) \sin\theta_1 = y_2 - (r_2 + t) \sqrt{1 - \frac{x_2^2}{(r_2 + t)^2}} \\ h_5 &= y_2 - r_2 \sin\frac{\beta}{2} \\ h_4 &= h_5 - \frac{b}{2}\tan\frac{\beta}{2} \\ h &= h_5 + \frac{b}{2 \tan\frac{\beta}{2}} \quad \text{ if } \; \beta \gt 0 \\ \; &= h_5 \quad \text{ if } \quad \beta = 0 \\ \end{aligned}

Here is ogee.py, a Python program that outputs an Ogee arch in SVG format to standard output, when given the arch width, arch thickness, lower arc radius, upper arc radius, and optionally apex angle (in degrees; defaults to infinitely sharp apex if unspecified) and cap width, as command-line arguments:

#!/usr/bin/python
import sys
from math import pi, sin, cos, tan, asin, acos, atan, sqrt

def arc(fromx, fromy, tox, toy, radius, sweep):
global x0, y0
return '<path stroke="#000" stroke-width="2" fill="none" d="M%.3f,%.3f A%.3f,%.3f,0,0,%d,%.3f,%.3f" />'"\n" % (x0+fromx, y0-fromy, radius, radius, sweep, x0+tox, y0-toy)

def line(fromx, fromy, tox, toy):
global x0, y0
return '<path stroke="#000" stroke-width="2" fill="none" d="M%.3f,%.3f L%.3f,%.3f" />'"\n" % (x0+fromx, y0-fromy, x0+tox, y0-toy)

def linevia(fromx, fromy, viax, viay, tox, toy):
global x0, y0
return '<path stroke="#000" stroke-width="2" fill="none" d="M%.3f,%.3f L%.3f,%.3f %.3f,%.3f" />'"\n" % (x0+fromx, y0-fromy, x0+viax, y0-viay, x0+tox, y0-toy)

if __name__ == '__main__':

# Parse parameters
if len(sys.argv) >= 5 and len(sys.argv) <= 7:
w = float(sys.argv[1])
t = float(sys.argv[2])
r1 = float(sys.argv[3])
r2 = float(sys.argv[4])
if len(sys.argv) >= 6:
beta = float(sys.argv[5]) * pi / 180.0
if beta > 0.0 and len(sys.argv) >= 7:
b = float(sys.argv[6])
else:
b = 0.0
else:
beta = 0.0
b = 0.0

else:
sys.stderr.write("\n"
"Usage: %s width thickness lowerradius upperradius [ apexangle [ apexwidth ] ] > output.svg\n"
"\n"
"If specified, the apex angle is in degrees.\n"
"\n" % sys.argv[0])
sys.exit(1)

# The base angle (lower arc angle) is phi:
phi = pi - acos( (0.5*(w-b) - r1 - t - r2*cos(0.5*beta)) / (r1 + t + r2))
x1 = 0.5*w - t - r1
x2 = x1 + (r1 + t + r2)*cos(phi)
y2 = (r1 + t + r2)*sin(phi)
w1 = 0.5*b
w2 = x1 + r1*cos(phi)
w3 = x1 + (r1+t)*cos(phi)
h1 = r1*sin(phi)
h2 = (r1+t)*sin(phi)
h3 = y2 - (r2 + t)*sqrt(1 - (x2*x2)/((r2+t)*(r2+t)))
h5 = y2 - r2*sin(0.5*beta)
h4 = h5 - 0.5*b*tan(0.5*beta)
if beta > 0.0:
h = h5 + 0.5*b/tan(0.5*beta)
else:
h = h5

w0 = x1
w4 = x1 + r1
w5 = x1 + r1 + t

pixelwidth = round(2*t + w)
pixelheight = round(2*t + h)
x0 = int(pixelwidth / 2)
y0 = int(round(h + t))

sys.stdout.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>' "\n"
'<svg xmlns="http://www.w3.org/2000/svg" width="%d" height="%d" viewBox="0 0 %d %d" >' "\n" % (pixelwidth, pixelheight, pixelwidth, pixelheight))
sys.stdout.write('<rect x="0" y="0" width="%d" height="%d" stroke="none" fill="#fff" />' "\n" % (pixelwidth, pixelheight))

# Left-side lower outer arc
sys.stdout.write(arc( -w5,0, -w3,h2, r1+t, 1 ))

# Left-side upper outer arc
sys.stdout.write(arc( -w3,h2, -w1,h5, r2, 0 ))

# Cap
if w1 > 0:
sys.stdout.write(linevia( -w1,h5, 0,h, w1,h5 ))

# Right-side upper outer arc
sys.stdout.write(arc( w1,h5, w3,h2, r2, 0 ))

# Right-side lower outer arc
sys.stdout.write(arc( w3,h2, w5,0, r1+t, 1 ))

# Right-side lower inner arc
sys.stdout.write(arc( w4,0, w2,h1, r1, 0 ))

# Right-side upper inner arc
sys.stdout.write(arc( w2,h1, 0,h3, r2+t, 1 ))

# Left-side upper inner arc
sys.stdout.write(arc( 0,h3, -w2,h1, r2+t, 1 ))

# Left-size lower inner arc
sys.stdout.write(arc( -w2,h1, -w4,0, r1, 0 ))

# Arc separator lines
sys.stdout.write(line( -w2,h1, -w3,h2 ))
sys.stdout.write(line(  w2,h1,  w3,h2 ))
sys.stdout.write(line( 0,h4, 0,h3 ))
sys.stdout.write(line( -w5,0, -w4,0 ))
sys.stdout.write(line(  w5,0,  w4,0 ))

# Cap bottom
if w1 > 0:
sys.stdout.write(linevia( -w1,h5, 0,h4, w1,h5 ))

sys.stdout.write("</svg>\n")


Save the above as ogee.py, and run e.g.

python ogee.py 800 10 500 600 45 15 > out.svg


Note that the above program generates each curve and line as separate path elements, so that it is easy to examine the generated file in e.g. Inkscape.

Feel free to use or modify the Python program as you wish; I consider it to be in public domain.

• I'll try plugging this in the CAD software tomorrow. For now I"ll assume this all works and upvote/accept. I'll award the bounty tomorrow if it works in the CAD software – Dan S Feb 14 '18 at 23:52
• So I'm plugging stuff in and wondering about typos, and a bit confused. I know x1 y1 because if w = 2r1 then x1 = 0 (and so far I'm not dealing with y offsets so y1 = 0) if w < 2r1 then x1 is on the "opposite side" of the curve (some positive value for the left hand side of the curve and a negative value for the right hand side of the curve. For your w expression shouldn't it be w = 2(t + r1) + 2(t + r2)cosβ - 2(t + r1 + r2)cosφ1. I know the following x1, y1, r1, r2, t. I am trying to get φ1, y0, x2, y2, and φ2, β. It looks like φ1 = φ2 + β. Can you help me? – Dan S Feb 16 '18 at 16:51
• @Nocturnal Animal can you please look over my question about the width. Also I'm trying to look for simple expressions for φ1, y0, x2, y2, φ2, β, h. The knowns I have are (x1,y1), r1, r2, t, w. – Dan S Feb 16 '18 at 19:29
• I'm a bit confused when you talk about "the apex can be a sharp point, a cap of width t, or a cap of width 2t" The standard Ogee does not have a flat portion but an inflection point at the top (an infinitely sharp tip) with no defined curvature (I think if you try to determine it you get a nonsense result). I'd like some simple equations for the unknowns (φ1, y0, x2, y2, φ2, β, h) given the known parameters (x1,y1), r1, r2, t, w. When I say "simple" I mean ideally each unknown has an equation using only known parameters. – Dan S Feb 16 '18 at 20:27
• Also I've awarded the bounty but would also like it if you could check my question about w. When I looked at it I got something slightly different than what you posted. – Dan S Feb 16 '18 at 20:33