Discussion:
Ellipse with border calculation
(too old to reply)
Bint
2014-03-13 17:20:49 UTC
Permalink
Hello,

I'm trying to generate points for an ellipse in OpenGL. The simple
ellipse has been easy, as I just scale the points for a circle in the Y
direction to squash or stretch. I don't know if this is an actual ellipse,
but for my purposes it's ok.

The problem is that I want to generate the points for a border around that
ellipse, and the border needs to be a constant width all the way around. I
can't just generate the points for a slightly larger ellipse the way I am
doing now, because the border width will scale along with the wider axis.

Is there any easy way to generate the points for the border? I am thinking
maybe I need to slightly alter the scaling according to my border width, but
I am not sure what the calculation should be.

OR, maybe I need to find a "real" ellipse equation and generate the points
that way? So far though all I have found online seems to be equations that
generate the points for a circle and scale the X and Y differently. Maybe
that is a real ellipse, I don't know.

Thanks!
B
Dr J R Stockton
2014-03-14 21:37:35 UTC
Permalink
Post by Bint
I'm trying to generate points for an ellipse in OpenGL. The simple
ellipse has been easy, as I just scale the points for a circle in the Y
direction to squash or stretch. I don't know if this is an actual ellipse,
but for my purposes it's ok.
It is an ellipse.
Post by Bint
The problem is that I want to generate the points for a border around that
ellipse, and the border needs to be a constant width all the way around. I
can't just generate the points for a slightly larger ellipse the way I am
doing now, because the border width will scale along with the wider axis.
Agreed.
Post by Bint
Is there any easy way to generate the points for the border? I am thinking
maybe I need to slightly alter the scaling according to my border width, but
I am not sure what the calculation should be.
Perhaps instead you can draw a slightly larger ellipse with half-width
internal and external borders?

If so, and if efficiency is not important, and if what you want is a
thicker ellipse, you could draw a small filled circle at each point of
the ellipse.
Post by Bint
OR, maybe I need to find a "real" ellipse equation and generate the points
that way? So far though all I have found online seems to be equations that
generate the points for a circle and scale the X and Y differently. Maybe
that is a real ellipse, I don't know.
An ellipse satisfies (x/a)^2 + (y/b)^2 = 1 ; you may need to move it and
rotate it. Ideally, you would calculate the tangent at each point of
the ellipse, erect an outwards perpendicular of length - border-width,
and its end would be a border point.

It might be easier in polar co-ordinates - anyway, see
<http://en.wikipedia.org/wiki/Ellipse>.
--
(c) John Stockton, nr London, UK. Mail via homepage. Turnpike v6.05 MIME.
Web <http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms and links;
Astro stuff via astron-1.htm, gravity0.htm ; quotings.htm, pascal.htm, etc.
No Encoding. Quotes before replies. Snip well. Write clearly. Mail no News.
Hans-Bernhard Bröker
2014-03-15 14:37:02 UTC
Permalink
Post by Dr J R Stockton
Post by Bint
Is there any easy way to generate the points for the border? I am thinking
maybe I need to slightly alter the scaling according to my border width, but
I am not sure what the calculation should be.
Perhaps instead you can draw a slightly larger ellipse with half-width
internal and external borders?
No, that wouldn't work. The offset curve of an ellipse is not another
ellipse. It looks deceptively much like it, particularly if the offset
it small compared to the ellipse's half axes, and in simple use cases
one might get away with it, but it's really wrong.

The gory details are best expressed by parametric curves. 't' here is
the parameter --- it works basically like the angle along a circle.

point(t; a,b) := [a*cos(t), b*sin(t)]
Ellipse(a,b) = { point(t;a,b) | t = 0..2*pi }

Now you need the unit-length vector orthogonal to the ellipse, at the
position of parameter value 't'. This is built by first computing the
tangent vector, dividing out its length and rotating it by 90 degrees:

deriv(t;a,b) := d/dt point(t;a,b)
= [-a*sin(t), b*cos(t)]
sped(t;a,b) := length(deriv(t;a,b))
= sqrt((a*sin(t))^2 + (b*cos(t))^2)
normal(t;a,b) = rotate(90 degrees, deriv(t;a,b)) / sped(t;a,b)
= [b*cos(t), a*sin(t)] / sped(t;a,b)

(NB: the thing called 'sped' is almost, but not quite, the speed along
the ellipse --- thus the name).

The offset curve is then built by going distance 'd' along this normal
vector:

offset_point(t;a,b,d) := point(t;a,b) + d * normal(t;a,b)
= [(a + d*b/sped(t;a,b)) * cos(t),
(b + d*a/sped(t;a,b)) * sin(t)]

Offset_Curve(a,b,d) := { offset_point(t;a,b,d) | t = 0..2*pi}

The resulting equation looks similar to that of a bigger ellipse, which
would be:

bigpoint(t;a,b,d) := [(a + d) * cos(t), (b + d) * sin(t)]

But the modification by factors b/sped() and a/sped() is important,
because these factors themselves change with t, via sped().

Loading...