Hello All,
I am attempting to learn a bit about the GDI+ transforms and charting data and I
feel like I'm getting a handle on how the transforms work. My chart object has a
large "canvas" bitmap that all data is scaled to and rendered on, and I display
a smaller "window" of the canvas that the user can page through left and right.
I've been able to scale my data (for the purposes of this discussion, x values
are 0 - 2PI and y values are -1 to 1; I'm charting Cosine) to the canvas bitmap
using the transforms applied to the graphics object and to a transformation
matrix, which I then useto transform the points and draw them on a graphics
object that has no transforms applied. I used both methods because I wanted to
learn how each works. So far, so good.
Next, I attempted to draw rectangles to highlight particular regions of
interest. This is where I get confused. I first worked with the transformed
graphics object and was able to get the rectangle to draw, but the values that I
had to use for its starting location do not make sense to me. Let me show the
transforms necessary to scale and fit my data to the canvas.
The canvas is 4096 x 100 pixels; the window is 512 x 100 pixels. Data is 0 - 2PI
for x values and -1 to 1 for y values. The transforms are as follows:
o Scale(1, -1) ; flip y coordinates
o Translate(0, -1) ; move ymin to origin
o Scale((4096/2PI), (100/(1 - -1)))
o Translate(0, 100)
This works out to be:
o Scale(1, -1)
o Translate(0, ymin)
o Scale((canvas_width/(xmax - xmmin)), (canvas_height/(ymax - ymin)))
o Translate(0, canvas_height)
I believe the first Translate call works because the ymin of -1 is first scaled
by -1 and becomes 1, 1 - 1 = 0 so we are back at the origin.
The crux of this is that I can draw rectangles using the graphics object that
has transforms applied to it, and it works as expected (i.e. if I want to draw a
rectangle that covers half of my window, I say:
FillRectangle(0, -1, PI/8.0, 2)
Two questions: How does the y-value of -1 work, because when you apply all of
the transforms, -1 = 100 (-1 * -1 = 1 -1 = 0 * (100/2.0) = 0 + 100 = 100). If
you were to attempt to fill a rectangle at location 0,100 with width of 256 and
height of 100 on a bitmap of size (512, 100), nothing would be displayed. Unless
I am misunderstanding how the transforms work, this call should not work, but it
does.
Why must the height of the rectangle be given as 2 (i.e. 1 - -1)
or ymax-ymin? If the other coordinates and measurements can be given in their
appropriate units, why must the height be different?
However, if I attempt to create the points and transform them with a
transformation matrix, the location of (0, -1) (i.e. xmin, ymin) does not work.
I must use *ymax* as the y-value of the location.
Is the transformed FillRectangle call (the one with the Cornsilk brush) doing
something strange to the coordinates? Does Matrix.TransformPoints call not work
properly?
I apologize that this is such a long post. If you need more info or my source
code, feel free to email me: jwbiagio at sbcglobal dot net.
Regards,
JBiagio
---------------------------------------
Here are the functions that I am using:
Public Function CreateMatrix(ByVal W As Single, ByVal H As Single, _
ByVal Xmin As Single, ByVal Xmax As Single, _
ByVal Ymin As Single, ByVal Ymax As Single) _
As Matrix
Dim m As New Matrix()
m.Translate(0, H) '4
m.Scale(W / (Xmax - Xmin), H / (Ymax - Ymin)) '3
m.Translate(-Xmin, Ymin) '1
m.Scale(1, -1) '2
'2134
Dim o(5) As Object
m.Elements.CopyTo(o, 0)
Console.WriteLine("{0}, {1}, {2}, {3}, {4}, {5}", o)
Return m
End Function
Protected Sub DrawCanvas()
'points range x: 0 - 2PI, y: -1 - 1
Dim g As Graphics = Graphics.FromImage(canvas)
'move the negative y-coord up one (1)
g.TranslateTransform(0, -1, MatrixOrder.Prepend)
g.ScaleTransform(1, -1, MatrixOrder.Prepend) 'flip y coordinate (2)
'append because we want to move before we scale (3)
g.ScaleTransform(4096 / (Math.PI * 2.0), 50, MatrixOrder.Append)
'move negative y coord up (i.e. 1 * -1 = -1 + -1 = -2 * (100/2.0) = -100) (4)
g.TranslateTransform(0, 100, MatrixOrder.Append)
'2134
Dim pt() As PointF = GeneratePoints()
Dim m As Matrix = CreateMatrix(4096, 100, 0, 2 * Math.PI, -1, 1)
m.TransformPoints(pt)
'g.TransformPoints(CoordinateSpace.Page, CoordinateSpace.World, pt)
Dim r As New RectangleF(0, -1, CSng(Math.PI / 8.0), 2)
'Draw rectangle with transformed graphics object
g.FillRectangle(Brushes.Cornsilk, r)
g.ResetTransform()
'set up a location that will be next to the rectangle drawn by the
'transformed graphics object
Dim pt3() As PointF = {New PointF(CSng(Math.PI / 8.0), 1)}
m.TransformPoints(pt3)
'note that height and width are in page coordinates because the graphics
'object is no longer transformed
g.FillRectangle(Brushes.Indigo, pt3(0).X, pt3(0).Y, 256, 100)
Dim p As New Pen(Color.Black, 1.0)
g.DrawLines(p, pt)
p.Dispose()
g.Dispose()
End Sub
Protected Function GeneratePoints() As PointF()
'This function will generate 20,000 points for Cosine(10x) from 0-2pi.
Dim pt(19999) As PointF
Dim i As Integer
Dim d As Double
For i = 0 To 19999
d = (i / 19999.0) * 2 * Math.PI
pt(i) = New PointF(d, Math.Cos(10 * d))
Next
Return pt
End Function
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
'This is a cobbled-together test. I need to create a much-larger bitmap and
'then scale some dummy data to it.
'Then the paint method will get a "slice" of the canvas bitmap and draw it
'on the form.
Dim bmp As Bitmap = canvas.Clone(New Rectangle(position * 512, 0, 512, 100), _
Imaging.PixelFormat.DontCare)
Dim font As New Font("Arial Bold", 13)
e.Graphics.DrawString(position.ToString, font, Brushes.Blue, 10, 10)
e.Graphics.DrawImageUnscaled(bmp, 50, 50)
End Sub 2 3328 http://www.vbdotnetheaven.com/
JBiagio wrote: Hello All,
I am attempting to learn a bit about the GDI+ transforms and charting data and I feel like I'm getting a handle on how the transforms work. My chart object has a large "canvas" bitmap that all data is scaled to and rendered on, and I display a smaller "window" of the canvas that the user can page through left and right.
I've been able to scale my data (for the purposes of this discussion, x values are 0 - 2PI and y values are -1 to 1; I'm charting Cosine) to the canvas bitmap using the transforms applied to the graphics object and to a transformation matrix, which I then useto transform the points and draw them on a graphics object that has no transforms applied. I used both methods because I wanted to learn how each works. So far, so good.
Next, I attempted to draw rectangles to highlight particular regions of interest. This is where I get confused. I first worked with the transformed graphics object and was able to get the rectangle to draw, but the values that I had to use for its starting location do not make sense to me. Let me show the transforms necessary to scale and fit my data to the canvas.
The canvas is 4096 x 100 pixels; the window is 512 x 100 pixels. Data is 0 - 2PI for x values and -1 to 1 for y values. The transforms are as follows:
o Scale(1, -1) ; flip y coordinates o Translate(0, -1) ; move ymin to origin o Scale((4096/2PI), (100/(1 - -1))) o Translate(0, 100)
This works out to be:
o Scale(1, -1) o Translate(0, ymin) o Scale((canvas_width/(xmax - xmmin)), (canvas_height/(ymax - ymin))) o Translate(0, canvas_height)
I believe the first Translate call works because the ymin of -1 is first scaled by -1 and becomes 1, 1 - 1 = 0 so we are back at the origin.
The crux of this is that I can draw rectangles using the graphics object that has transforms applied to it, and it works as expected (i.e. if I want to draw a rectangle that covers half of my window, I say: FillRectangle(0, -1, PI/8.0, 2)
Two questions: How does the y-value of -1 work, because when you apply all of the transforms, -1 = 100 (-1 * -1 = 1 -1 = 0 * (100/2.0) = 0 + 100 = 100). If you were to attempt to fill a rectangle at location 0,100 with width of 256 and height of 100 on a bitmap of size (512, 100), nothing would be displayed. Unless I am misunderstanding how the transforms work, this call should not work, but it does.
Why must the height of the rectangle be given as 2 (i.e. 1 - -1) or ymax-ymin? If the other coordinates and measurements can be given in their appropriate units, why must the height be different?
However, if I attempt to create the points and transform them with a transformation matrix, the location of (0, -1) (i.e. xmin, ymin) does not work. I must use *ymax* as the y-value of the location.
Is the transformed FillRectangle call (the one with the Cornsilk brush) doing something strange to the coordinates? Does Matrix.TransformPoints call not work properly?
I apologize that this is such a long post. If you need more info or my source code, feel free to email me: jwbiagio at sbcglobal dot net.
Regards, JBiagio
--------------------------------------- Here are the functions that I am using:
Public Function CreateMatrix(ByVal W As Single, ByVal H As Single, _ ByVal Xmin As Single, ByVal Xmax As Single, _ ByVal Ymin As Single, ByVal Ymax As Single) _ As Matrix Dim m As New Matrix() m.Translate(0, H) '4 m.Scale(W / (Xmax - Xmin), H / (Ymax - Ymin)) '3 m.Translate(-Xmin, Ymin) '1 m.Scale(1, -1) '2 '2134 Dim o(5) As Object m.Elements.CopyTo(o, 0) Console.WriteLine("{0}, {1}, {2}, {3}, {4}, {5}", o) Return m End Function
Protected Sub DrawCanvas()
'points range x: 0 - 2PI, y: -1 - 1 Dim g As Graphics = Graphics.FromImage(canvas)
'move the negative y-coord up one (1) g.TranslateTransform(0, -1, MatrixOrder.Prepend) g.ScaleTransform(1, -1, MatrixOrder.Prepend) 'flip y coordinate (2) 'append because we want to move before we scale (3) g.ScaleTransform(4096 / (Math.PI * 2.0), 50, MatrixOrder.Append)
'move negative y coord up (i.e. 1 * -1 = -1 + -1 = -2 * (100/2.0) = -100) (4) g.TranslateTransform(0, 100, MatrixOrder.Append) '2134 Dim pt() As PointF = GeneratePoints() Dim m As Matrix = CreateMatrix(4096, 100, 0, 2 * Math.PI, -1, 1) m.TransformPoints(pt) 'g.TransformPoints(CoordinateSpace.Page, CoordinateSpace.World, pt)
Dim r As New RectangleF(0, -1, CSng(Math.PI / 8.0), 2)
'Draw rectangle with transformed graphics object g.FillRectangle(Brushes.Cornsilk, r)
g.ResetTransform()
'set up a location that will be next to the rectangle drawn by the 'transformed graphics object Dim pt3() As PointF = {New PointF(CSng(Math.PI / 8.0), 1)} m.TransformPoints(pt3)
'note that height and width are in page coordinates because the graphics 'object is no longer transformed g.FillRectangle(Brushes.Indigo, pt3(0).X, pt3(0).Y, 256, 100)
Dim p As New Pen(Color.Black, 1.0)
g.DrawLines(p, pt)
p.Dispose() g.Dispose()
End Sub
Protected Function GeneratePoints() As PointF() 'This function will generate 20,000 points for Cosine(10x) from 0-2pi. Dim pt(19999) As PointF Dim i As Integer Dim d As Double
For i = 0 To 19999 d = (i / 19999.0) * 2 * Math.PI pt(i) = New PointF(d, Math.Cos(10 * d)) Next
Return pt End Function
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) 'This is a cobbled-together test. I need to create a much-larger bitmap and 'then scale some dummy data to it.
'Then the paint method will get a "slice" of the canvas bitmap and draw it 'on the form.
Dim bmp As Bitmap = canvas.Clone(New Rectangle(position * 512, 0, 512, 100), _ Imaging.PixelFormat.DontCare)
Dim font As New Font("Arial Bold", 13)
e.Graphics.DrawString(position.ToString, font, Brushes.Blue, 10, 10)
e.Graphics.DrawImageUnscaled(bmp, 50, 50) End Sub
JBiagio,
Did you know you have the most change on an answer for your question in the
newsgroup.
microsoft.public.dotnet.framework.drawing
with probably as second best
microsoft.public.dotnet.languages.vb
You can also crosspost it to those newsgroups, (sending one message to both
newsgroups at once). However in this case I would first try it with a single
post to the first.
And as advice do make a snippet of your problem. It is very rare in this
newsgroups that questions with so much code are answered.
I hope this helps?
Cor This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: John Bailo |
last post by:
I am walking through some of the very first sample code from the book
"Beginning .NET Game Programming" from Apress. I identify his sample
code with //SC
This code puzzles me:
Graphics graph...
|
by: JBiagio |
last post by:
Hello All,
I am attempting to learn a bit about the GDI+ transforms and charting data and I
feel like I'm getting a handle on how the transforms work. My chart object has a
large "canvas" bitmap...
|
by: matko |
last post by:
When I call the following function, the rectangle will overlap the
graphics that is drawn _afterwards_. Why is that? How can I make sure
my graphics is drawn in correct order?
(Note: If I...
|
by: rushikesh.joshi |
last post by:
Hi All,
I want to create a webcontrol which will generate a bar (bar chart). I
have done some graphics code in my ASPX page and it's working fine, but
how do i create a Custom Control or User...
|
by: rushikesh.joshi |
last post by:
Hi All,
I want some charting functionality in my ASP.NET application.
I want to show a multiple bar on my web page. It's based on down time
of different servers.
like
server1: down betn 4 AM...
|
by: Mark Ingram |
last post by:
Hi, I would like to know which is the faster method to call,
FillRectangle or FillPath.
I have a path which is essentially a square, except for rounded corners,
so I can end up with 2 almost...
|
by: gopal28 |
last post by:
HI I am using the Graphics to paint to a a picture box but if i minimise my screen the picture disappears is there anyway i can fix this?? Please Help!! here is my code:
PLease Help me it will be...
|
by: =?Utf-8?B?QW5kcmV3?= |
last post by:
Email Question:
When I send an email (basically a sms to a phone) from ms outlook it works
fine. When I try to send it pragmatically I get an error stating that it
can’t relay for <the email...
|
by: =?Utf-8?B?QW5kcmV3?= |
last post by:
I have a borderless form that has a transparent background. I only wanted
the color that I painted the background with to be transparent and not the
controls on the form or the box I draw in the...
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome former...
|
by: ryjfgjl |
last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
| |