Related
I have two fits images from the WFC3 that I am trying to combine with a C# program. When I try to combine multiple images I don't think the values I am getting for my x/y coordinates (calculated from Right Ascension/Declination) are correct. I am expecting a final image that is about the same width as the two images combined, but it turns out to be about the same width and about twice the height. I know the final image should be about double the width of a single image because I manually combined the images in photoshop and the final image was about twice as wide as either of the two original images.
NOTE: when I say "image" they are fits images, so they are just a bunch of single values in a file, so to combine them I create a new file and initialize the correct number of single values (width * height) to zero, and then fill in the values from the images I am using to combine. They are not jpg or tif or png.
I am using the following formula to change from world coordinate system to cartesian:
formula is (since distance is the same for everything):
x = cos(dec) * cos(ra)
y = cos(dec) * sin(ra)
I get the right ascension and declination from the header in the fits file.
For the final image dimensions, I calculate the distance between x1 and x2 and create a new image that is 1/2 image 1 width + distance + 1/2 image 2 width. For the final height I do a similar calculation with y and image heights.
The images do also have a rotational component, but I am ignoring that as both images share the same rotation. This could be part of my problem.
public const double PixelsPerArcSecond = .039; // per WFC3 spec from Nasa
public static ImageDataModel Combine(List<ImageDataModel> inputImages)
{
// Right ascension is CRVAL1
// Declination is CRVAL2
// formula is (since distance is the same for everything):
// x = cos(dec) * cos(ra)
// y = cos(dec) * sin(ra)
ImageDataModel returnImage = new ImageDataModel();
ImageDataModel bm = inputImages[0];
double x1, y1, x2, y2;
x1 = Math.Cos(bm.CRVAL2) * Math.Cos(bm.CRVAL1);
y1 = Math.Cos(bm.CRVAL2) * Math.Sin(bm.CRVAL1);
int mult = 4; // todo: set this based off of the bitpix of the incoming images.
for (int i = 1; i < inputImages.Count; i++)
{
ImageDataModel cm = inputImages[i];
x2 = Math.Cos(cm.CRVAL2) * Math.Cos(cm.CRVAL1);
y2 = Math.Cos(cm.CRVAL2) * Math.Sin(cm.CRVAL1);
double dx = x1 - x2;
double dy = y1 - y2;
int distX = (int)((dx * 3600) / PixelsPerArcSecond);
int distY = (int)((dy * 3600) / PixelsPerArcSecond);
// This is what I expect to be wider than tall, but the converse is true.
int w = Math.Abs(distX) + (bm.ImageWidth / 2) + (cm.ImageWidth / 2);
int h = Math.Abs(distY) + (bm.ImageHeight / 2) + (cm.ImageHeight / 2);
// This is where the two images are combined into the final image.
ImageDataModel imd = CombineTwoImages(bm, cm, i, w, h, mult);
bm = imd;
}
return returnImage;
}
I am expecting an image that turns out like this:
http://wierdling.net/stack-overflow-images/ManuallyCombined.png
But getting this:
http://wierdling.net/stack-overflow-images/CombinedTest.png
The stats for the first image are: Width = 4139, Height = 4535, RA = 350.1584456860353 (CRVAL1), DEC = 61.16155335032816 (CRVAL2), ORIENTAT = -125
The stats for the second image are:Width = 4139, Height = 4535, RA = 350.1159150008405 (CRVAL1), DEC = 61.19543100394401 (CRVAL2), ORIENTAT = -125
The final expected width is close to 7733 with a height near 4773.
The final actual width is 4284, and the height is 7662.
Does anyone have any insight into what I am doing wrong?
The full source code for the program can be downloaded from https://bitbucket.org/wierdling/fitscombiner/src/master/
It currently only works with WFC3 data, and the program is very much a work in progress.
I think that your image program already does the rotation and you should do it too.
If I rotate the coordinates you calculated by 125 degrees and then calculate how far away the coordinate x1 is from the left side and the same for x2 and the y coordiantes I get a width of 6725 and height of 6166.
Not perfect but I think it goes in the right direction.
Hope that helped.
public static ImageDataModel Combine(List<ImageDataModel> inputImages)
{
// Right ascension is CRVAL1
// Declination is CRVAL2
// formula is (since distance is the same for everything):
// x = cos(dec) * cos(ra)
// y = cos(dec) * sin(ra)
ImageDataModel returnImage = new ImageDataModel();
ImageDataModel bm = inputImages[0];
double x1, y1, x2, y2;
x1 = Math.Cos(bm.CRVAL2) * Math.Cos(bm.CRVAL1);
y1 = Math.Cos(bm.CRVAL2) * Math.Sin(bm.CRVAL1);
var values = Rotate(0 - bm.Orientation, x1, y1);
x1 = values.x;
y1 = values.y;
int mult = 4; // todo: set this based off of the bitpix of the incoming images.
for (int i = 1; i < inputImages.Count; i++)
{
ImageDataModel cm = inputImages[i];
x2 = Math.Cos(cm.CRVAL2) * Math.Cos(cm.CRVAL1);
y2 = Math.Cos(cm.CRVAL2) * Math.Sin(cm.CRVAL1);
var values2 = Rotate(0 - bm.Orientation, x2, y2);
x2 = values2.x;
y2 = values2.y;
double dx = x1 - x2;
double dy = y1 - y2;
int distX = (int)((dx * 3600) / PixelsPerArcSecond);
int distY = (int)((dy * 3600) / PixelsPerArcSecond);
double width = (1.0 + x1) * (bm.ImageWidth / 2) + (1.0 - x2) * (cm.ImageWidth / 2) + Math.Abs(distX);
double height = (1.0 + y1) * (bm.ImageHeight / 2) + (1.0 - y2) * (cm.ImageHeight / 2) + Math.Abs(distY);
// This is what I expect to be wider than tall, but the converse is true.
int w = Math.Abs(distX) + (bm.ImageWidth / 2) + (cm.ImageWidth / 2);
int h = Math.Abs(distY) + (bm.ImageHeight / 2) + (cm.ImageHeight / 2);
// This is where the two images are combined into the final image.
ImageDataModel imd = CombineTwoImages(bm, cm, i, w, h, mult);
bm = imd;
}
return returnImage;
}
private static (double x, double y) Rotate(int angle, double x, double y)
{
double rad = Math.PI * angle / 180.0;
return (x * Math.Cos(rad) - y * Math.Sin(rad), x * Math.Sin(rad) + y * Math.Cos(rad));
}
I have next task - draw ellipe trough 3 points (like in the picture).
.
User can drag theese points that to change ellipse size. Two of points placed on edges of great axis. In my solution I use GDI throug Graphics class.
Now my solution is calculate rectangle corresponding to an ellipse and use
DrawEllipse method and rotate transform (if it's need). But this solution has many mathematical calculation. Maybe there is the simplest approach to solve this task?
Here is how to use the DrawEllipse method from a rotation, the minor axis and two vertices.
First we calculate the Size of the bounding Rectangle:
Given the Points A and B sitting on the short sides of length smallSize we get the long side with a little Pythagoras:
int longSide = (int)(Math.Sqrt((A.Y - B.Y) * (A.Y - B.Y) + (B.X - A.X) * (B.X - A.X)));
So :
Size size = new System.Drawing.Size(longSide, smallSize);
Next we need the rotation angle:
float angle = -(float)(Math.Atan2(A.Y - B.Y, B.X - A.X) * 180f / Math.PI);
And it will make things easier to also get the center Point C:
Point C = new Point((A.X + B.X)/ 2, (A.Y + B.Y)/ 2);
The last thing we want is a routine that draws an ellipse of a given Size, rotated around C at an angle:
void DrawEllipse(Graphics G, Pen pen, Point center, Size size, float angle)
{
int h2 = size.Height / 2;
int w2 = size.Width / 2;
Rectangle rect = new Rectangle( new Point(center.X - w2, center.Y - h2), size );
G.TranslateTransform(center.X, center.Y);
G.RotateTransform(angle);
G.TranslateTransform(-center.X, -center.Y);
G.DrawEllipse(pen, rect);
G.ResetTransform();
}
[![enter image description here][1]][1]
Here is a little testbed that brings it all together:
Point A = new Point(200, 200); // *
Point B = new Point(500, 250);
int smallSize = 50;
void doTheDraw(PictureBox pb)
{
Bitmap bmp = new Bitmap(pb.Width, pb.Height);
float angle = -(float)(Math.Atan2(A.Y - B.Y, B.X - A.X) * 180f / Math.PI);
int longSide = (int)(Math.Sqrt((A.Y - B.Y) * (A.Y - B.Y) + (B.X - A.X) * (B.X - A.X)));
Point C = new Point((A.X + B.X) / 2, (A.Y + B.Y) / 2);
Size size = new System.Drawing.Size((int)longSide, smallSize);
using (Pen pen = new Pen(Color.Orange, 3f))
using (Graphics g = Graphics.FromImage(bmp))
{
// a nice background grid (optional):
DrawGrid(g, 0, 0, 100, 50, 10,
Color.LightSlateGray, Color.DarkGray, Color.Gainsboro);
// show the points we use (optional):
g.FillEllipse(Brushes.Red, A.X - 4, A.Y - 4, 8, 8);
g.FillRectangle(Brushes.Red, B.X - 3, B.Y - 3, 7, 7);
g.FillEllipse(Brushes.Red, C.X - 5, C.Y - 5, 11, 11);
// show the connection line (optional):
g.DrawLine(Pens.Orange, A, B);
// here comes the ellipse:
DrawEllipse(g, pen, C, size, angle);
}
pb.Image = bmp;
}
The grid is a nice helper:
void DrawGrid(Graphics G, int ox, int oy,
int major, int medium, int minor, Color c1, Color c2, Color c3)
{
using (Pen pen1 = new Pen(c1, 1f))
using (Pen pen2 = new Pen(c2, 1f))
using (Pen pen3 = new Pen(c3, 1f))
{
pen2.DashStyle = DashStyle.Dash;
pen3.DashStyle = DashStyle.Dot;
for (int x = ox; x < G.VisibleClipBounds.Width; x += major)
G.DrawLine(pen1, x, 0, x, G.VisibleClipBounds.Height);
for (int y = oy; y < G.VisibleClipBounds.Height; y += major)
G.DrawLine(pen1, 0, y, G.VisibleClipBounds.Width, y);
for (int x = ox; x < G.VisibleClipBounds.Width; x += medium)
G.DrawLine(pen2, x, 0, x, G.VisibleClipBounds.Height);
for (int y = oy; y < G.VisibleClipBounds.Height; y += medium)
G.DrawLine(pen2, 0, y, G.VisibleClipBounds.Width, y);
for (int x = ox; x < G.VisibleClipBounds.Width; x += minor)
G.DrawLine(pen3, x, 0, x, G.VisibleClipBounds.Height);
for (int y = oy; y < G.VisibleClipBounds.Height; y += minor)
G.DrawLine(pen3, 0, y, G.VisibleClipBounds.Width, y);
}
}
Note that I made A, B, smallSide class level variables so I can modify them during my tests, (and I did *)..
As you can see I have added a TrackBar to make the smallside dynamic; for even more fun I have added this MouseClick event:
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button.HasFlag(MouseButtons.Left)) A = e.Location;
else B = e.Location;
doTheDraw(pictureBox1);
}
I hope some of my logic can help you out on what you're trying to achieve. Next question you make try to add more info and be less generic.
Compute the similarity transform (translation and rotation) that brings the first two points to (-a, 0) and (a, 0). [This can be done with a matrix transform or complex numbers.]
Apply the same transform to the third point. Now the equation of the reduced ellipse is
x² / a² + y² / b² = 1.
You simply determine the parameter b by plugging the reduced coordinates of the third point,
b = y / √(1 - x²/a²).
Now you have
the center,
the orientation of the axis,
the length of the major axis,
the length of the minor axis.
I have a C# bitmap object, and i am able to draw a line from point A to point B.
I have the 2 points on the edges of the diagram, and I would like to draw an ellipse from A to B. The basic g.DrawEllipse() only draws ellipses either perfectly horizontally or vertically, however I need the ellipse to be kind of diagonal from the one end of the image to the other.
My bitmap: 200 tall by 500 wide
Point A: Column 0, Row 20 (0,20)
Point B: Column 499, Row 60 (499, 60)
Widest Point: 30 - Narrow Radius of the ellipse
Here is what I have so far, the draw ellipse doesnt have the overload I need, so help there please:
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawLine(pen, new Point(20,0), new Point(499,60));
g.DrawEllipse(pen, 20, 0, someWidth, someHeight);
}
Here is how to use the DrawEllipse method from a rotation, the minor axis and two vertices.
First we calculate the Size of the bounding Rectangle:
Given the Points A and B sitting on the short sides of length smallSize we get the long side with a little Pythagoras:
int longSide = (int)(Math.Sqrt((A.Y - B.Y) * (A.Y - B.Y) + (B.X - A.X) * (B.X - A.X)));
So :
Size size = new System.Drawing.Size(longSide, smallSize);
Next we need the rotation angle:
float angle = -(float)(Math.Atan2(A.Y - B.Y, B.X - A.X) * 180f / Math.PI);
And it will make things easier to also get the center Point C:
Point C = new Point((A.X + B.X)/ 2, (A.Y + B.Y)/ 2);
The last thing we want is a routine that draws an ellipse of a given Size, rotated around C at an angle:
void DrawEllipse(Graphics G, Pen pen, Point center, Size size, float angle)
{
int h2 = size.Height / 2;
int w2 = size.Width / 2;
Rectangle rect = new Rectangle( new Point(center.X - w2, center.Y - h2), size );
G.TranslateTransform(center.X, center.Y);
G.RotateTransform(angle);
G.TranslateTransform(-center.X, -center.Y);
G.DrawEllipse(pen, rect);
G.ResetTransform();
}
Here is a little testbed that brings it all together:
Point A = new Point(200, 200); // *
Point B = new Point(500, 250);
int smallSize = 50;
void doTheDraw(PictureBox pb)
{
Bitmap bmp = new Bitmap(pb.Width, pb.Height);
float angle = -(float)(Math.Atan2(A.Y - B.Y, B.X - A.X) * 180f / Math.PI);
int longSide = (int)(Math.Sqrt((A.Y - B.Y) * (A.Y - B.Y) + (B.X - A.X) * (B.X - A.X)));
Point C = new Point((A.X + B.X) / 2, (A.Y + B.Y) / 2);
Size size = new System.Drawing.Size((int)longSide, smallSize);
using (Pen pen = new Pen(Color.Orange, 3f))
using (Graphics g = Graphics.FromImage(bmp))
{
// a nice background grid (optional):
DrawGrid(g, 0, 0, 100, 50, 10,
Color.LightSlateGray, Color.DarkGray, Color.Gainsboro);
// show the points we use (optional):
g.FillEllipse(Brushes.Red, A.X - 4, A.Y - 4, 8, 8);
g.FillRectangle(Brushes.Red, B.X - 3, B.Y - 3, 7, 7);
g.FillEllipse(Brushes.Red, C.X - 5, C.Y - 5, 11, 11);
// show the connection line (optional):
g.DrawLine(Pens.Orange, A, B);
// here comes the ellipse:
DrawEllipse(g, pen, C, size, angle);
}
pb.Image = bmp;
}
The grid is a nice helper:
void DrawGrid(Graphics G, int ox, int oy,
int major, int medium, int minor, Color c1, Color c2, Color c3)
{
using (Pen pen1 = new Pen(c1, 1f))
using (Pen pen2 = new Pen(c2, 1f))
using (Pen pen3 = new Pen(c3, 1f))
{
pen2.DashStyle = DashStyle.Dash;
pen3.DashStyle = DashStyle.Dot;
for (int x = ox; x < G.VisibleClipBounds.Width; x += major)
G.DrawLine(pen1, x, 0, x, G.VisibleClipBounds.Height);
for (int y = oy; y < G.VisibleClipBounds.Height; y += major)
G.DrawLine(pen1, 0, y, G.VisibleClipBounds.Width, y);
for (int x = ox; x < G.VisibleClipBounds.Width; x += medium)
G.DrawLine(pen2, x, 0, x, G.VisibleClipBounds.Height);
for (int y = oy; y < G.VisibleClipBounds.Height; y += medium)
G.DrawLine(pen2, 0, y, G.VisibleClipBounds.Width, y);
for (int x = ox; x < G.VisibleClipBounds.Width; x += minor)
G.DrawLine(pen3, x, 0, x, G.VisibleClipBounds.Height);
for (int y = oy; y < G.VisibleClipBounds.Height; y += minor)
G.DrawLine(pen3, 0, y, G.VisibleClipBounds.Width, y);
}
}
Note that I made A, B, smallSide class level variables so I can modify them during my tests, (and I did *)..
As you can see I have added a TrackBar to make the smallside dynamic; for even more fun I have added this MouseClick event:
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button.HasFlag(MouseButtons.Left)) A = e.Location;
else B = e.Location;
doTheDraw(pictureBox1);
}
Note that I didn't care for disposing of the old Bitmap; you should, of course..!
If you wish to use Graphics to create a diagonal ellipse, perhaps you can use DrawBezier() method.
Here is some code that does it:
// Draws an ellipse using 2 beziers.
private void DrawEllipse(Graphics g, PointF center, float width, float height, double rotation)
{
// Unrotated ellipse frame
float left = center.X - width / 2;
float right = center.X + width / 2;
float top = center.Y - height / 2;
float bottom = center.Y + height / 2;
PointF p1 = new PointF(left, center.Y);
PointF p2 = new PointF(left, top);
PointF p3 = new PointF(right, top);
PointF p4 = new PointF(right, center.Y);
PointF p5 = new PointF(right, bottom);
PointF p6 = new PointF(left, bottom);
// Draw ellipse with rotated points.
g.DrawBezier(Pens.Black, Rotate(p1, center, rotation), Rotate(p2, center, rotation), Rotate(p3, center, rotation), Rotate(p4, center, rotation));
g.DrawBezier(Pens.Black, Rotate(p4, center, rotation), Rotate(p5, center, rotation), Rotate(p6, center, rotation), Rotate(p1, center, rotation));
}
// Rotating a given point by given angel around a given pivot.
private PointF Rotate(PointF point, PointF pivot, double angle)
{
float x = point.X - pivot.X;
float y = point.Y - pivot.Y;
double a = Math.Atan(y / x);
if (x < 0)
{
a += Math.PI;
}
float size = (float)Math.Sqrt(x * x + y * y);
double newAngel = a + angle;
float newX = ((float)Math.Cos(newAngel) * size);
float newY = ((float)Math.Sin(newAngel) * size);
return pivot + new SizeF(newX, newY);
}
The above code computes the frame of the ellipse (proir to the rotation) at points p1, p2, ..., p6. And then, draws the ellipse as 2 beziers with the ellipse frame rotated points.
i i am relative new to c# and is trying to draw a curved line in c#. I would like to ask that is there any possible way to create an X and Y axis in order to show the coordinates of each point of the curved line.
Please do help me on this matter as i am stuck on how to execute it.
protected override void OnPaint(PaintEventArgs e)
{
float a = 1, b = 5, c = 1;
double x1, x2, x3,x4,x5,x6, y1, y2, y3,y4,y5, delta;
delta = (b * b) - (4 * a * c);
x1=0;
y1 = a * (x1 * x1) + (b * (x1)) + c;
x2 = 3;
y2 = a * (x2 * x2) + (b * (x2)) + c;
x3 = - 3;
y3 = a * (x3 * x3) + (b * (x3)) + c;
x4 = 5;
y4 = a * (x4 * x4) + (b * (x4)) + c;
x5 = -10;
y5 = a * (x5 * x5) + (b * (x5)) + c;
int cx1 = Convert.ToInt32(x1);
int cx2 = Convert.ToInt32(x2);
int cx3 = Convert.ToInt32(x3);
int cy1 = Convert.ToInt32(y1);
int cy2 = Convert.ToInt32(y2);
int cy3 = Convert.ToInt32(y3);
int cx4 = Convert.ToInt32(x4);
int cy4 = Convert.ToInt32(y4);
int cx5 = Convert.ToInt32(x5);
int cy5 = Convert.ToInt32(y5);
Graphics g = e.Graphics;
int deltaX = 100;
int deltaY = 100;
g.TranslateTransform(deltaX, deltaY);
float factor = 2.5f;
Matrix m = new Matrix();
m.Scale(factor, factor);
g.MultiplyTransform(m);
Pen aPen = new Pen(Color.Blue, 1);
Point point1 = new Point(cx1, cy1);
Point point2 = new Point(cx2, cy2);
Point point3 = new Point(cx3, cy3);
Point point4 = new Point(cx4, cy4);
Point point5 = new Point(cx5, cy5);
Point[] Points = { point5, point3, point1,point2,point4 };
g.DrawCurve(aPen, Points);
Maybe I misunderstand you, but it sounds like you want to make your GDI+ graphics scale with the window size (i.e. you want to scale the X and Y axis with the size of the window), right?
This is pretty simple, you just have to decide how big of a space you want to present in the window -- i.e. if you want to make the axis go from 0,0 on the top left, to 512x512 on the bottom right, then you would just need to scale the X axis by a factor of 512/width, and the Y axis by a factor of 512/height.
So you would do that by performing a ScaleTransform on your Graphics object. You'll need to use your Form's ClientSize to get the width and height. (The regular Form's .Width, and .Height properties, include all the borders and title bars, padding pixels, etc. -- so it's no good for this calculation.)
Then you will need to force an Invalidation during the form's Resize event (it will work without this, when you make the window smaller, but when you make it bigger, this will be required, or else it will only redraw the edges).
Another thing worth considering is turning on the form's DoubleBuffered property, the redraw will be much smoother.
So, let's assume you want to work in a virtual space of 512x512 "pixels" where 0 ,0 is always the top left, and 512,512 is the bottom right. You could add this code to the top of your OnPaint event handler:
float scaleX = 512f / ((float)this.ClientSize.Width);
float scaleY = 512f / ((float)this.ClientSize.Height);
e.Graphics.ScaleTransform(scaleX, scaleY);
Then add a handler for the Form's Resize event and add something like this:
this.Invalidate(true);
That should do the trick.
I am scratching my head to figure out a way to scale a signal on a 2D graphic pane. The story is: I connect my application to a microcontroller and on fixed intervals I read a data value (A voltage point). Now I want to draw this on my graphic pane. Example:
So up in the picture you see at time 0, the voltage is also 0 and this goes on and after 6 data points I will clear the pane and redo the whole stuff.
The question is, how can I translate this voltage into pixel values, having in mind I want the middle of the graphic pane to be my signals 0, just like a normal cartesian graph. Can someone please help me to figure out the scaling algorithm in this case?
Seems like simple math: just add the width/2 to all X coordinates which you are passing into drawing functions. Suppose you have an array of 6 points you can do the following:
var g = this.CreateGraphics();
var points = new Point[6]{new Point(0, 0), new Point(10, 10), new Point(30, 0), new Point(40,20), new Point(50, 0), new Point(60,30)};
for (int i = 0; i < points.Length-1; i++)
{
g.DrawLine(Pens.Black, points[i].X + Width / 2, Height / 2 - points[i].Y, points[i + 1].X + Width / 2, Height / 2 - points[i + 1].Y);
}
Alternatively you can invoke TranslateTransform function to move all further drawing to some amount by X and Y axes. Example:
var g = this.CreateGraphics();
var points = new Point[6]{new Point(0, 0), new Point(10, 10), new Point(30, 0), new Point(40,20), new Point(50, 0), new Point(60,30)};
g.TranslateTransform(Width / 2, 0, System.Drawing.Drawing2D.MatrixOrder.Append);
for (int i = 0; i < points.Length-1; i++)
{
g.DrawLine(Pens.Black, points[i].X, Height / 2 - points[i].Y, points[i + 1].X, Height / 2 - points[i + 1].Y);
}
Maybe this will be useful (remember that scale and translate functions are changing points in array):
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
var points = new PointF[6] { new PointF(0, 0), new PointF(30, 3), new PointF(90, 0), new PointF(190, 3.1f), new PointF(270, -0.5f), new PointF(360, 3.5f) };
float maxX = (from p in points select p).Max(t => t.X);
float maxY = (from p in points select p).Max(t => t.Y);
float xSizeToFit = pictureBox1.Width;
float ySizeToFit = pictureBox1.Height/2;
float scaleX = xSizeToFit / maxX;
float scaleY = ySizeToFit / maxY;
// scale to fit to given size
ScalePoints(points, scaleX, scaleY);
// translate to center
TranslatePoints(points, this.pictureBox1.Width / 2 - 0.5f * xSizeToFit, this.pictureBox1.Height / 2 + 0.5f * ySizeToFit);
DrawAxis(e.Graphics, this.pictureBox1.Size);
e.Graphics.DrawLines(Pens.Black, points);
}
private void TranslatePoints(PointF[] points, float transX, float transY)
{
for (int i = 0; i < points.Length; i++)
{
points[i].X += transX;
points[i].Y = transY - points[i].Y;
}
}
private void ScalePoints(PointF[] points, float scaleX, float scaleY)
{
for (int i = 0; i < points.Length; i++)
{
points[i].X *= scaleX;
points[i].Y *= scaleY;
}
}
public void DrawAxis(Graphics g, Size size)
{
//x
g.DrawLine(Pens.Black, 0, size.Height / 2, size.Width, size.Height / 2);
//y
g.DrawLine(Pens.Black, size.Width / 2, size.Height, size.Width / 2, 0);
}
private void pictureBox1_Resize(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}