I've been trying to solve a problem I'm having with rotating an oval. The code that I'm posting works, but it's mimicking the kind of code I have to work with for real. Meaning, I can't use the OnPaint override and I'm limited to what I can do in the main code. I'm adding an oval to a graphic layer, and I need to be able to rotate, move and resize the oval. Move and resizing work flawlessly, but rotating doesn't work as I need it to.
If you click in the small box at the 9 oclock position,
the oval will rotate as expected:
The required behavior is to be able to click in the small box at the 12 oclock position, and have the oval rotate again. This does not occur. In order to get the oval to rotate again you need to click in the original 9 oclock position. What I'm really, really trying to find out is how to get the coordinates of the box at the 12 oclock position (or what ever position or location that box ends up after rotating) so that I can rotate it again. Thus far, I have been unable to figure it out. Please try and understand, I'm working with old code that was poorly written and I'm not allowed to change very much of it. What I write must integrate with what's already there. Below is the code snippet that demonstrates what I'm doing. I know I'm missing something obvious, just don't know what. Thanks.
public partial class Form1 : Form
{
int theAngle = 0;
Pen pen2 = new Pen(Color.FromArgb(255, 68, 125, 255), 4);
Pen pen3 = new Pen(Color.Green, 4);
Pen smallPen = new Pen(Color.Black, 1);
PointF center = new PointF(0, 0);
Rectangle rectangle = new Rectangle(20, 20, 100, 30);
Rectangle myRect2 = new Rectangle();
bool mouseBtnDown = false;
Graphics gw;
public Form1()
{
InitializeComponent();
this.MouseDown += mouseDown;
gw = this.CreateGraphics();
}
private void mouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (myRect2.Contains(e.Location))
theAngle+=90;
rotate();
}
if (e.Button == MouseButtons.Right)
{
//oval = false;
//mouseBtnDown = false;
theAngle = 0;
rectangle.X = e.X - 50;
rectangle.Y = e.Y - 15;
rectangle.Width = 100;
rectangle.Height = 30;
center.X = rectangle.Left + (0.5f * rectangle.Width);
center.Y = rectangle.Top + (0.5f * rectangle.Height);
myRect2.Size = new Size(15, 15);
myRect2.Location = new Point(rectangle.Left - 15, (rectangle.Top - (rectangle.Height / 2)) + 15);
drawstuff();
// Invalidate();
}
}
public void rotate()
{
var matrix = new Matrix();
matrix.RotateAt(theAngle, center);
gw.Transform = matrix;
drawstuff();
}
public void drawstuff()
{
gw.SmoothingMode = SmoothingMode.AntiAlias; // Creates smooth lines.
gw.DrawEllipse(pen2, rectangle);
gw.DrawRectangle(smallPen, myRect2);
}
}
You can use the Transform matrix to rotate points. So what I've done is get the 4 corner points of myRect2, rotate them using the same Transform matrix, then assign these to a rectangle. You can then use this new rectangle to check the location. I also changed the call to drawstuff() at the end of the right button click to call rotate(), this way the rotated rectangle can get updated when the ellipse is first placed, and the graphics transform angle gets updated to 0.
public partial class Form1 : Form
{
int theAngle = 0;
Pen pen2 = new Pen(Color.FromArgb(255, 68, 125, 255), 4);
Pen pen3 = new Pen(Color.Green, 4);
Pen smallPen = new Pen(Color.Black, 1);
PointF center = new PointF(0, 0);
Rectangle rectangle = new Rectangle(20, 20, 100, 30);
Rectangle myRect2 = new Rectangle();
Rectangle rotatedRect2 = new Rectangle();
bool mouseBtnDown = false;
Graphics gw;
public Form1()
{
InitializeComponent();
this.MouseDown += mouseDown;
gw = this.CreateGraphics();
}
private void mouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (rotatedRect2.Contains(e.Location))
theAngle += 90;
rotate();
}
if (e.Button == MouseButtons.Right)
{
//oval = false;
//mouseBtnDown = false;
theAngle = 0;
rectangle.X = e.X - 50;
rectangle.Y = e.Y - 15;
rectangle.Width = 100;
rectangle.Height = 30;
center.X = rectangle.Left + (0.5f * rectangle.Width);
center.Y = rectangle.Top + (0.5f * rectangle.Height);
myRect2.Size = new Size(15, 15);
myRect2.Location = new Point(rectangle.Left - 15, (rectangle.Top - (rectangle.Height / 2)) + 15);
rotate();
//drawstuff();
// Invalidate();
}
}
public void rotate()
{
var matrix = new Matrix();
matrix.RotateAt(theAngle, center);
gw.Transform = matrix;
// Get the 4 corner points of myRect2.
Point p1 = new Point(myRect2.X, myRect2.Y),
p2 = new Point(myRect2.X + myRect2.Width, myRect2.Y),
p3 = new Point(myRect2.X, myRect2.Y + myRect2.Height),
p4 = new Point(myRect2.X + myRect2.Width, myRect2.Y + myRect2.Height);
Point[] pts = new Point[] { p1, p2, p3, p4 };
// Rotate the 4 points.
gw.Transform.TransformPoints(pts);
// Update rotatedRect2 with those rotated points.
rotatedRect2.X = pts.Min(pt => pt.X);
rotatedRect2.Y = pts.Min(pt => pt.Y);
rotatedRect2.Width = pts.Max(pt => pt.X) - pts.Min(pt => pt.X);
rotatedRect2.Height = pts.Max(pt => pt.Y) - pts.Min(pt => pt.Y);
drawstuff();
}
public void drawstuff()
{
gw.SmoothingMode = SmoothingMode.AntiAlias; // Creates smooth lines.
gw.DrawEllipse(pen2, rectangle);
gw.DrawRectangle(smallPen, myRect2);
}
}
Something to note. Drawing to the screen like this (using the form's created graphics and drawing using your own draw function) means the ellipses/rectangles are only drawn once. i.e. if you draw a few then minimize your form, when you bring it back up the ellipses will be gone. Not sure if this is what you're after or not. One way to fix this would be to draw the ellipses to a Bitmap and then in the form's Paint event this bitmap is draw to the form.
Related
I posted a question about using Graphics Transform and got a great answer. What I needed was to have a spot on an oval where, if the mouse was in it, the oval would rotate. The code below includes that. However, now I ALSO need a region where, if the mouse is clicked inside it, I can resize the oval.
The problem I'm having isn't with the resize, it's with the region detection because the code that's transforming the resize rectangle isn't working. That same code works great when applied to the small, moving circle, which is leaving me more than a little confused.
When you start out, you have everything correctly placed and working. The oval, the small circle that will rotate it when you click in it, and the green box (Currently hidden under a red one) where if you click in it, you can resize the oval.
However, if you begin to rotate everything, the red rectangle is what you get. But what I need is that red rectangle to be the exact same size and shape as the green one and in the same place as the green one so that I can use the rectange.Contains(mousepointer) methods.
I know that I'm missing something basic here, but I have yet to be able to isolate it. Any helpful ideas would be appreciated. Here's the code I'm using:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace OvalTestV2
{
public partial class Form1 : Form
{
int theAngle = 0;
Pen pen2 = new Pen(Color.FromArgb(255, 68, 125, 255), 4);
Pen pen3 = new Pen(Color.Green, 4);
Pen smallPen = new Pen(Color.Black, 1);
bool testspot = false;
PointF center = new PointF(0, 0);
Rectangle rectangle = new Rectangle(20, 20, 100, 30);
Rectangle myRect2 = new Rectangle();
Rectangle rotatedRect2 = new Rectangle();
Rectangle resizeRect = new Rectangle();
Rectangle resizeRect2 = new Rectangle();
bool mouseBtnDown = false;
Graphics gw;
public Form1()
{
InitializeComponent();
this.MouseDown += mouseDown;
gw = this.CreateGraphics();
}
private void mouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (resizeRect.Contains(e.Location))
{
testspot = true;
}
if (resizeRect2.Contains(e.Location))
testspot = true;
if (rotatedRect2.Contains(e.Location))
{
gw.Clear(SystemColors.Control);
theAngle += 5;
rotate();
}
}
if (e.Button == MouseButtons.Right)
{
//oval = false;
//mouseBtnDown = false;
theAngle = 0;
rectangle.X = e.X - 50;
rectangle.Y = e.Y - 15;
rectangle.Width = 100;
rectangle.Height = 30;
center.X = rectangle.Left + (0.5f * rectangle.Width);
center.Y = rectangle.Top + (0.5f * rectangle.Height);
myRect2.Size = new Size(15, 15);
myRect2.Location = new Point(rectangle.Left - 15, (rectangle.Top - (rectangle.Height / 2)) + 15);
resizeRect.X = rectangle.X;
resizeRect.Y = rectangle.Y;
resizeRect.Size = rectangle.Size;
rectangle.Location = rectangle.Location;
rotate();
//drawstuff();
}
}
public void rotate()
{
mouseDnX_lbl.Text = myRect2.X.ToString();
mouseDnY_lbl.Text = myRect2.Y.ToString();
var matrix = new Matrix();
matrix.RotateAt(theAngle, center);
gw.Transform = matrix;
//For the Rotation area
// Get the 4 corner points of myRect2.
Point p1 = new Point(myRect2.X, myRect2.Y),
p2 = new Point(myRect2.X + myRect2.Width, myRect2.Y),
p3 = new Point(myRect2.X, myRect2.Y + myRect2.Height),
p4 = new Point(myRect2.X + myRect2.Width, myRect2.Y + myRect2.Height);
Point[] pts = new Point[] { p1, p2, p3, p4 };
// Rotate the 4 points.
gw.Transform.TransformPoints(pts);
// Update rotatedRect2 with those rotated points.
rotatedRect2.X = pts.Min(pt => pt.X);
rotatedRect2.Y = pts.Min(pt => pt.Y);
rotatedRect2.Width = pts.Max(pt => pt.X) - pts.Min(pt => pt.X);
rotatedRect2.Height = pts.Max(pt => pt.Y) - pts.Min(pt => pt.Y);
//End of Rotation Area
//For the Resize area
Point rp1 = new Point(resizeRect.X, resizeRect.Y),
rp2 = new Point(resizeRect.X + resizeRect.Width, resizeRect.Y),
rp3 = new Point(resizeRect.X, resizeRect.Y + resizeRect.Height),
rp4 = new Point(resizeRect.X + resizeRect.Width, resizeRect.Y + resizeRect.Height);
Point[] rpts = new Point[] { rp1, rp2, rp3,rp4 };
// Rotate the 4 points.
gw.Transform.TransformPoints(rpts);
// Update rotatedRect2 with those rotated points.
resizeRect2.X = rpts.Min(pt => pt.X);
resizeRect2.Y = rpts.Min(pt => pt.Y);
resizeRect2.Width = rpts.Max(pt => pt.X) - rpts.Min(pt => pt.X);
resizeRect2.Height = rpts.Max(pt => pt.Y) - rpts.Min(pt => pt.Y);
//End of Resize area
drawstuff();
}
Pen pen4 = new Pen(Color.Red, 4);
public void drawstuff()
{
gw.SmoothingMode = SmoothingMode.AntiAlias; // Creates smooth lines.
gw.DrawEllipse(pen2, rectangle);
gw.DrawEllipse(smallPen, myRect2);
gw.DrawRectangle(pen3, resizeRect);
gw.DrawRectangle(pen4, resizeRect2);
}
Imagine I have a line which is colored Gradient with three color : dark red, red and light red. I want to change position of these colors in that line . My purpose is showing something is moving along line.
I don't know How I can create animation for changing position of each colors in a line which is colored gradient.
I have found this : https://learn.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/how-to-animate-the-position-or-color-of-a-gradient-stop
but It isn't too clear.
Here is an example:
It uses a LineraGradientBrush, moving the starting point of the defining rectangle top left and painting a rotated rectangle onto a PictureBox:
Point p1 = Point.Empty;
private void timer1_Tick(object sender, EventArgs e)
{
int deltaX = -3;
int deltaY = -3;
p1 = new Point(p1.X + deltaX , p1.Y + deltaY); // roll..
if (p1.X < deltaX * 1000) p1 = Point.Empty; // ..around
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
float angle = 33f;
if (!timer1.Enabled) return;
Rectangle rectG = new Rectangle(p1.X, p1.Y, 122, 22);
Rectangle rectR = new Rectangle(22, 22, 222, 22);
LinearGradientBrush lBrush = new LinearGradientBrush(rectG,
Color.Red, Color.Red, angle, false);
ColorBlend cblend = new ColorBlend(5);
cblend.Colors = new Color[5]
{ Color.Red, Color.Pink, Color.MistyRose, Color.LightCoral, Color.White };
cblend.Positions = new float[5] { 0f, 0.2f, 0.5f, 0.8f, 1f };
lBrush.InterpolationColors = cblend;
lBrush.WrapMode = WrapMode.TileFlipXY;
e.Graphics.RotateTransform(angle);
e.Graphics.TranslateTransform(22,11);
e.Graphics.FillRectangle(lBrush, rectR);
}
Note that this being Winforms you can't get real smooth animations but if the control/form you paint on is DoubleBufered at least it won't flicker..
I have a list of Points that have been drawn on pictureBox1.
pictureBox1 has been transformed.
Now, I want to get XY coordinates of the point that was drawn as I hover over any drawn point.
When I hover over the pictureBox1, I am getting the XY of the pictureBox -- not a transformed XY.
Can you help me get to the transformed XY?
Thanks
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
int height = pictureBox1.ClientSize.Height / 2;
int width = pictureBox1.ClientSize.Width / 2;
//=====
//scale
//=====
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TranslateTransform(-width, -height);
e.Graphics.ScaleTransform(2f, 2f);
//===========
//draw center
//===========
e.Graphics.DrawLine(new Pen(Color.Black, 0.5f), new Point(width - 2, height), new Point(width + 2, height));
e.Graphics.DrawLine(new Pen(Color.Black, 0.5f), new Point(width, height - 2), new Point(width, height + 2));
//===========
//draw points
//===========
foreach (var p in Points)
{
Point[] pts = new Point[] { new Point(p.X, p.Y) };
Rectangle rc = new Rectangle(pts[0], new Size(1, 1));
e.Graphics.DrawRectangle(Pens.Red, rc);
}
}
As a variation to #Vitaly's answer you can do this:
After transforming the Graphics object you can save its transformation matrix e.Graphics.Transform in a variable:
Matrix matrix = null;
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
int height = pictureBox1.ClientSize.Height / 2;
int width = pictureBox1.ClientSize.Width / 2;
//=====
//scale
//=====
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TranslateTransform(-width, -height);
e.Graphics.ScaleTransform(2f, 2f);
matrix = e.Graphics.Transform; // save the transformation matrix!
...
This is necessary as the transfomation data are lost after the Paint event!
Note that the GraphicsState graphics.Save()&Restore() functions can't be used very well for this purpose, as it only puts the state on the stack for using it once, meaning it doesn't save these data in a persistent way.
Later you can use the Matrix and this function to either transform Points with the same matrix or reverse the transformation, e.g. for mouse coordinates:
PointF transformed(Point p0, bool forward)
{
Matrix m = matrix.Clone();
if (!forward) m.Invert();
var pt = new Point[] { p0 };
m.TransformPoints(pt);
return pt[0];
}
Now my MouseMove event shows the location both raw and re-transformed:
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
label1.Text = e.Location + " <-> " + transformed(e.Location, false) ;
}
And to test the forward transformation you could add this to the end of the Paint event:
e.Graphics.ResetTransform();
for (int i = 0; i < Points.Count; i++)
{
Point[] pts = new Point[] { Point.Round(transformed(Points[i], true)) };
Rectangle rc = new Rectangle(pts[0], new Size(19, 19));
e.Graphics.DrawRectangle(Pens.Red, rc);
}
This first clears all the transformations and then paints larger Rectangles at the same locations by calling the transformed function.
Note that this will also work with a rotated Graphics object. (Although the last test does not draw the larger rectangles rotated, just moved to the right locations.)
Also note that I return PointF for better precision when scaling with fractions. You can use Point.Round (or Point.Truncate) to get Point.
Do have a look the the Matrix.Elements: They contain the numbers you have used:
float scaleX = matrix.Elements[0];
float scaleY = matrix.Elements[3];
float transX = matrix.Elements[4];
float transY = matrix.Elements[5];
Finally: It is well worth studying the many methods of Matrix..!
You can create a Matrix with necessary transformations and apply it in pictureBox1_Paint(...) via MultiplyTransform(...):
https://msdn.microsoft.com/en-us/library/bt34tx5d(v=vs.110).aspx
Then you can use Matrix::TransformPoints(...) to get transformed XY
So I have this steering wheel control, and when I rotate it with the mouse and refresh the image it stops my other panel control from drawing its graph from updating/redrawing. Below is the code for rotating and redrawing the steering wheel.
private readonly Bitmap _originalHelmImage;
private Bitmap _newHelmImage;
private void HelmPb_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
PictureBox p = (PictureBox) sender;
Bitmap bmp = (Bitmap) p.Image;
//GetPixel works on initial image, not stretched one.
double ratio = (double) p.Image.Width/p.Width;
//Ignore the non-helm portion of the helm.
Color trans = bmp.GetPixel(Convert.ToInt32(ratio*e.X), Convert.ToInt32(ratio*e.Y));
if (trans.A.Equals(0))
{
_dontTurn = true;
return;
}
_offsetAngle = OffsetAngle() - _lastAngleTurn;
_lastAngleTurn = 0;
_dontTurn = false;
}
private double OffsetAngle()
{
int helmXMid = HelmPb.PointToScreen(Point.Empty).X + (HelmPb.Width / 2);
int helmYMid = HelmPb.PointToScreen(Point.Empty).Y + (HelmPb.Height / 2);
double angle = AngleFromPoints(MousePosition, new Point(helmXMid, helmYMid));
return angle;
}
private void HelmPb_MouseMove(object sender, MouseEventArgs e)
{
if ((e.Button != MouseButtons.Left) || _dontTurn) return;
double angle = OffsetAngle();
float degrees = Convert.ToSingle(angle - _offsetAngle);
//float diff = ((360 - degrees) - _deltaHelmTurn%360)%360;
//float diff = (_lastAngleTurn - (degrees - 360)) % 360;
double diff = 90 - angle;
_deltaHelmTurn += Convert.ToSingle(diff - _lastAngleTurn);
if (Math.Abs(_deltaHelmTurn) >= (_maxHelmTurn*360.0))
{
_deltaHelmTurn = Convert.ToSingle(_maxHelmTurn*360.0);
degrees = 0;
}
_lastAngleTurn = Convert.ToSingle(degrees);
_newHelmImage = RotateImage(_originalHelmImage, -degrees);
HelmPb.Image.Dispose();
HelmPb.Image = _newHelmImage;
WaterDepthPlot.Invalidate();
HelmPb.Refresh();
}
double AngleFromPoints(Point pt1, Point pt2)
{
Point p = new Point(pt1.X - pt2.X, pt1.Y - pt2.Y);
double alpha;
if (p.Y == 0) alpha = p.X > 0 ? 0d : 180d;
else
{
double f = 1d * p.X / (Math.Sqrt(p.X * p.X + p.Y * p.Y));
alpha = Math.Acos(f) * 180d / Math.PI;
if (p.Y > 0) alpha = 360d - alpha;
}
return alpha;
}
private Bitmap RotateImage(Bitmap b, float angle)
{
//Create a new empty bitmap to hold rotated image.
Bitmap returnBitmap = new Bitmap(b.Width, b.Height);
//Make a graphics object from the empty bitmap.
Graphics g = Graphics.FromImage(returnBitmap);
//move rotation point to center of image.
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.TranslateTransform(b.Width/2F, b.Height/2F);
//Rotate.
g.RotateTransform(angle);
//Move image back.
g.TranslateTransform(-b.Width/2F, -b.Height/2F);
//Draw passed in image onto graphics object.
g.DrawImage(b, new PointF(0.0F, 0.0F));
return returnBitmap;
}
Below is the code for updating my graph. It is never ran when the steering wheel is being moved. Once the users stops moving, it will update. Is there a way for it to constantly update along with it? I tried throwing a refresh/invalidate of the panel into the mousemove event so whenever the wheel is refreshed, so is the graph; no luck. Any suggestions?
private void WaterDepthPlot_Paint(object sender, PaintEventArgs e)
{
Pen pen = new Pen(Color.FromArgb(70, 75, 80));
int xOffset = WaterDepthPlot.Location.X;
e.Graphics.DrawLine(pen, new Point(0, 0), new Point(WaterDepthPlot.Width, 0));
e.Graphics.DrawLine(pen, new Point(0, (WaterDepthPlot.Height/5)),
new Point(WaterDepthPlot.Width, (WaterDepthPlot.Height/5)));
e.Graphics.DrawLine(pen, new Point(0, (2*WaterDepthPlot.Height/5)),
new Point(WaterDepthPlot.Width, (2*WaterDepthPlot.Height/5)));
e.Graphics.DrawLine(pen, new Point(0, (3*WaterDepthPlot.Height/5)),
new Point(WaterDepthPlot.Width, (3*WaterDepthPlot.Height/5)));
e.Graphics.DrawLine(pen, new Point(0, (4*WaterDepthPlot.Height/5)),
new Point(WaterDepthPlot.Width, (4*WaterDepthPlot.Height/5)));
e.Graphics.DrawLine(pen, new Point((ThirdXScaleUnit.Location.X - xOffset), 0),
new Point((ThirdXScaleUnit.Location.X - xOffset),
(WaterDepthPlot.Height + WaterDepthPlot.Location.Y)));
e.Graphics.DrawLine(pen, new Point((SecondXScaleUnit.Location.X - xOffset), 0),
new Point((SecondXScaleUnit.Location.X - xOffset),
(WaterDepthPlot.Height + WaterDepthPlot.Location.Y)));
e.Graphics.DrawLine(pen, new Point((FirstXScaleUnit.Location.X - xOffset), 0),
new Point((FirstXScaleUnit.Location.X - xOffset),
(WaterDepthPlot.Height + WaterDepthPlot.Location.Y)));
pen = new Pen(Color.Firebrick);
pen.DashStyle = DashStyle.Dash;
float[] dash = {3, 3};
pen.DashPattern = dash;
double diff = (double) WaterDepthPlot.Height/(5*_depthYScale);
int alertDiff = (int)(_alertDepth * diff);
e.Graphics.DrawLine(pen, new Point(0, alertDiff), new Point(WaterDepthPlot.Width, alertDiff));
pen = new Pen(Color.White);
GraphicsPath gp = new GraphicsPath();
if (_depthCurve.Count < 2) return;
gp.AddCurve(_depthCurve.ToArray());
e.Graphics.DrawPath(pen, gp);
}
hey i am trying to build a windows application in .net,i have to draw factorial image inside the panel
private void Canvas_Paint(object sender, PaintEventArgs e)
{
start_x = Canvas.Width / 2;
start_Y = Canvas.Height / 2;
for (int i = 0; i < 400; i++)
draw_T();
}
public void draw_T()
{
mypen = new Pen(Color.Green, 2F);
my_angle = my_angle + (45);
my_length = 100 + (1);
end_x = (int)(start_x + Math.Cos(my_angle * .0174539676) * my_length);
end_Y = (int)(start_Y + Math.Sin(my_angle * .0174539676) * my_length);
Point[] points =
{
new Point (start_x,start_Y),
new Point (end_x,end_Y)
};
Point[] points1 =
{
new Point ((end_x+start_x)/2,(end_Y+start_Y)/2),
new Point (end_x+50,end_Y-100)
};
start_x = end_x;
start_Y = end_Y;
Graphics g = Canvas.CreateGraphics();
g.DrawLines(mypen, points);
g.DrawLines(mypen, points1);
}
drawing T shape line,then i start to draw another T shape from last end points .But problem is diagram is going outside of the panel.How do i fix drawing inside the panel