Inconsistency when generating rectangles [duplicate] - c#

I'm moving control(label or image) success in PictureBox. When I move, it will save control position(x, y).
Like this:
But problem is: the image result is:
Before gif image, I was drag and drop a label control in center screen. But result image doesn't save label in center screen.
I was set PictureBox attribute to StretchImage.
My code to get position and DrawText in PictureBox like:
public PositionControl CtrlPos = new PositionControl();
private void control_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Control control = (Control)sender;
Point nextPosition = new Point();
nextPosition = picPreview.PointToClient(MousePosition);
nextPosition.Offset(mouseX, mouseY);
control.Location = nextPosition;
CtrlPos.x = nextPosition.X;
CtrlPos.y = nextPosition.Y;
Invalidate();
}
}
My code is parent control(PictureBox) contain all control.
In my class, I'm using this:
private void picPreview_MouseMove(object sender, MouseEventArgs e)
{
if (SelectedControl != null && e.Button == MouseButtons.Left)
{
timer1.Stop();
Invalidate();
if (SelectedControl.Height < 20)
{
SelectedControl.Height = 20;
direction = Direction.None;
Cursor = Cursors.Default;
return;
}
else if (SelectedControl.Width < 20)
{
SelectedControl.Width = 20;
direction = Direction.None;
Cursor = Cursors.Default;
return;
}
//get the current mouse position relative the the app
Point pos = picPreview.PointToClient(MousePosition);
#region resize the control in 8 directions
if (direction == Direction.NW)
{
//north west, location and width, height change
newLocation = new Point(pos.X, pos.Y);
newSize = new Size(SelectedControl.Size.Width - (newLocation.X - SelectedControl.Location.X),
SelectedControl.Size.Height - (newLocation.Y - SelectedControl.Location.Y));
SelectedControl.Location = newLocation;
CtrlPos.x = newLocation.X;
CtrlPos.y = newLocation.Y;
SelectedControl.Size = newSize;
}
else if (direction == Direction.SE)
{
//south east, width and height change
newLocation = new Point(pos.X, pos.Y);
newSize = new Size(SelectedControl.Size.Width + (newLocation.X - SelectedControl.Size.Width - SelectedControl.Location.X),
SelectedControl.Height + (newLocation.Y - SelectedControl.Height - SelectedControl.Location.Y));
SelectedControl.Size = newSize;
}
else if (direction == Direction.N)
{
//north, location and height change
newLocation = new Point(SelectedControl.Location.X, pos.Y);
newSize = new Size(SelectedControl.Width,
SelectedControl.Height - (pos.Y - SelectedControl.Location.Y));
SelectedControl.Location = newLocation;
SelectedControl.Size = newSize;
}
else if (direction == Direction.S)
{
//south, only the height changes
newLocation = new Point(pos.X, pos.Y);
newSize = new Size(SelectedControl.Width,
pos.Y - SelectedControl.Location.Y);
SelectedControl.Size = newSize;
}
else if (direction == Direction.W)
{
//west, location and width will change
newLocation = new Point(pos.X, SelectedControl.Location.Y);
newSize = new Size(SelectedControl.Width - (pos.X - SelectedControl.Location.X),
SelectedControl.Height);
SelectedControl.Location = newLocation;
SelectedControl.Size = newSize;
}
else if (direction == Direction.E)
{
//east, only width changes
newLocation = new Point(pos.X, pos.Y);
newSize = new Size(pos.X - SelectedControl.Location.X,
SelectedControl.Height);
SelectedControl.Size = newSize;
}
else if (direction == Direction.SW)
{
//south west, location, width and height change
newLocation = new Point(pos.X, SelectedControl.Location.Y);
newSize = new Size(SelectedControl.Width - (pos.X - SelectedControl.Location.X),
pos.Y - SelectedControl.Location.Y);
SelectedControl.Location = newLocation;
SelectedControl.Size = newSize;
}
else if (direction == Direction.NE)
{
//north east, location, width and height change
newLocation = new Point(SelectedControl.Location.X, pos.Y);
newSize = new Size(pos.X - SelectedControl.Location.X,
SelectedControl.Height - (pos.Y - SelectedControl.Location.Y));
SelectedControl.Location = newLocation;
SelectedControl.Size = newSize;
}
#endregion
}
}
Draw image using CtrlPost(x, y):
g.DrawImage(
DrawText(image, new Font(cbxFont.Text, fontSize), colorInput,
Color.Transparent),
new Point(CtrlPos.x, CtrlPos.y));
// g is Graphics object.
Updated:
I was using code to add label1 to pictureBox1 like this:
pictureBox1.Controls.Add(label1);

If your PictureBox is in Sizemodes StretchImage or Zoom then the pixels are scaled; the Label's Location however is not. So you would have the calculate the position where to draw:
PointF stretched(Point p0, PictureBox pb)
{
if (pb.Image == null) return PointF.Empty;
float scaleX = 1f * pb.Image.Width / pb.ClientSize.Width;
float scaleY = 1f * pb.Image.Height / pb.ClientSize.Height;
return new PointF(p0.X * scaleX, p0.Y * scaleY);
}
You would call it as PointF p1 = stretched(p0, pictureBox1);
You would draw maybe like this:
g.DrawImage( DrawText(image, new Font(cbxFont.Text, fontSize),
colorInput, Color.Transparent),
Point.Round(stretched( CtrlPos.Location, picPreview));
If you also want to correct the size you can use a similar function..
If the SizeMode is CenterImage the pixels are not scaled but most likely transposed and a correction is necessary as well.
For the other direction simply switch denominator and numerator in the fractions!

Related

Drag and drop images on canvas

I have drag and drop the images on canvas. I have fix the boundaries so that my images not drag out of canvas,but when I zoom-in and zoom-out the images then its boundaries changes,and it would not drag over whole canvas.I have try this till now.
public void Btnedit_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
button.IsEnabled = false;
CompositeTransform CT = new CompositeTransform();
ImgeracOpen.ManipulationMode = ManipulationModes.All;
//ImgeracOpen.ManipulationDelta += Drag_ManipulationDelta;
ImgeracOpen.ManipulationDelta += Composite_ManipulationDelta;
ImgeracOpen.RenderTransform = CT;
}
void Composite_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
// scale the image
FrameworkElement Elem = sender as FrameworkElement;
CompositeTransform CT = Elem.RenderTransform as CompositeTransform;
if (CT != null)
{
CT.ScaleX *= e.Delta.Scale;
CT.ScaleY *= e.Delta.Scale;
CT.CenterX = Elem.ActualWidth / 2;
CT.CenterY = Elem.ActualHeight / 2;
if (CT.ScaleX < 0.25) CT.ScaleX = 0.25;
if (CT.ScaleY < 0.25) CT.ScaleY = 0.25;
if (CT.ScaleX > 1.15) CT.ScaleX = 1.15;
if (CT.ScaleY > 1.15) CT.ScaleY = 1.15;
}
double Left = Canvas.GetLeft(Elem);
double Top = Canvas.GetTop(Elem);
Left += e.Delta.Translation.X;//Get x cordinate
Top += e.Delta.Translation.Y;//Get y cordinate
//check for bounds
if (Left < 0)
{
Left = 0;
}
else if (Left > (my_canvas.ActualWidth - Elem.ActualWidth))
{
Left = my_canvas.ActualWidth - Elem.ActualWidth;
}
if (Top < 0)
{
Top = 0;
}
else if (Top > (my_canvas.ActualHeight - Elem.ActualHeight))
{
Top = my_canvas.ActualHeight - Elem.ActualHeight;
}
Canvas.SetLeft(Elem, Left);
Canvas.SetTop(Elem, Top);
thanks in advance
when I zoom-in and zoom-out the images then its boundaries changes,and it would not drag over whole canvas.
It's because when you scale the Image, the Image's ActualWidth and ActualHeight won't change and so is Left and Top that you get from Canvas.GetLeft and Canvas.GetTop.
To fix the problem, you need to calucate the Left and Top values when the image scales like below:
As you can see in the picture. When image scales, the Left Value should be Canvas.Width-Image.ActualWidth-xOffset when image hit the right boundary. And when it hit the left boundary Left should be equal to xOffset.
Through this logic, the codes in Composite_ManipulationDelta should be modified like below:
void Composite_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
// scale the image
FrameworkElement Elem = sender as FrameworkElement;
CompositeTransform CT = Elem.RenderTransform as CompositeTransform;
if (CT != null)
{
CT.ScaleX *= e.Delta.Scale;
CT.ScaleY *= e.Delta.Scale;
CT.CenterX = Elem.ActualWidth / 2;
CT.CenterY = Elem.ActualHeight / 2;
//if (CT.ScaleX < 0.25) CT.ScaleX = 0.25;
//if (CT.ScaleY < 0.25) CT.ScaleY = 0.25;
//if (CT.ScaleX > 1.15) CT.ScaleX = 1.15;
//if (CT.ScaleY > 1.15) CT.ScaleY = 1.15;
}
double Left = Canvas.GetLeft(Elem);
double Top = Canvas.GetTop(Elem);
//output.Text = "Left:=" + Left + " Top:=" + Top+"\nActualWidth:="+Elem.Width+" ActualHeight"+Elem.Height;
Left += e.Delta.Translation.X;//Get x cordinate
Top += e.Delta.Translation.Y;//Get y cordinate
//check for bounds
double xOffset = Elem.ActualWidth * (CT.ScaleX-1) / 2;
double yOffset = Elem.ActualHeight * (CT.ScaleY-1) / 2;
if (Left-xOffset < 0)
{
Left = xOffset;
}
else if (Left > (my_canvas.ActualWidth - Elem.ActualWidth-xOffset))
{
Left = my_canvas.ActualWidth - Elem.ActualWidth-xOffset;
}
if (Top -yOffset<0 )
{
Top = yOffset;
}
else if (Top > (my_canvas.ActualHeight - Elem.ActualHeight-yOffset))
{
Top = my_canvas.ActualHeight - Elem.ActualHeight-yOffset;
}
Canvas.SetLeft(Elem, Left);
Canvas.SetTop(Elem, Top);
}

Getting the mouse position on a zoomed picture

I am creating a screenshot maker/uploader and everything works great but now i wanna intergrate something like paint. So first i am creating the pencil function. But there starts the problems i can draw :D but not on the position of my mouse. He takes other position then my cursor?
So the question is:
Hoe to get the mouse positions on a zoomed picturebox?
My code:
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (draw && pencil)
{
Graphics panel = Graphics.FromImage(ScreenShot);
Pen pen = new Pen(Color.Black, 14);
pen.EndCap = LineCap.Round;
pen.StartCap = LineCap.Round;
panel.DrawLine(pen, pX, pY, e.X, e.Y);
pictureBox1.CreateGraphics().DrawImage(ScreenShot, pictureBox1.Width, pictureBox1.Height);
pictureBox1.Invalidate();
}
Point p = pictureBox1.PointToClient(Cursor.Position);
pX = p.X;
pY = p.Y;
}
When using the mouse on a zoomed image the reported pixels are the zoomed coordinates. So we need to get at the real pixels..
After setting up things somehow..
float pbZoom = 3f; // the factor by which the PictureBox is zoomed in or out
pictureBox.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox.ClientSize = new Size((int)(pictureBox.Image.Width * pbZoom),
(int)(pictureBox.Image.Height * pbZoom));
pictureBox.Paint += pictureBox_Paint;
pictureBox.MouseDown += pictureBox_MouseDown;
pictureBox.MouseMove += pictureBox_MouseMove;
pictureBox.MouseUp += pictureBox_MouseUp;
.. you can write the events to draw onto or into the zoomed image.
First a helper function to undo the zoom for a point:
PointF unZoomed(PointF pt) { return new PointF(pt.X / pbZoom, pt.Y / pbZoom );}
For simplicity lets keep a few things at class level:
PointF mDown = PointF.Empty; // mouse down point
PointF mCurrent = PointF.Empty; // current mouse location
We start each mouse event by calculating the unzoomed e.Location.
Our test draws a straight, moving red line on the surface until you release the mouse. Then that line is drawn into the Image in green.
The MouseDown simply stores the starting point, unzoomed:
void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
mDown = unZoomed(e.Location);
}
In the MouseMove we store the current point and trigger the Paint event:
void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.None) return;
PointF e_ = unZoomed(e.Location);
mCurrent = e_;
pictureBox.Invalidate();
}
In the MouseUp we draw the line into the Image of the PictureBox, changing its pixels; then we set the Image and reset the points:
void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
Bitmap bmp = (Bitmap) pictureBox.Image;
using (Graphics G = Graphics.FromImage(bmp))
{
G.SmoothingMode = SmoothingMode.HighQuality;
G.DrawLine(Pens.Green, mDown, mCurrent);
}
mDown = PointF.Empty;
mCurrent = PointF.Empty;
pictureBox.Image = bmp;
}
To draw onto the Control surface we use the Paint event. To draw scaled we use a Matrix..:
void pictureBox_Paint(object sender, PaintEventArgs e)
{
Matrix scaleMatrix = new Matrix();
scaleMatrix.Scale(pbZoom, pbZoom);
e.Graphics.MultiplyTransform(scaleMatrix);
e.Graphics.DrawLine(Pens.Red, mDown, mCurrent);
}
I also working with zoom image. I simply use this code, it's working. So you can just compare with bitmap (original image) before zoomed in/out.
private void pbInput_MouseMove(object sender, MouseEventArgs e) {
if (pbInput.Image == null) {
mouseY.Text = "";
mouseX.Text = "";
}
else {
Bitmap b = new Bitmap(pbInput.Image);
int x = b.Width * e.X / pbInput.Width;
int y = b.Height * e.Y / pbInput.Height;
mouseX.Text = x.ToString();
mouseY.Text = y.ToString();
}
}
this.Cursor = new Cursor(Cursor.Current.Handle);
Size size1 = pictureBox1.Image.Size;
Size size2 = pictureBox1.Size;
float x1 = (float)size1.Width / ((float)size2.Width + 1);
float y1 = (float)size1.Height / ((float)size2.Height + 1);
float divisor = x1 >= y1 ? x1 : y1;
divisor = divisor > 0 ? divisor : 1;
Size imagesize = new Size((int)(size1.Width / divisor), (int)(size1.Height / divisor));
int ex = imagesize.Width - size2.Width >= 0 ? imagesize.Width - size2.Width : size2.Width - imagesize.Width;
int ey = imagesize.Height - size2.Height >= 0 ? imagesize.Height - size2.Height : size2.Height - imagesize.Height;
float ftx = ((float)size1.Width / (float)imagesize.Width) * ((float)(Cursor.Position.X - this.Location.X - pictureBox1.Location.X - (ex / 2) - 8));
float fty = ((float)size1.Height / (float)imagesize.Height) * ((float)(Cursor.Position.Y - this.Location.Y - pictureBox1.Location.Y - (ey / 2) - 31));
Point LOP = new Point(Convert.ToInt32(ftx), Convert.ToInt32(fty)); //point of cursos on picturebox image pixel ...

How can i check that the pictureBox i'm moving around will not get out the borders top left right bottom of the second picturebox area?

private void picZoom_MouseMove(object sender, MouseEventArgs e)
{
if (PicImageClicked == false)
{
if (checkBox1.Checked)
{
int x = e.X + picZoom.Left - picImage.Left;
int y = e.Y + picZoom.Top - picImage.Top;
if (x <= picImage.Width && y <= picImage.Height &&
x <= picImage.Top && y <= picImage.Left)
{
MouseEventArgs e2 = new MouseEventArgs(MouseButtons.None, 0, x, y, 0);
picImageReposition(null, e2);
}
}
else
{
UpdateZoomedImage(e);
}
}
}
picImage is a bigger pictureBox and picZoom is a smaller pictureBox the picZoom i'm moving aorund inside the picImage are with the mouse.
This condition:
if (x <= picImage.Width && y <= picImage.Height
Is working if i'm moving the picZoom to the left border or the bottom border it stop on it and not continue.
But the second condition:
x <= picImage.Top && y <= picImage.Left
Is not working good it make everything slow and it's not stopping on the left or top borders.
I want to make a condition/s so the picZoom will stay in the picImage area borders.
What i tried now is:
private void picZoom_MouseMove(object sender, MouseEventArgs e)
{
Point pnt;
int x, y;
if (MouseButtons.Left == e.Button)
{
pnt = picZoom.PointToScreen(e.Location);
pnt = this.PointToClient(pnt);
x = pnt.X - mouseDown.X;
y = pnt.Y - mouseDown.Y;
if (x < picImage.Left)
{
x = picImage.Left;
}
else if (x + picZoom.Width > picImage.Left + picImage.Width)
{
x = picImage.Left + picImage.Width - picZoom.Width;
}
else
{ }
if (y < picImage.Top)
{
y = picImage.Top;
}
else if (y + picZoom.Height > picImage.Top + picImage.Height)
{
y = picImage.Top + picImage.Height - picZoom.Height;
}
else
{ }
picZoom.Location = new Point(x, y);
if (PicImageClicked == false)
{
if (checkBox1.Checked)
{
MouseEventArgs e2 = new MouseEventArgs(MouseButtons.None, 0, x, y, 0);
picImageReposition(null, e2);
}
else
{
UpdateZoomedImage(e);
}
}
}
}
picImageReposition is:
private void picImageReposition(object sender, MouseEventArgs e)
{
// If no picture is loaded, return
if (picImage.Image == null)
return;
if (PicImageClicked == false)
{
picZoom.BringToFront();
picZoom.Left = e.X + picImage.Left - picZoom.Width/2;
picZoom.Top = e.Y + picImage.Top - picZoom.Height/2;
UpdateZoomedImage(e);
}
}
And UpdateZoomedImage is:
private void UpdateZoomedImage(MouseEventArgs e)
{
// Calculate the width and height of the portion of the image we want
// to show in the picZoom picturebox. This value changes when the zoom
// factor is changed.
int zoomWidth = picZoom.Width / _ZoomFactor;
int zoomHeight = picZoom.Height / _ZoomFactor;
// Calculate the horizontal and vertical midpoints for the crosshair
// cursor and correct centering of the new image
int halfWidth = zoomWidth / 2;
int halfHeight = zoomHeight / 2;
// Create a new temporary bitmap to fit inside the picZoom picturebox
tempBitmap = new Bitmap(zoomWidth, zoomHeight, PixelFormat.Format24bppRgb);
// Create a temporary Graphics object to work on the bitmap
Graphics bmGraphics = Graphics.FromImage(tempBitmap);
// Clear the bitmap with the selected backcolor
bmGraphics.Clear(_BackColor);
// Set the interpolation mode
bmGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Draw the portion of the main image onto the bitmap
// The target rectangle is already known now.
// Here the mouse position of the cursor on the main image is used to
// cut out a portion of the main image.
bmGraphics.DrawImage(picImage.Image,
new Rectangle(0, 0, zoomWidth, zoomHeight),
new Rectangle(e.X - halfWidth, e.Y - halfHeight, zoomWidth, zoomHeight),
GraphicsUnit.Pixel);
// Draw the bitmap on the picZoom picturebox
picZoom.Image = tempBitmap;
// Draw a crosshair on the bitmap to simulate the cursor position
bmGraphics.DrawLine(Pens.Black, halfWidth + 1, halfHeight - 4, halfWidth + 1, halfHeight - 1);
bmGraphics.DrawLine(Pens.Black, halfWidth + 1, halfHeight + 6, halfWidth + 1, halfHeight + 3);
bmGraphics.DrawLine(Pens.Black, halfWidth - 4, halfHeight + 1, halfWidth - 1, halfHeight + 1);
bmGraphics.DrawLine(Pens.Black, halfWidth + 6, halfHeight + 1, halfWidth + 3, halfHeight + 1);
// Dispose of the Graphics object
bmGraphics.Dispose();
// Refresh the picZoom picturebox to reflect the changes
picZoom.Refresh();
}
If the formula of moving the picZoom control is what you want eg
int x = e.X + picZoom.Left - picImage.Left;
int y = e.Y + picZoom.Top - picImage.Top;
then the comparison is(x, y is the position in picImage meaning that 0,0 is the left top position):
if(x >= 0 && y >= 0 && x + picZoom.Width <= picImage.Width && y + picZoom.Height <= picImage.Height)
{
...
...
}
EDIT
When you click in picZoom and drag, the control moves with the mouse:
private Point mouseDown;
private void picZoom_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = e.Location;
}
private void picZoom_MouseMove(object sender, MouseEventArgs e)
{
Point pnt;
int x, y;
if (MouseButtons.Left == e.Button)
{
pnt = picZoom.PointToScreen(e.Location);
pnt = this.PointToClient(pnt);
x = pnt.X - mouseDown.X;
y = pnt.Y - mouseDown.Y;
if (x < picImage.Left)
{
x = picImage.Left;
}
else if (x + picZoom.Width > picImage.Left + picImage.Width)
{
x = picImage.Left + picImage.Width - picZoom.Width;
}
else
{ }
if (y < picImage.Top)
{
y = picImage.Top;
}
else if (y + picZoom.Height > picImage.Top + picImage.Height)
{
y = picImage.Top + picImage.Height - picZoom.Height;
}
else
{ }
picZoom.Location = new Point(x, y);
}
}
valter
This is not an answer to your question as much as it is a suggestion. Could you not create a Rect() directly over your picture and simply check if the mouse position is within it's bounds.
Something along the lines of:
Rectangle rect = obj.GetBounds(e.Graphics);
if (!rect.Intersects(e.ClipRectangle))
continue;
(stolen from another post)
So I looked over your code again, and it struck me.
You are comparing an x value to the top bound of your picture and a y value to the left bound...
x <= picImage.Top && y <= picImage.Left
should be
x <= picImage.Left && y <= picImage.Top
That is, if I understand what you are trying to do.
Good luck!

Snapping drawn rectangles to each other

I have a WPF application, wherein I draw rectangles in a canvas.I need to add a functionality in which when i draw a rectangle if there is a rectangle next to it (for eg: suppose first rectangle x coordinate is 236 and second rectangle coordinate is 235) i need to snap the second rectangle x coordinate to 236 as shown in the image.
The snap would be done only if the distance difference is 10.
I have written the following code to do this.
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
startPos = e.GetPosition(Canvas);
System.Windows.Point curPosition = e.GetPosition(SectionCanvas);
rect = new System.Windows.Shapes.Rectangle
{
Stroke = brushColor,
StrokeDashArray = new DoubleCollection { 2, 2 },
Tag = "rectangle"
};
Canvas.SetLeft(rect, startPos.X);
Canvas.SetTop(rect, startPos.X);
SectionCanvas.Children.Add(rect);
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
currentPos = e.GetPosition(SectionCanvas);
var x = Math.Min(currentPos.X, startPos.X);
var y = Math.Min(currentPos.Y, startPos.Y);
var w = Math.Max(currentPos.X, startPos.X) - x;
var h = Math.Max(currentPos.Y, startPos.Y) - y;
rect.Width = w;
rect.Height = h;
Canvas.SetLeft(rect, x);
Canvas.SetTop(rect, y);
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
if(rect == null)
{
MessageBox.Show("Could not capture section, Please try again");
return;
}
endPos = e.GetPosition(SectionCanvas);
IEnumerable<Rect> coordinates = rectCollection.Select(r => new Rect(Canvas.GetLeft(r), Canvas.GetTop(r), r.Width, r.Height));
Rect newCordinates = new Rect(Canvas.GetLeft(rect), Canvas.GetTop(rect), rect.Width, rect.Height);
if (coordinates.Any(c => c.IntersectsWith(newCordinates)))))
{
MessageBox.Show("New Rectangle intersects with existing rectangle");
Canvas.Children.Remove(rect);
return;
}
rectCollection.Add(rect);
rect = null;
foreach(Point p in tempCollection)
{
if((startPos.X <= (p.X + 10) && startPos.X >= (p.X -10)))
{
startPos.X = p.X;
}
if(endPos.X <= (p.X + 10) && endPos.X >= (p.X - 10))
{
var x1 = Math.Max(endPos.X,p.X) - Math.Min(endPos.X, p.X);
var w1 = startPos.X - x1;
endPos.X = p.X;
startPos.X = w1;
}
if ((startPos.Y <= (p.Y + 10) && startPos.Y >= (p.Y - 10)))
{
startPos.Y = p.Y;
}
if (endPos.Y <= (p.Y + 10) && endPos.Y >= (p.Y - 10))
{
var x1 = Math.Max(endPos.Y, p.Y) - Math.Min(endPos.Y, p.Y);
var w1 = startPos.Y - x1;
endPos.Y = p.Y;
}
}
var x = Math.Min(currentPos.X, startPos.X);
var y = Math.Min(currentPos.Y, startPos.Y);
var w = Math.Max(currentPos.X, startPos.X) - x;
var h = Math.Max(currentPos.Y, startPos.Y) - y;
rect.Width = w;
rect.Height = h;
rect.Stroke = Brushes.Coral;
Canvas.SetLeft(rect, x);
Canvas.SetTop(rect, y);
rect = null;
tempCollection.Add(startPos);
tempCollection.Add(endPos);
}
The above code doesnt work when I am changing the endpoints values. While debugging I can see that the end point value changes but the rectangle drawn doesn't change. I am not able to find out what I am doing wrong.
I figured out the answer which was a dumb mistake from my end.
While calculating the width and height after snapping, I am using currentPos, instead I should use endPos.
var x = Math.Min(endPos.X, startPos.X);
var y = Math.Min(endPos.Y, startPos.Y);
var w = Math.Max(endPos.X, startPos.X) - x;
var h = Math.Max(endPos.Y, startPos.Y) - y;

Zoom Out by reversing Zoom In Mouse

I have a block of code which is executed on a C# Windows Form upon Mouse_Up. It basically zooms in on a rendered image and keeps zooming in each time the rubber band is drawn. I want to reverse this by adding a checkbox (which I have already done) and if the check box is ticked, do zooming out instead from the current view as per drawing of the rubber band. I thought it would be as simple as using the opposite operands i.e "+" instead of a "-" but it won't work. I have posted the event code below. There is a conditional IF on there for changing of the checkbox state. The first lot work fine with zooming in. The section after the ELSE IF doesn't let me zoom out - hence I have just left repeated code there for someone to look at. Thanks
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (checkBox1.Checked == false)
{
int z, w;
this.Cursor = Cursors.Arrow;
// Set internal flag to know we no longer "have the mouse".
weHaveMouse = false;
// If we have drawn previously, draw again in that spot
// to remove the lines.
if (ptLast.X != -1)
{
toolStripStatusLabel1.Text = "Please click and drag to zoom into the Fractal";
Point ptCurrent = new Point(e.X, e.Y);
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
// Set flags to know that there is no "previous" line to reverse.
ptLast.X = -1;
ptLast.Y = -1;
ptOriginal.X = -1;
ptOriginal.Y = -1;
//e.consume();
if (action)
{
xe = e.X;
ye = e.Y;
if (xs > xe)
{
z = xs;
xs = xe;
xe = z;
}
if (ys > ye)
{
z = ys;
ys = ye;
ye = z;
}
w = (xe - xs);
z = (ye - ys);
if ((w < 2) && (z < 2)) initvalues();
else
{
if (((float)w > (float)z * xy)) ye = (int)((float)ys + (float)w / xy);
else xe = (int)((float)xs + (float)z * xy);
xende = xstart + xzoom * (double)xe;
yende = ystart + yzoom * (double)ye;
xstart += xzoom * (double)xs;
ystart += yzoom * (double)ys;
}
xzoom = (xende - xstart) /(double)x1;
yzoom = (yende - ystart) / (double)y1;
mandelbrot();
rectangle = false;
//Refresh();
}
}
else if (checkBox1.Checked == true)
{
int z, w;
this.Cursor = Cursors.Arrow;
// Set internal flag to know we no longer "have the mouse".
weHaveMouse = false;
// If we have drawn previously, draw again in that spot
// to remove the lines.
if (ptLast.X != -1)
{
toolStripStatusLabel1.Text = "Please click and drag to zoom into the Fractal";
Point ptCurrent = new Point(e.X, e.Y);
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
// Set flags to know that there is no "previous" line to reverse.
ptLast.X = -1;
ptLast.Y = -1;
ptOriginal.X = -1;
ptOriginal.Y = -1;
//e.consume();
if (action)
{
xe = e.X;
ye = e.Y;
if (xs > xe)
{
z = xs;
xs = xe;
xe = z;
}
if (ys > ye)
{
z = ys;
ys = ye;
ye = z;
}
w = (xe - xs);
z = (ye - ys);
if ((w < 2) && (z < 2)) initvalues();
else
{
if (((float)w > (float)z * xy)) ye = (int)((float)ys + (float)w / xy);
else xe = (int)((float)xs + (float)z * xy);
xende = xstart + xzoom * (double)xe;
yende = ystart + yzoom * (double)ye;
xstart += xzoom * (double)xs;
ystart += yzoom * (double)ys;
}
xzoom = (xende - xstart) / (double)x1;
yzoom = (yende - ystart) / (double)y1;
mandelbrot();
rectangle = false;
//Refresh();
}
}
}
First of all, in my humble opinion, there is no need to draw rubber band when you are zooming out. Just a click where the zoomed out image will be centered. Nevertheless, I cannot see the difference in the code you provided between the code for zooming in and zooming out. In general, the simplest thing to do is to zoom out the image in a way that current center of the image remains at its place and handle the image drawing in a way that X and Y coordinates are divided by 2 and Width and Height are multiplied by 2.
In case of your code, calculating something like this at the end of code could maybe do the trick:
xzoom = 1/xzoom;
yzoom = 1/yzoom;

Categories

Resources