Saturday, March 24, 2012

Why so much trouble with ellipses?

In a recent post of mine I mentioned the inaccurate shapes drawn by
FillEllipse. In the response that I recieved I was told that DrawArc had
less problems, which I found to be true (I have been using DrawEllipse, but
they seem to have the same results when drawing a complete 360). However,
even with these methods, there are situations where the results are not even
symmetric along both axes (my best example of this is with a width and
height of 6). I know enough about math and computers to be able to figure
out how to write a simple method to create a basic circle or ellipse, so I'm
not going to ask anyone to tell me how to fix it (even though that would be
nice), but I am going to ask why couldn't Microsoft make this simple method
themselves? It's not like this is the first time they ever had to do it.
Heck, they could have just borrowed some code from Paint, I know that that
makes correct circles/ellipses. Do they plan to fix this in a future
version, or is GDI+ such a small part of .NET that they don't care? (I will
admit that I am guilty of still using .NET 1.1, but I still think it should
have been a simple enough task that they could have done it right by now).
What do all of you think?
--
Nathan Sokalski
njsokalski@dotnet.itags.org.hotmail.com
http://www.nathansokalski.com/Nathan,
You make me curious I see a lot of crossposting adresses. Feel free to do
that.
The in my idea real newsgroup for this question
microsoft.public.dotnet.framework.drawing
is not in it.
What is the reason for that?
Cor
I am not currently subscribed to that newsgroup, so I guess I forgot to post
to it. But now that I know about it, I guess it would be one of, if not the,
best group for my question. Thanks.
--
Nathan Sokalski
njsokalski@.hotmail.com
http://www.nathansokalski.com/
"Cor Ligthert [MVP]" <notmyfirstname@.planet.nl> wrote in message
news:%23VUnRJBGGHA.1032@.TK2MSFTNGP12.phx.gbl...
> Nathan,
> You make me curious I see a lot of crossposting adresses. Feel free to do
> that.
> The in my idea real newsgroup for this question
> microsoft.public.dotnet.framework.drawing
> is not in it.
> What is the reason for that?
> Cor
>
Hi Nathan
these two thing should help you, you don't need to use them both, it seems
to me that setting the g.SmoothingMode gives better results.
g.PixelOffsetMode = Drawing2D.PixelOffsetMode.Half
g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
Greetz Peter
Programming today is a race between software engineers striving to build
bigger and better idiot-proof programs, and the Universe trying to produce
bigger and better idiots. So far, the Universe is winning. (Rich Cook)
"Nathan Sokalski" <njsokalski@.hotmail.com> schreef in bericht
news:uI$Q1sHGGHA.2012@.TK2MSFTNGP14.phx.gbl...
> I am not currently subscribed to that newsgroup, so I guess I forgot to
post
> to it. But now that I know about it, I guess it would be one of, if not
the,
> best group for my question. Thanks.
> --
> Nathan Sokalski
> njsokalski@.hotmail.com
> http://www.nathansokalski.com/
> "Cor Ligthert [MVP]" <notmyfirstname@.planet.nl> wrote in message
> news:%23VUnRJBGGHA.1032@.TK2MSFTNGP12.phx.gbl...
do
>
I tried all of the settings for each of these, but none of them made
ellipses with a radius of 6 the same on all sides, the closest ones were the
same as not setting the settings at all. I am assuming that this would be
true for other radii as well, but since DrawEllipse already gave me good
ellipses for all the radii I tried, I didn't bother testing anything other
than 6. In other words, back to the System.Drawing board.
--
Nathan Sokalski
njsokalski@.hotmail.com
http://www.nathansokalski.com/
"Peter Proost" <pproost@.nospam.hotmail.com> wrote in message
news:eSAk5CoGGHA.648@.TK2MSFTNGP14.phx.gbl...
> Hi Nathan
> these two thing should help you, you don't need to use them both, it seems
> to me that setting the g.SmoothingMode gives better results.
> g.PixelOffsetMode = Drawing2D.PixelOffsetMode.Half
> g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
> Greetz Peter
> --
> Programming today is a race between software engineers striving to build
> bigger and better idiot-proof programs, and the Universe trying to produce
> bigger and better idiots. So far, the Universe is winning. (Rich Cook)
> "Nathan Sokalski" <njsokalski@.hotmail.com> schreef in bericht
> news:uI$Q1sHGGHA.2012@.TK2MSFTNGP14.phx.gbl...
> post
> the,
> do
>
Hi Nathan,
if I add g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality to the sample
I posted a couple of days ago, I get nice ellipses with drawellipse and
fillellipse for all radii from 4 to 14 (haven't tested any further)
Grtz Peter
Programming today is a race between software engineers striving to build
bigger and better idiot-proof programs, and the Universe trying to produce
bigger and better idiots. So far, the Universe is winning. (Rich Cook)
"Nathan Sokalski" <njsokalski@.hotmail.com> schreef in bericht
news:#$43EQwGGHA.2036@.TK2MSFTNGP14.phx.gbl...
> I tried all of the settings for each of these, but none of them made
> ellipses with a radius of 6 the same on all sides, the closest ones were
the
> same as not setting the settings at all. I am assuming that this would be
> true for other radii as well, but since DrawEllipse already gave me good
> ellipses for all the radii I tried, I didn't bother testing anything other
> than 6. In other words, back to the System.Drawing board.
> --
> Nathan Sokalski
> njsokalski@.hotmail.com
> http://www.nathansokalski.com/
> "Peter Proost" <pproost@.nospam.hotmail.com> wrote in message
> news:eSAk5CoGGHA.648@.TK2MSFTNGP14.phx.gbl...
seems
produce
to
>
Here's the example again because it wasn't origanly posted in this thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim myBmp As New Bitmap(450, 450)
Dim g As Graphics
g = Graphics.FromImage(myBmp)
g.Clear(Color.Black)
g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
Dim posX As Integer = 10
Dim myWidth, myHeight As Integer
myWidth = 4
myHeight = 4
For i As Integer = 0 To 21
If i <= 10 Then
drawCircles(g, 0, posX, myWidth, myHeight)
Else
drawCircles(g, 1, posX, myWidth, myHeight)
End If
posX += 20
myWidth += 1
myHeight += 1
If i = 10 Then
myWidth = 4
myHeight = 4
End If
Next
g.Dispose()
PictureBox1.Image = myBmp
myBmp.Save("c:\testEllipse.bmp", Drawing.Imaging.ImageFormat.Bmp)
MsgBox("c:\testEllipse.bmp Saved", MsgBoxStyle.Information, "Saved")
End Sub
Private Sub drawCircles(ByVal g As Graphics, ByVal drawType As Integer,
ByVal x As Integer, ByVal width As Integer, _ ByVal _ height As Integer)
Dim intY As Integer = 5
For i As Integer = 0 To 20
Select Case drawType
Case 0
g.FillEllipse(Brushes.LawnGreen, x, intY, width, height)
Case 1
g.DrawEllipse(Pens.LawnGreen, x, intY, width, height)
End Select
intY += 18
Next
End Sub
Greetz Peter
--
Programming today is a race between software engineers striving to build
bigger and better idiot-proof programs, and the Universe trying to produce
bigger and better idiots. So far, the Universe is winning. (Rich Cook)
"Nathan Sokalski" <njsokalski@.hotmail.com> schreef in bericht
news:#$43EQwGGHA.2036@.TK2MSFTNGP14.phx.gbl...
> I tried all of the settings for each of these, but none of them made
> ellipses with a radius of 6 the same on all sides, the closest ones were
the
> same as not setting the settings at all. I am assuming that this would be
> true for other radii as well, but since DrawEllipse already gave me good
> ellipses for all the radii I tried, I didn't bother testing anything other
> than 6. In other words, back to the System.Drawing board.
> --
> Nathan Sokalski
> njsokalski@.hotmail.com
> http://www.nathansokalski.com/
> "Peter Proost" <pproost@.nospam.hotmail.com> wrote in message
> news:eSAk5CoGGHA.648@.TK2MSFTNGP14.phx.gbl...
seems
produce
to
>
Take note that in your code you do not draw the circles using the DrawEllips
e method, you use a custom-written Sub, DrawCircles. Even though DrawCircles
uses DrawEllipse (or FillEllipse) and should have the same results as if yo
u called DrawEllipse directly, my results still do not work. Here is my code
and what I get:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.Event
Args) Handles MyBase.Load
Dim mybitmap As New Bitmap(10, 10)
Dim mygraphic As Graphics = Graphics.FromImage(mybitmap)
mygraphic.DrawEllipse(New Pen(Color.HotPink, 1), 1, 1, 5, 5)
mybitmap.Save(Server.MapPath("images/ellipse6.gif"), Imaging.ImageFormat.Gif
)
Image1.ImageUrl = "images/ellipse6.gif?timemade=" & Server.UrlEncode(Date.No
w.ToShortDateString() & Date.Now.ToLongTimeString())
End Sub
My code uses 5 rather than 6, I probably forgot to mention this in my previo
us postings since my application makes this adjustment automatically (sorry
for any confusion). But either way, it shouldn't be happening. What results
do you get when you enter 5 for the width/height parameters? Thanks.
--
Nathan Sokalski
njsokalski@.hotmail.com
http://www.nathansokalski.com/
"Peter Proost" <pproost@.nospam.hotmail.com> wrote in message news:uP0AHezGGHA.3896@.TK2MSFTN
GP15.phx.gbl...
> Here's the example again because it wasn't origanly posted in this thread
>
> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles Button1.Click
> Dim myBmp As New Bitmap(450, 450)
> Dim g As Graphics
> g = Graphics.FromImage(myBmp)
> g.Clear(Color.Black)
> g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
> Dim posX As Integer = 10
> Dim myWidth, myHeight As Integer
> myWidth = 4
> myHeight = 4
> For i As Integer = 0 To 21
> If i <= 10 Then
> drawCircles(g, 0, posX, myWidth, myHeight)
> Else
> drawCircles(g, 1, posX, myWidth, myHeight)
> End If
> posX += 20
> myWidth += 1
> myHeight += 1
> If i = 10 Then
> myWidth = 4
> myHeight = 4
> End If
> Next
> g.Dispose()
> PictureBox1.Image = myBmp
> myBmp.Save("c:\testEllipse.bmp", Drawing.Imaging.ImageFormat.Bmp)
> MsgBox("c:\testEllipse.bmp Saved", MsgBoxStyle.Information, "Saved")
>
>
> End Sub
>
> Private Sub drawCircles(ByVal g As Graphics, ByVal drawType As Integer,
> ByVal x As Integer, ByVal width As Integer, _ ByVal _ height As Integer)
> Dim intY As Integer = 5
> For i As Integer = 0 To 20
> Select Case drawType
> Case 0
> g.FillEllipse(Brushes.LawnGreen, x, intY, width, height
)
> Case 1
> g.DrawEllipse(Pens.LawnGreen, x, intY, width, height)
> End Select
> intY += 18
> Next
> End Sub
>
> Greetz Peter
> --
> Programming today is a race between software engineers striving to build
> bigger and better idiot-proof programs, and the Universe trying to produce
> bigger and better idiots. So far, the Universe is winning. (Rich Cook)
>
> "Nathan Sokalski" <njsokalski@.hotmail.com> schreef in bericht
> news:#$43EQwGGHA.2036@.TK2MSFTNGP14.phx.gbl...
> the
> seems
> produce
> to
>
>
Hi Nathan, I did some testing and when I tested your code I got the same res
ult as you posted but then I added,
mygraphic.SmoothingMode = Drawing2D.SmoothingMode.HighQuality and it gave a
better result but still not as it should be. Then I started looking at my ex
ample to see what was the difference, because my sample drawed every ellipse
OK, event those with width and height 5. I then noticed that I use g.clear(
Color.Black) so I added that to your code combined with mygraphic.SmoothingM
ode = Drawing2D.SmoothingMode.HighQuality and it produces a good ellipse. I
don't know why it behaves like this, but leaving out the mygraphic.Clear(Col
or.Black) or SmoothingMode.HighQuality part causes it to draw a faulty ellip
se. I can see why leaving out the SmoothingMode part would lower the quality
, but the mygraphic.Clear(Color.Black) has got me wondering why? Posted belo
w is your code with my addition which produces a good result on my pc.
Dim mybitmap As New Bitmap(10, 10)
Dim mygraphic As Graphics = Graphics.FromImage(mybitmap)
mygraphic.Clear(Color.Black)
mygraphic.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
mygraphic.DrawEllipse(New Pen(Color.HotPink, 1), 1, 1, 5, 5)
mybitmap.Save("c:\ellipse6.gif", Imaging.ImageFormat.Gif)
'Just to see if there's any difference between them both
mybitmap.Save("c:\ellipse6.bmp", Imaging.ImageFormat.Bmp)
I hope this helps you out.
Greetz Peter
--
Programming today is a race between software engineers striving to build big
ger and better idiot-proof programs, and the Universe trying to produce bigg
er and better idiots. So far, the Universe is winning. (Rich Cook)
"Nathan Sokalski" <njsokalski@.hotmail.com> schreef in bericht news:OHZ#x85GG
HA.608@.TK2MSFTNGP14.phx.gbl...
Take note that in your code you do not draw the circles using the DrawEllips
e method, you use a custom-written Sub, DrawCircles. Even though DrawCircles
uses DrawEllipse (or FillEllipse) and should have the same results as if yo
u called DrawEllipse directly, my results still do not work. Here is my code
and what I get:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.Event
Args) Handles MyBase.Load
Dim mybitmap As New Bitmap(10, 10)
Dim mygraphic As Graphics = Graphics.FromImage(mybitmap)
mygraphic.DrawEllipse(New Pen(Color.HotPink, 1), 1, 1, 5, 5)
mybitmap.Save(Server.MapPath("images/ellipse6.gif"), Imaging.ImageFormat.Gif
)
Image1.ImageUrl = "images/ellipse6.gif?timemade=" & Server.UrlEncode(Date.No
w.ToShortDateString() & Date.Now.ToLongTimeString())
End Sub
My code uses 5 rather than 6, I probably forgot to mention this in my previo
us postings since my application makes this adjustment automatically (sorry
for any confusion). But either way, it shouldn't be happening. What results
do you get when you enter 5 for the width/height parameters? Thanks.
--
Nathan Sokalski
njsokalski@.hotmail.com
http://www.nathansokalski.com/
"Peter Proost" <pproost@.nospam.hotmail.com> wrote in message news:uP0AHezGGHA.3896@.TK2MSFTN
GP15.phx.gbl...
> Here's the example again because it wasn't origanly posted in this thread
>
> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles Button1.Click
> Dim myBmp As New Bitmap(450, 450)
> Dim g As Graphics
> g = Graphics.FromImage(myBmp)
> g.Clear(Color.Black)
> g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
> Dim posX As Integer = 10
> Dim myWidth, myHeight As Integer
> myWidth = 4
> myHeight = 4
> For i As Integer = 0 To 21
> If i <= 10 Then
> drawCircles(g, 0, posX, myWidth, myHeight)
> Else
> drawCircles(g, 1, posX, myWidth, myHeight)
> End If
> posX += 20
> myWidth += 1
> myHeight += 1
> If i = 10 Then
> myWidth = 4
> myHeight = 4
> End If
> Next
> g.Dispose()
> PictureBox1.Image = myBmp
> myBmp.Save("c:\testEllipse.bmp", Drawing.Imaging.ImageFormat.Bmp)
> MsgBox("c:\testEllipse.bmp Saved", MsgBoxStyle.Information, "Saved")
>
>
> End Sub
>
> Private Sub drawCircles(ByVal g As Graphics, ByVal drawType As Integer,
> ByVal x As Integer, ByVal width As Integer, _ ByVal _ height As Integer)
> Dim intY As Integer = 5
> For i As Integer = 0 To 20
> Select Case drawType
> Case 0
> g.FillEllipse(Brushes.LawnGreen, x, intY, width, height
)
> Case 1
> g.DrawEllipse(Pens.LawnGreen, x, intY, width, height)
> End Select
> intY += 18
> Next
> End Sub
>
> Greetz Peter
> --
> Programming today is a race between software engineers striving to build
> bigger and better idiot-proof programs, and the Universe trying to produce
> bigger and better idiots. So far, the Universe is winning. (Rich Cook)
>
> "Nathan Sokalski" <njsokalski@.hotmail.com> schreef in bericht
> news:#$43EQwGGHA.2036@.TK2MSFTNGP14.phx.gbl...
> the
> seems
> produce
> to
>
>
Hi Nathan, I did some testing and when I tested your code I got the same res
ult as you posted but then I added,
mygraphic.SmoothingMode = Drawing2D.SmoothingMode.HighQuality and it gave a
better result but still not as it should be. Then I started looking at my ex
ample to see what was the difference, because my sample drawed every ellipse
OK, event those with width and height 5. I then noticed that I use g.clear(
Color.Black) so I added that to your code combined with mygraphic.SmoothingM
ode = Drawing2D.SmoothingMode.HighQuality and it produces a good ellipse. I
don't know why it behaves like this, but leaving out the mygraphic.Clear(Col
or.Black) or SmoothingMode.HighQuality part causes it to draw a faulty ellip
se. I can see why leaving out the SmoothingMode part would lower the quality
, but the mygraphic.Clear(Color.Black) has got me wondering why? Posted belo
w is your code with my addition which produces a good result on my pc.
Dim mybitmap As New Bitmap(10, 10)
Dim mygraphic As Graphics = Graphics.FromImage(mybitmap)
mygraphic.Clear(Color.Black)
mygraphic.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
mygraphic.DrawEllipse(New Pen(Color.HotPink, 1), 1, 1, 5, 5)
mybitmap.Save("c:\ellipse6.gif", Imaging.ImageFormat.Gif)
'Just to see if there's any difference between them both
mybitmap.Save("c:\ellipse6.bmp", Imaging.ImageFormat.Bmp)
I hope this helps you out.
Greetz Peter
--
Programming today is a race between software engineers striving to build big
ger and better idiot-proof programs, and the Universe trying to produce bigg
er and better idiots. So far, the Universe is winning. (Rich Cook)
"Nathan Sokalski" <njsokalski@.hotmail.com> schreef in bericht news:OHZ#x85GG
HA.608@.TK2MSFTNGP14.phx.gbl...
Take note that in your code you do not draw the circles using the DrawEllips
e method, you use a custom-written Sub, DrawCircles. Even though DrawCircles
uses DrawEllipse (or FillEllipse) and should have the same results as if yo
u called DrawEllipse directly, my results still do not work. Here is my code
and what I get:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.Event
Args) Handles MyBase.Load
Dim mybitmap As New Bitmap(10, 10)
Dim mygraphic As Graphics = Graphics.FromImage(mybitmap)
mygraphic.DrawEllipse(New Pen(Color.HotPink, 1), 1, 1, 5, 5)
mybitmap.Save(Server.MapPath("images/ellipse6.gif"), Imaging.ImageFormat.Gif
)
Image1.ImageUrl = "images/ellipse6.gif?timemade=" & Server.UrlEncode(Date.No
w.ToShortDateString() & Date.Now.ToLongTimeString())
End Sub
My code uses 5 rather than 6, I probably forgot to mention this in my previo
us postings since my application makes this adjustment automatically (sorry
for any confusion). But either way, it shouldn't be happening. What results
do you get when you enter 5 for the width/height parameters? Thanks.
--
Nathan Sokalski
njsokalski@.hotmail.com
http://www.nathansokalski.com/
"Peter Proost" <pproost@.nospam.hotmail.com> wrote in message news:uP0AHezGGHA.3896@.TK2MSFTN
GP15.phx.gbl...
> Here's the example again because it wasn't origanly posted in this thread
>
> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles Button1.Click
> Dim myBmp As New Bitmap(450, 450)
> Dim g As Graphics
> g = Graphics.FromImage(myBmp)
> g.Clear(Color.Black)
> g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
> Dim posX As Integer = 10
> Dim myWidth, myHeight As Integer
> myWidth = 4
> myHeight = 4
> For i As Integer = 0 To 21
> If i <= 10 Then
> drawCircles(g, 0, posX, myWidth, myHeight)
> Else
> drawCircles(g, 1, posX, myWidth, myHeight)
> End If
> posX += 20
> myWidth += 1
> myHeight += 1
> If i = 10 Then
> myWidth = 4
> myHeight = 4
> End If
> Next
> g.Dispose()
> PictureBox1.Image = myBmp
> myBmp.Save("c:\testEllipse.bmp", Drawing.Imaging.ImageFormat.Bmp)
> MsgBox("c:\testEllipse.bmp Saved", MsgBoxStyle.Information, "Saved")
>
>
> End Sub
>
> Private Sub drawCircles(ByVal g As Graphics, ByVal drawType As Integer,
> ByVal x As Integer, ByVal width As Integer, _ ByVal _ height As Integer)
> Dim intY As Integer = 5
> For i As Integer = 0 To 20
> Select Case drawType
> Case 0
> g.FillEllipse(Brushes.LawnGreen, x, intY, width, height
)
> Case 1
> g.DrawEllipse(Pens.LawnGreen, x, intY, width, height)
> End Select
> intY += 18
> Next
> End Sub
>
> Greetz Peter
> --
> Programming today is a race between software engineers striving to build
> bigger and better idiot-proof programs, and the Universe trying to produce
> bigger and better idiots. So far, the Universe is winning. (Rich Cook)
>
> "Nathan Sokalski" <njsokalski@.hotmail.com> schreef in bericht
> news:#$43EQwGGHA.2036@.TK2MSFTNGP14.phx.gbl...
> the
> seems
> produce
> to
>
>

0 comments:

Post a Comment