HighTechTalks DotNet Forums  

I believe there is something wrong with Matrix.RotateAt

Dotnet Framework (Drawing) microsoft.public.dotnet.framework.drawing


Discuss I believe there is something wrong with Matrix.RotateAt in the Dotnet Framework (Drawing) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
active
 
Posts: n/a

Default I believe there is something wrong with Matrix.RotateAt - 05-27-2007 , 09:29 PM






I believe there is something wrong with Matrix.RotateAt

The following example shows the problem.

Form needs a picture box and a context menu.

PictureBox1

ContextMenuStrip1

ToolStripMenuItemPlus20

ToolStripMenuItemMinus20

ToolStripMenuItemNewImage

When the image is rotated it loses the rightmost pixels



I'd be interested in your comments





Imports System.Drawing.Drawing2D

Public Class Form1

Private Const NumbOfPixels As Integer = 99

Private Sub Rotate(ByVal angle As Single)

Dim TmpBitmap As New Drawing.Bitmap(CInt(PictureBox1.Image.Width),
CInt(PictureBox1.Image.Height))

Dim TmpBitmapGraphics As Graphics = Graphics.FromImage(TmpBitmap)

Dim mx As Matrix = New Matrix()

mx.RotateAt(angle, New PointF(CSng((PictureBox1.Image.Width - 1) / 2),
CSng((PictureBox1.Image.Height - 1) / 2))) 'Rotates CW about the specified
point

TmpBitmapGraphics.Transform = mx

TmpBitmapGraphics.DrawImage(PictureBox1.Image, 0, 0,
PictureBox1.Image.Width, PictureBox1.Image.Height)

TmpBitmap.SetPixel(PictureBox1.Image.Width - 1, PictureBox1.Image.Height \
2, Color.Green)

TmpBitmapGraphics.Dispose()

PictureBox1.Image.Dispose()

PictureBox1.Image = TmpBitmap

End Sub

Private Sub ToolStripMenuItemPlus20_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles ToolStripMenuItemPlus20.Click

Rotate(90)

End Sub

Private Sub ToolStripMenuItemMinus20_Click(ByVal sender As Object, ByVal e
As System.EventArgs) Handles ToolStripMenuItemMinus20.Click

Rotate(-90)

End Sub

Private Sub ToolStripMenuItemNewImage_Click(ByVal sender As Object, ByVal e
As System.EventArgs) Handles ToolStripMenuItemNewImage.Click

If PictureBox1.Image IsNot Nothing Then PictureBox1.Image.Dispose()

PictureBox1.Image = New Bitmap(NumbOfPixels, NumbOfPixels)

Dim g As Graphics = Graphics.FromImage(PictureBox1.Image)

g.Clear(Color.Yellow)

g.DrawRectangle(New Pen(Color.Black, 1), 0, 0, NumbOfPixels - 1,
NumbOfPixels - 1) 'NumbOfPixels pixels wide rectangle even tho width and
height equal NumbOfPixels-1

g.DrawRectangle(New Pen(Color.Red, 1), 1, 1, NumbOfPixels - 3,
NumbOfPixels - 3)

g.Dispose()

End Sub

End Class



Reply With Quote
  #2  
Old   
Michael C
 
Posts: n/a

Default Re: I believe there is something wrong with Matrix.RotateAt - 05-27-2007 , 09:54 PM






" active" <activeNOSPAM (AT) a-znet (DOT) com> wrote

Quote:
mx.RotateAt(angle, New PointF(CSng((PictureBox1.Image.Width - 1) / 2),
CSng((PictureBox1.Image.Height - 1) / 2))) 'Rotates CW about the specified
point
Why are you subtracting 1?

Michael




Reply With Quote
  #3  
Old   
active
 
Posts: n/a

Default Re: I believe there is something wrong with Matrix.RotateAt - 05-28-2007 , 11:41 AM



Doesn't affect this problem. I tried it without first.

Just want to see if it changed anything.

I shouldn't have left it in.

I also tried different widths. 100 works the same as 99.

Thanks



"Michael C" <nospam (AT) nospam (DOT) com> wrote

Quote:
" active" <activeNOSPAM (AT) a-znet (DOT) com> wrote in message
news:%23BK6xeMoHHA.4424 (AT) TK2MSFTNGP03 (DOT) phx.gbl...
mx.RotateAt(angle, New PointF(CSng((PictureBox1.Image.Width - 1) / 2),
CSng((PictureBox1.Image.Height - 1) / 2))) 'Rotates CW about the
specified point

Why are you subtracting 1?

Michael




Reply With Quote
  #4  
Old   
Michael C
 
Posts: n/a

Default Re: I believe there is something wrong with Matrix.RotateAt - 05-28-2007 , 08:22 PM



" active" <activeNOSPAM (AT) a-znet (DOT) com> wrote

Quote:
Doesn't affect this problem. I tried it without first.

Just want to see if it changed anything.

I shouldn't have left it in.

I also tried different widths. 100 works the same as 99.
It worked perfectly on mine. For a 100x100 bitmap I need to rotate around
50,50. For a 101x101 bitmap I can rotate around 50.5,50.5 to get the correct
result. Try putting the PointF into a var and checking to make sure it has
the correct values.

Michael




Reply With Quote
  #5  
Old   
active
 
Posts: n/a

Default Re: I believe there is something wrong with Matrix.RotateAt - 05-28-2007 , 08:46 PM




"Michael C" <nospam (AT) nospam (DOT) com> wrote

Quote:
" active" <activeNOSPAM (AT) a-znet (DOT) com> wrote in message
news:OwloZ6ToHHA.5052 (AT) TK2MSFTNGP04 (DOT) phx.gbl...
Doesn't affect this problem. I tried it without first.

Just want to see if it changed anything.

I shouldn't have left it in.

I also tried different widths. 100 works the same as 99.

It worked perfectly on mine. For a 100x100 bitmap I need to rotate around
50,50. For a 101x101 bitmap I can rotate around 50.5,50.5 to get the
correct result. Try putting the PointF into a var and checking to make
sure it has the correct values.

Michael

Got this after I sent the copy of my display.
I used QuickWatch and PointF does have the values you mentioned above. Tried
both 100 ,101.

Did you notice that in the picture I sent you the black line on the right
side is missing?

When you say it worked perfectly, do you mean the right side has both the
red and the black lines?


Thanks




Reply With Quote
  #6  
Old   
Michael C
 
Posts: n/a

Default Re: I believe there is something wrong with Matrix.RotateAt - 05-28-2007 , 09:41 PM



" active" <activeNOSPAM (AT) a-znet (DOT) com> wrote

Quote:
mx.RotateAt(angle, New PointF(CSng((PictureBox1.Image.Width) / 2),
CSng((PictureBox1.Image.Height) / 2)))
I missed the problem the first few times I read this. First I should say
that using the extra set of brackets around Image.Width is unnecessary and
makes the code more confusing (it confused me for sure!). Anyway, the
problem is you are dividing by 2 and then converting to single. This will do
an integer divide, hence dropping the decimal part. Convert to width to
single first and then divide by 2.

Also, are you using PixelOffsetMode.Half?

Michael




Reply With Quote
  #7  
Old   
active
 
Posts: n/a

Default Re: I believe there is something wrong with Matrix.RotateAt - 05-29-2007 , 01:19 AM




"Michael C" <nospam (AT) nospam (DOT) com> wrote

Quote:
" active" <activeNOSPAM (AT) a-znet (DOT) com> wrote in message
news:OtPC4hYoHHA.2452 (AT) TK2MSFTNGP02 (DOT) phx.gbl...
mx.RotateAt(angle, New PointF(CSng((PictureBox1.Image.Width) / 2),
CSng((PictureBox1.Image.Height) / 2)))

I missed the problem the first few times I read this. First I should say
that using the extra set of brackets around Image.Width is unnecessary and
makes the code more confusing (it confused me for sure!). Anyway, the
problem is you are dividing by 2 and then converting to single. This will
do an integer divide, hence dropping the decimal part. Convert to width to
single first and then divide by 2.
You do C#, riight?
In VB we have "/" which results in a Double and "\" which does integer
devision.
The extra brackets are probably left over from when I tried subtracting 1.



Quote:
Also, are you using PixelOffsetMode.Half?
No I was not, and when I set it the problem went away.
Isn't it strange that it affected the right side but not the botton.
Since the example was completely simmetrical one might expect an operation
would not treat X any differently then Y.

Is PixelOffsetMode.Half something that I should use regulary?

What about SmoothingMode. Should I be setting this before operations like
"Rotate"


Thanks a lot for sticking throught this for me!
I really appreciate it.




Quote:
Michael




Reply With Quote
  #8  
Old   
Michael C
 
Posts: n/a

Default Re: I believe there is something wrong with Matrix.RotateAt - 05-29-2007 , 01:46 AM



" active" <activeNOSPAM (AT) a-znet (DOT) com> wrote

Quote:
You do C#, riight?
That's true although I came from Vb6.

Quote:
In VB we have "/" which results in a Double and "\" which does integer
devision.
That was true for VB6 but not for vb.net. In vb.net if both sides of the
division are integers then it will do an integer divide (hence it is
irrelevant whether you use / or \). If you try it with 11 and 2 the result
will be 5 when you really want 5.5.

Quote:
No I was not, and when I set it the problem went away.
Isn't it strange that it affected the right side but not the botton.
Since the example was completely simmetrical one might expect an operation
would not treat X any differently then Y.
Possibly a combination of PixelOffsetMode and rounding error?

Quote:
Is PixelOffsetMode.Half something that I should use regulary?
I'd have to go back through my code and check where I have and haven't used
it but I would say that it is something that should regularly be used for
painting bitmaps to the screen. I don't see any reason myself for not using
it.

Quote:
What about SmoothingMode. Should I be setting this before operations like
"Rotate"
This doesn't appear to apply to painting bitmaps.

Quote:
Thanks a lot for sticking throught this for me!
I really appreciate it.
No problems, I've learn a couple things myself. :-)

Michael




Reply With Quote
  #9  
Old   
active
 
Posts: n/a

Default Re: I believe there is something wrong with Matrix.RotateAt - 05-29-2007 , 02:09 PM




"Michael C" <nospam (AT) nospam (DOT) com> wrote

Quote:
" active" <activeNOSPAM (AT) a-znet (DOT) com> wrote in message
news:O$gL6DboHHA.1776 (AT) TK2MSFTNGP05 (DOT) phx.gbl...
You do C#, riight?

That's true although I came from Vb6.

In VB we have "/" which results in a Double and "\" which does integer
devision.

That was true for VB6 but not for vb.net. In vb.net if both sides of the
division are integers then it will do an integer divide (hence it is
irrelevant whether you use / or \). If you try it with 11 and 2 the result
will be 5 when you really want 5.5.

I believe
5 \ 2 will return type integer equal to 2 but

Dim n As Double = 5

Dim d As Double = 2

n / d will return a type double equal to 2.5

at least in VB.Net
========================

Just checked it out and the above is correct.
Dim a As Double = 5 \ 2 ' returns 2 but

Dim n As Double = 5

Dim d As Double = 2

Dim q As Double = n / d 'returns 2.5


also
Dim qq As Double = n \ d

If Option Strict is On will produce a compiler error since n and d are
converted to integers before the division.

I always have to look it up when it's important but if rounding vs.
truncation is important cint(), fix() and \ do not all behave it the same.


Thanks again for the help






Reply With Quote
  #10  
Old   
Michael C
 
Posts: n/a

Default Re: I believe there is something wrong with Matrix.RotateAt - 05-29-2007 , 07:10 PM



" active" <activeNOSPAM (AT) a-znet (DOT) com> wrote

Quote:
I believe
5 \ 2 will return type integer equal to 2 but

Dim n As Double = 5

Dim d As Double = 2

n / d will return a type double equal to 2.5
That's true but my point was if you try this

dim n as integer =5
dim d as integer = 2
n / d will return 2 as an integer.
this is the same result if you use n \ d which is interesting because it
means with option strict turned on there is no real use for the \.




Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.