here's my code,
private bool isMouseOverPin(int x, int y, Pin pin)
{
int left, top, right, bottom,size;
size=5;
left = pin.theRectangle.Left-size;
right = pin.theRectangle.Right + size;
top = pin.theRectangle.Top - size;
bottom = pin.theRectangle.Bottom + size;
if (x >= left && y >= top && x <= right && y <= bottom)
{
return true;
}
else
{
return false;
}
}
private void pinHover()
{
for (int i = 0; i < pins.Count; i++)
{
if (isMouseOverPin(Cursor.Position.X, Cursor.Position.Y, pins[i]) == true)
{
using (Graphics gr=canvas.CreateGraphics())
{
gr.DrawRectangle(10,10,10,10);
}
}
}
}
private void canvas_MouseMove(object sender, MouseEventArgs e)
{
pinHover();
}
i want when some one place a mouse over a pin it draws a rectangle, pin size is 5, i am unable to understand why its not working properly. help plz
I suspect that your pins location is relative to canvas instead of to screen.
You should pass e.Location from the MouseEventArgs to pinHover, or you could use PointToClient
e.g.
List<Int32> DrawPinRects;
private void initBuffer()
{
DrawPinRects = new List<Int32>();
}
private void pinHover(Point Position)
{
DrawPinRects.Clear();
for (int i = 0; i < pins.Count; i++)
{
if (isMouseOverPin(Position.X, Position.Y, pins[i]) == true)
{
DrawPinRects.Add(i);
}
}
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
pinHover(e.Location);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
foreach(Int32 index in DrawPinRects)
{
Int32 y = panel1.VerticalScroll.Value + 10;
e.Graphics.DrawRectangle(Pens.Black, 10, y, 10, 10);
}
}
Also this:
int left, top, right, bottom,size;
size=5;
left = pin.theRectangle.Left-size;
right = pin.theRectangle.Right + size;
top = pin.theRectangle.Top - size;
bottom = pin.theRectangle.Bottom + size;
if (x >= left && y >= top && x <= right && y <= bottom)
can be simplified to
int size = 5;
Rectangle TestRect = pin.theRectangle;
TestRect.Inflate(size,size);
if (TestRect.Contains(x,y))
which will do the same thing.
Related
I'm looking for the method for moving and changing the size of shape using mouse #C.
That shape made by mouse location (Point start, end) on pictureBox named "captureDesign".
I wanted to ask for a little bit of help.
I searched many similar case of question, but I couldn't solve it yet.
IF possible, please let me know to how.
Here is my code.
It's not everything, for example, I omitted the contents about the mode selection for shape using Button_click.
I studied the similar case.
But I haven't noticed it yet.
How can I associate startPt (#MouseDown) and endPt (#MouseUp) with MyMove to make the move successful?
MyMove code is written in upper link. I need it change.
Actually I need to code for change the size but, first of all, I want to move that using mouse.
namespace Pilot
{
enum DrawMode { LINE, RECTANGLE, CIRCLE, NUMBER };
public partial class mainForm : Form
{
#region define
private bool _isCaptionShow = false;
private ScreenPicture sp;
private IContainer components = null;
Bitmap bitmap;
private DrawMode drawMode;
private Graphics g;
private Pen pen = new Pen(Color.Red, 7);
Point startPt, endPt, currPt, prevPt, addPt;
private int numberCount = 0;
int rectWidth, rectHeight;
Font font = new Font("Arial", 12);
private bool selectMode = false;
private void selectModeButton_CheckedChanged(object sender, EventArgs e)
{
if (selectModeButton.Checked == true)
selectMode = true;
else
selectMode = false;
}
MyMove m;
Point deltaStart;
Point deltaEnd;
bool dragging = false;
#region Contents on PictureBox "captureDesign;" when mouse clicked.
private void captureDesign_MouseDown(object sender, MouseEventArgs e)
{
startPt = new Point(e.X, e.Y);
prevPt = startPt;
currPt = startPt;
if (selectMode)
{
if (e.Button == MouseButtons.Left && m.IsPointOnLine(e.Location, 5))
{
dragging = true;
deltaStart = new Point(startPt.X- e.Location.X, startPt.Y - e.Location.Y);
}
}
}
#region Contents on PictureBox captureDesign when Mouse dropped.
private void captureDesign_MouseUp(object sender, MouseEventArgs e)
{
g = captureDesign.CreateGraphics();
endPt = new Point(e.X, e.Y);
m = new MyMove(pen, startPt, endPt);
#region calculate between start Point ~ end Point to width, height
if (endPt.X < startPt.X)
{
rectWidth = Math.Abs(endPt.X - startPt.X);
addPt.X = endPt.X;
}
else
{
rectWidth = Math.Abs(endPt.X - startPt.X);
addPt.X = startPt.X;
}
if (endPt.Y < startPt.Y)
{
rectHeight = Math.Abs(endPt.Y - startPt.Y);
addPt.Y = endPt.Y;
}
else
{
rectHeight = Math.Abs(endPt.Y - startPt.Y);
addPt.Y = startPt.Y;
}
#endregion
if (selectMode)
{
deltaEnd = new Point(endPt.X - e.Location.X, endPt.Y - e.Location.Y);
}
else //No selectMode
{
#region draw the shape in case of drawMode
switch (drawMode)
{
case DrawMode.LINE:
if (arrowCheck.Checked == true)
{
pen.StartCap = LineCap.ArrowAnchor;
}
else
//g.DrawLine(pen, startPt, endPt);
g.DrawLine(m.mpen, m.mStart, m.mEnd);
break;
case DrawMode.RECTANGLE:
//g.DrawRectangle(pen, new Rectangle(startPt, new Size(endPt.X - startPt.X, endPt.Y - startPt.Y)));
g.DrawRectangle(pen, new Rectangle(addPt, new Size(rectWidth, rectHeight)));
break;
case DrawMode.CIRCLE:
g.DrawEllipse(pen, new Rectangle(addPt, new Size(rectWidth, rectHeight)));
break;
case DrawMode.NUMBER:
numberCount++;
g.DrawString(numberCount.ToString(), font, Brushes.White, endPt);
break;
}
#endregion
}
}
#region
private void captureDesign_MouseMove(object sender, MouseEventArgs e)
{
if (dragging && deltaStart != null && deltaEnd != null)
{
m.mStart = new Point(deltaStart.X + e.Location.X, deltaStart.Y + e.Location.Y);
m.mEnd = new Point(deltaEnd.X + e.Location.X, deltaEnd.Y + e.Location.Y);
}
}
}
public class MyMove
{
public Pen mpen { get; set; }
public Point mStart { get; set; }
public Point mEnd { get; set; }
public MyMove(Pen p, Point p1, Point p2)
{
mpen = p;
mStart = p1;
mEnd = p2;
}
public float slope
{
get
{
return (((float)mEnd.Y - (float)mStart.Y) / ((float)mEnd.X - (float)mStart.X));
}
}
public float YIntercept
{
get
{
return mStart.Y - slope * mStart.X;
}
}
public bool IsPointOnLine(Point p, int cushion)
{
float temp = (slope * p.X + YIntercept);
if (temp >= (p.Y-cushion) && temp <=(p.Y+cushion))
{
return true;
}
else
{
return false;
}
}
}
1ST ANSWER
Everything happens on MouseMove(object sender, MouseEventArgs e).
Here is a sample
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
//If we are not allowed to draw, simply return and disregard the rest of the code
if (!_canDraw) return;
//The x-value of our rectangle should be the minimum between the start x-value and the current x-position
int x = Math.Min(_startX, e.X);
//The y-value of our rectangle should also be the minimum between the start y-value and current y-value
int y = Math.Min(_startY, e.Y);
//The width of our rectangle should be the maximum between the start x-position and current x-position minus
//the minimum of start x-position and current x-position
int width = Math.Max(_startX, e.X) - Math.Min(_startX, e.X);
//For the hight value, it's basically the same thing as above, but now with the y-values:
int height = Math.Max(_startY, e.Y) - Math.Min(_startY, e.Y);
_rect = new Rectangle(x, y, width, height);
//Refresh the form and draw the rectangle
Refresh();
}
protected override void OnPaint(PaintEventArgs e)
{
//Create a new 'pen' to draw our rectangle with, give it the color red and a width of 2
using (Pen pen = new Pen(Color.Red, 2))
{
//Draw the rectangle on our form with the pen
e.Graphics.DrawRectangle(pen, _rect);
}
}
You can further study the detail here, C# Tutorial - Drawing rectangles with the mouse.
2ND ANSWER (UPDATE)
I achieve the solution you want but I use a third party library MoveGraphLibrary. You can further read this article Moveable Resizable Objects.
Sample Code
GRAPHICAL OBJECT
public class Rectangle : GraphicalObject
{
protected RectangleF rc;
protected Resizing resize;
protected float wMin, wMax, hMin, hMax;
protected int radius;
protected int halfstrip;
protected SolidBrush brush;
int minsize = 25;
// -------------------------------------------------
public Rectangle(RectangleF rect, RectRange range, int rad, int half, Color color)
{
rc = new RectangleF(rect.X, rect.Y, Math.Max(minsize, rect.Width), Math.Max(minsize, rect.Height));
if (range == null)
{
wMin = wMax = rc.Width;
hMin = hMax = rc.Height;
}
else
{
wMin = Math.Max(minsize, Math.Min(rc.Width, range.MinWidth));
wMax = Math.Max(rc.Width, range.MaxWidth);
hMin = Math.Max(minsize, Math.Min(rc.Height, range.MinHeight));
hMax = Math.Max(rc.Height, range.MaxHeight);
}
RectRange realrange = new RectRange(wMin, wMax, hMin, hMax);
resize = realrange.Resizing;
radius = rad;
halfstrip = half;
brush = new SolidBrush(color);
}
// -------------------------------------------------
// ------------------------------------------------- RectAround
new public RectangleF RectAround
{
get { return (rc); }
}
// ------------------------------------------------- Radius
public int Radius
{
get { return (radius); }
set
{
radius = Math.Abs(value);
DefineCover();
}
}
// ------------------------------------------------- HalfStrip
public int HalfStrip
{
get { return (halfstrip); }
set
{
halfstrip = Math.Abs(value);
DefineCover();
}
}
// ------------------------------------------------- Color
public Color Color
{
get { return (brush.Color); }
set { brush.Color = value; }
}
// -------------------------------------------------
public void Draw(Graphics grfx)
{
grfx.FillRectangle(brush, rc);
}
// ------------------------------------------------- Resizing
public Resizing Resizing
{
get { return (resize); }
set
{
resize = value;
DefineCover();
}
}
// ------------------------------------------------- DefineCover
public override void DefineCover()
{
cover = new Cover(rc, resize, radius, halfstrip);
}
// -------------------------------------------------
public override void Move(int dx, int dy)
{
rc.X += dx;
rc.Y += dy;
}
// ------------------------------------------------- MoveNode
public override bool MoveNode(int iNode, int dx, int dy, Point ptM, MouseButtons catcher)
{
bool bRet = false;
if (catcher == MouseButtons.Left)
{
float wNew, hNew;
switch (resize)
{
case Resizing.Any:
if (iNode == 8)
{
Move(dx, dy);
}
else if (iNode == 0) //LT corner
{
hNew = rc.Height - dy;
if (hMin <= hNew && hNew <= hMax)
{
MoveBorder_Top(dy);
bRet = true;
}
wNew = rc.Width - dx;
if (wMin <= wNew && wNew <= wMax)
{
MoveBorder_Left(dx);
bRet = true;
}
}
else if (iNode == 1) // RT corner
{
hNew = rc.Height - dy;
if (hMin <= hNew && hNew <= hMax)
{
MoveBorder_Top(dy);
bRet = true;
}
wNew = rc.Width + dx;
if (wMin <= wNew && wNew <= wMax)
{
MoveBorder_Right(dx);
bRet = true;
}
}
else if (iNode == 2) // RB corner
{
wNew = rc.Width + dx;
if (wMin <= wNew && wNew <= wMax)
{
MoveBorder_Right(dx);
bRet = true;
}
hNew = rc.Height + dy;
if (hMin <= hNew && hNew <= hMax)
{
MoveBorder_Bottom(dy);
bRet = true;
}
}
else if (iNode == 3) // LB corner
{
hNew = rc.Height + dy;
if (hMin <= hNew && hNew <= hMax)
{
MoveBorder_Bottom(dy);
bRet = true;
}
wNew = rc.Width - dx;
if (wMin <= wNew && wNew <= wMax)
{
MoveBorder_Left(dx);
bRet = true;
}
}
else if (iNode == 4) // on left side
{
wNew = rc.Width - dx;
if (wMin <= wNew && wNew <= wMax)
{
MoveBorder_Left(dx);
bRet = true;
}
}
else if (iNode == 5) // on right side
{
wNew = rc.Width + dx;
if (wMin <= wNew && wNew <= wMax)
{
MoveBorder_Right(dx);
bRet = true;
}
}
else if (iNode == 6) // on top
{
hNew = rc.Height - dy;
if (hMin <= hNew && hNew <= hMax)
{
MoveBorder_Top(dy);
bRet = true;
}
}
else if (iNode == 7) // on bottom
{
hNew = rc.Height + dy;
if (hMin <= hNew && hNew <= hMax)
{
MoveBorder_Bottom(dy);
bRet = true;
}
}
break;
case Resizing.NS:
if (iNode == 2)
{
Move(dx, dy);
}
else if (iNode == 0) // on top
{
hNew = rc.Height - dy;
if (hMin <= hNew && hNew <= hMax)
{
MoveBorder_Top(dy);
bRet = true;
}
}
else if (iNode == 1) // on bottom
{
hNew = rc.Height + dy;
if (hMin <= hNew && hNew <= hMax)
{
MoveBorder_Bottom(dy);
bRet = true;
}
}
break;
case Resizing.WE:
if (iNode == 2)
{
Move(dx, dy);
}
else if (iNode == 0) // on left side
{
wNew = rc.Width - dx;
if (wMin <= wNew && wNew <= wMax)
{
MoveBorder_Left(dx);
bRet = true;
}
}
else if (iNode == 1) // on right side
{
wNew = rc.Width + dx;
if (wMin <= wNew && wNew <= wMax)
{
MoveBorder_Right(dx);
bRet = true;
}
}
break;
case Resizing.None:
Move(dx, dy);
break;
}
}
return (bRet);
}
// ------------------------------------------------- MoveBorder_Top
private void MoveBorder_Top(int dy)
{
rc.Y += dy;
rc.Height -= dy;
}
// ------------------------------------------------- MoveBorder_Bottom
private void MoveBorder_Bottom(int dy)
{
rc.Height += dy;
}
// ------------------------------------------------- MoveBorder_Left
private void MoveBorder_Left(int dx)
{
rc.X += dx;
rc.Width -= dx;
}
// ------------------------------------------------- MoveBorder_Right
private void MoveBorder_Right(int dx)
{
rc.Width += dx;
}
public PointF Location
{
get
{
return rc.Location;
}
}
}
MAIN FORM
public partial class Form1 : Form
{
RectRange rr;
// Variables use for Moving & Resizing
NumericUpDown numericUD_Radius = new NumericUpDown();
NumericUpDown numericUD_HalfStrip = new NumericUpDown();
string[] strs = new string[] {"Circles' radius",
"Half strip width"
};
Mover mover;
Point ptMouse_Down;
bool bShowCovers = false;
RigidlyBoundRectangles rigidrectsView;
List<Shapes.Rectangle> rects = new List<Shapes.Rectangle>();
int radius, halfstrip;
// Variables use for Drawing
bool isMouseDown = false;
public Form1()
{
InitializeComponent();
lblXAxis.Text = $"X Axis: -";
lblYAxis.Text = $"Y Axis: -";
numericUD_Radius.Value = 6;
numericUD_HalfStrip.Value = 3;
mover = new Mover(panel1);
SizeF[] sizefStrs = Auxi_Geometry.MeasureStrings(this, strs);
rigidrectsView = new RigidlyBoundRectangles(new Control[] { numericUD_Radius, numericUD_HalfStrip });
rigidrectsView.Add(Auxi_Geometry.RectangleToRectangleSide(numericUD_Radius.Bounds, Side.E, sizefStrs[0], 4), "Radius");
rigidrectsView.Add(Auxi_Geometry.RectangleToRectangleSide(numericUD_HalfStrip.Bounds, Side.E, sizefStrs[1], 4), "Strip");
rigidrectsView.AddUnionRectangle();
radius = Convert.ToInt32(numericUD_Radius.Value);
halfstrip = Convert.ToInt32(numericUD_HalfStrip.Value);
rr = new RectRange(panel1.MinimumSize.Width, panel1.Size.Width, panel1.MinimumSize.Height, panel1.Size.Height);
rects.Add(new Shapes.Rectangle(new RectangleF(100, 100, 300, 400), rr, radius, halfstrip, Color.Black));
RenewMover();
}
private void RenewMover()
{
mover.Clear();
mover.Insert(0, rigidrectsView);
for (int i = 0; i < rects.Count; i++)
{
mover.Add(rects[i]);
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Graphics grfx = e.Graphics;
GraphicalObject grobj;
for (int i = mover.Count - 1; i >= 0; i--)
{
grobj = mover[i].Source;
if (grobj is Shapes.Rectangle)
{
(grobj as Shapes.Rectangle).Draw(grfx);
}
if (bShowCovers)
{
mover[i].DrawCover(grfx);
}
}
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
lblXAxis.Text = $"X Axis: {e.X}";
lblYAxis.Text = $"Y Axis: {e.Y}";
if (rbMoveOrResize.Checked && mover.Move(e.Location))
{
panel1.Invalidate();
}
else
{
if (isMouseDown)
{
var rectangle = rects.Last();
var drawRectangle = new Shapes.Rectangle(new RectangleF(rectangle.Location.X,
rectangle.Location.Y,
e.X - rectangle.Location.X,
e.Y - rectangle.Location.Y),
rr, radius, halfstrip, Color.Black);
rects.Remove(rects.Last());
rects.Add(drawRectangle);
RenewMover();
panel1.Invalidate();
}
}
}
private void panel1_MouseLeave(object sender, EventArgs e)
{
lblXAxis.Text = $"X Axis: -";
lblYAxis.Text = $"Y Axis: -";
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
if (rbMoveOrResize.Checked)
{
ptMouse_Down = e.Location;
mover.Catch(e.Location, e.Button);
}
else
{
isMouseDown = true;
rects.Add(new Shapes.Rectangle(new RectangleF(e.Location.X, e.Location.Y, 0, 0), rr, radius, halfstrip, Color.Black));
}
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
if (rbMoveOrResize.Checked && mover.Release())
{
if (e.Button == MouseButtons.Left &&
Auxi_Geometry.Distance(ptMouse_Down, e.Location) <= 3)
{
GraphicalObject grobj = mover[mover.ReleasedObject].Source;
if (grobj is Shapes.Rectangle)
{
PopupRectangle(grobj.ID);
}
}
}
else
{
isMouseDown = false;
}
}
private void rb_CheckedChanged(object sender, EventArgs e)
{
bShowCovers = rbMoveOrResize.Checked;
panel1.Invalidate();
}
private void PopupRectangle(long id)
{
for (int i = rects.Count - 1; i > 0; i--)
{
if (id == rects[i].ID)
{
Shapes.Rectangle elem = rects[i];
rects.RemoveAt(i);
rects.Insert(0, elem);
RenewMover();
panel1.Invalidate();
break;
}
}
}
}
SAMPLE OUTPUT
i'm doing homework in Visual Studio 2017.
I have to create a convex hull and then add more convex hulls to it, without changing others. So I find out how to make one convex hull but I don't know how to add more in this code. I have to create new botton (Add convex hull) in a code and then I don't know how to continue.
Thank you for all your answers.
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
Point zacasna = new Point();
zacasna.X = e.X;
zacasna.Y = e.Y;
seznamTock.Add(zacasna);
pictureBox1.Image = Image.FromFile(file);
using (var g = Graphics.FromImage(pictureBox1.Image))
{
for (int i = 0; i < seznamTock.Count; i++)
{
g.DrawEllipse(barva_tock, seznamTock[i].X, seznamTock[i].Y,
5, 5);
}
pictureBox1.Refresh();
}
}
private List<Point> konveksnaLupina(List<Point> tocka)
{
List<Point> hull = new List<Point>();
Point vPointOnHull = tocka.Where(p => p.X == tocka.Min(min =>
min.X)).First();
Point vEndpoint;
do
{
hull.Add(vPointOnHull);
vEndpoint = tocka[0];
for (int i = 1; i < tocka.Count; i++)
{
if ((vPointOnHull == vEndpoint)
|| (Orientacija(vPointOnHull, vEndpoint, tocka[i]) ==
-1))
{
vEndpoint = tocka[i];
}
}
vPointOnHull = vEndpoint;
}
while (vEndpoint != hull[0]);
return hull;
}
private static int Orientacija(Point p1, Point p2, Point p)
{
// Determinanta
int Orin = (p2.X - p1.X) * (p.Y - p1.Y) - (p.X - p1.X) * (p2.Y -
p1.Y);
if (Orin > 0)
{
return -1; //orientacija v levo
}
if (Orin < 0)
{
return 1; //orientacija v desno
}
return 0; //neutralna orientacija
}
private void button2_Click(object sender, EventArgs e)
{
if (seznamTock.Count < 3)
{
MessageBox.Show("Premalo tock!");
return;
}
List<Point> hull = new List<Point>();
hull = konveksnaLupina(seznamTock);
pictureBox1.Image = Image.FromFile(file);
using (var g = Graphics.FromImage(pictureBox1.Image))
{
for (int j = 0; j < seznamTock.Count; j++)
{
g.DrawEllipse(barva_tock, seznamTock[j].X, seznamTock[j].Y,
5, 5);
}
for (int j = 0; j < hull.Count; j++)
{
Point tocka1 = new Point(hull[j].X, hull[j].Y);
Point tocka2 = new Point(hull[(j + 1) % hull.Count].X,
hull[(j + 1) % hull.Count].Y);
g.DrawLine(barva_kon_lupine, tocka1, tocka2);
}
for (int j = 0; j < hull.Count; j++)
{
g.DrawEllipse(barva_tock_kon_lupine, hull[j].X, hull[j].Y,
`enter code here`5, 5);
}
pictureBox1.Refresh();
}
}
}
add new points in to the new list, but without changing previous figure
You are thinking List<Point> is figure. Well, it's not. It's a list of points. Figures may have more properties and if you have several figures stored as array of points - how would you know which point belong to which figure?
OOP can make it more clear:
abstract class Figure
{
public abstract void Draw(Graphics graphics);
}
class Convex: Figure
{
public List<Point> Points { get; set; }
public Color Color { get; set; } = Color.Black;
... // more properties
public override void Draw(Graphics graphics)
{
if(Points != null)
using(var pen = new Pen(Color))
graphics.DrawLines(pen, Points.ToArray());
}
}
... // more figures
You can hold different figures in List<Figure> and simply add new figure to it:
class Billboard
{
public List<Figure> Figures { get; } = new List<Figure>();
public void Add(Figure figure) => Figures.Add(figure);
... // more methods
}
Redraw:
Billboard _billboard = new Billboard();
void pictureBox1_Paint(object sender, PaintEventArgs e)
{
foreach(var figure in _billboard.Figures)
figure.Draw(e.Graphics);
}
I like Sinatrs approach. But, here's an alternative, just using a collection and your existing code. It's not, the best mod. Think, it does what you want.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
Collection<List<Point>> test = new Collection<List<Point>>();
List<Point> seznamTock = new List<Point>();
Pen barva_tock = new Pen(Color.Blue);
Pen barva_kon_lupine = new Pen(Color.Black);
Pen barva_tock_kon_lupine = new Pen(Color.Yellow);
public Form1()
{
InitializeComponent();
test.Add(seznamTock);
}
private List<Point> konveksnaLupina(List<Point> tocka)
{
List<Point> hull = new List<Point>();
Point vPointOnHull = tocka.Where(p => p.X == tocka.Min(min =>
min.X)).First();
Point vEndpoint;
do
{
hull.Add(vPointOnHull);
vEndpoint = tocka[0];
for (int i = 1; i < tocka.Count; i++)
{
if ((vPointOnHull == vEndpoint)
|| (Orientacija(vPointOnHull, vEndpoint, tocka[i]) ==
-1))
{
vEndpoint = tocka[i];
}
}
vPointOnHull = vEndpoint;
}
while (vEndpoint != hull[0]);
return hull;
}
private static int Orientacija(Point p1, Point p2, Point p)
{
// Determinanta
int Orin = (p2.X - p1.X) * (p.Y - p1.Y) - (p.X - p1.X) * (p2.Y - p1.Y);
return (Orin == 0) ? Orin : ((Orin > 0) ? -1 : 1);
//if (Orin > 0)
//{
// return -1; //orientacija v levo
//}
//if (Orin < 0)
//{
// return 1; //orientacija v desno
//}
//return 0; //neutralna orientacija
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
Point zacasna = new Point();
zacasna.X = e.X;
zacasna.Y = e.Y;
seznamTock.Add(zacasna);
//pictureBox1.Image = Image.FromFile(file);
using (var g = Graphics.FromImage(pictureBox1.Image))
{
for (int i = 0; i < seznamTock.Count; i++) { g.DrawEllipse(barva_tock, seznamTock[i].X, seznamTock[i].Y, 5, 5); }
pictureBox1.Refresh();
}
}
private void button1_Click(object sender, EventArgs e)
{
//if (seznamTock.Count < 3)
//{
// MessageBox.Show("Premalo tock!");
// return;
//}
List<Point> hull = new List<Point>();
hull = konveksnaLupina(seznamTock);
//pictureBox1.Image = Image.FromFile(file);
using (var g = Graphics.FromImage(pictureBox1.Image))
{
for (int j = 0; j < seznamTock.Count; j++)
{
g.DrawEllipse(barva_tock, seznamTock[j].X, seznamTock[j].Y,
5, 5);
}
for (int j = 0; j < hull.Count; j++)
{
Point tocka1 = new Point(hull[j].X, hull[j].Y);
Point tocka2 = new Point(hull[(j + 1) % hull.Count].X,
hull[(j + 1) % hull.Count].Y);
g.DrawLine(barva_kon_lupine, tocka1, tocka2);
}
for (int j = 0; j < hull.Count; j++)
{
g.DrawEllipse(barva_tock_kon_lupine, hull[j].X, hull[j].Y, 5, 5);
}
pictureBox1.Refresh();
test.Add(seznamTock);
seznamTock = new List<Point>();
}
}
}
}
I have something like chessboard, 21x21 checks, each of one have 10x10pixels. I have no idea how do I paint one of the check when user click mouse on it.
Probably i have to use arrays but i dont know how can I assign 10x10 pixels to one element of other array. Can i assign array wiht 100 elements to one elemnet of other array?
This is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace gotowa_mapa
{
public partial class Form1 : Form
{
Bitmap mapa;
private int szer_pb = 200;
private int wys_pb = 200;
private int ilosc_kratek_x = 41;
private int ilosc_kratek_y = 41;
// private void wpisanie_tablic()
//{
// int[,] tablica_kratki = new int[ilosc_kratek_x, ilosc_kratek_y];
// int[,] tablica_piksele = new int[szer_pb, wys_pb];
//for(int i=0;i<ilosc_kratek_x; i++)
// {
// for(int j=0; j<ilosc_kratek_y; j++)
//{
// tablica_kratki[ilosc_kratek_x, ilosc_kratek_y] = tablica_piksele[2,2];
//}
//}
//}
private void siatka1()
{
mapa = new Bitmap(szer_pb, wys_pb);
int factor_x = (int)(szer_pb / ilosc_kratek_x);
int factor_y = (int)(wys_pb / ilosc_kratek_y);
for (int i = 0; i < szer_pb; i++)
{
if (i > (factor_x * ilosc_kratek_x))
break;
for (int j = 0; j < wys_pb; j++)
{
if (j > (factor_y * ilosc_kratek_y))
break;
if (i % (factor_x) == 0 || j % (factor_y) == 0)
{
mapa.SetPixel(i, j, Color.Black);
mapa.SetPixel(j, i, Color.Black);
}
else
{
mapa.SetPixel(i, j, Color.White);
mapa.SetPixel(j, i, Color.White);
}
}
}
}
// private void rysowanie_scian(int x, int y)
// {
// }
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
siatka1();
pictureBox1.Image = mapa;
}
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
int x, y;
x = e.X;
y = e.Y;
MessageBox.Show(x + " " + y);
}
}
}
I've made an example for you, although there is probably better ways of doing this, using some simple math you can achieve this.
A neat trick is overriding the onPaint method of a panel, making a new Bitmap with the same size as the panel, drawing this image over the panel during the onPaint method, making changes directly to the image, then invalidating the panel so it draws the image. (You can then save the image with Bitmap.Save)
Keep in mind, if a game of some sort is what you are aiming for, GDI is not ideal, look into managed DirectX or similar.
//declare variables
public const int offset = 50;
public const int boardX = 10;
public const int boardY = 10;
public const int checkSize = 40;
int[] checks;
//set initial values for the checks array
if(checks == null)
{
checks = new int[boardX * boardY];
}
//start iterating through the array of checks
for (int i = 0; i < checks.Length; i++)
{
//if the check is empty (assuming you will use integers as identifiers for the pieces on the board)
if (checks[i] < 1)
{
//check if the check in array is odd number & paint odd numbers black on alternating rows
if (i % 2 != 0)
{
//check if row is odd
if (Math.Ceiling((double)(i + 1) / boardX) % 2 != 0)
{
drawCheck(Brushes.Black, e.Graphics, i);
}
else
{
drawCheck(Brushes.White, e.Graphics, i)
}
}
else
{
//check if row is odd
if (Math.Ceiling((double)(i+1) / boardX) % 2 != 0;
{
drawCheck(Brushes.White, e.Graphics, i);
}
else
{
drawCheck(Brushes.Black, e.Graphics, i)
}
}
}
else if (checks[i] == 1)
{
//the check is a "clicked check" - draw it red
drawCheck(Brushes.Red, e.Graphics, i);
}
}
//The Methods
private void YOURDRAWINGSURFACE_MouseClick(object sender, MouseEventArgs e)
{
if(e.X < (boardX * checkSize) + offset && e.Y < (boardY * checkSize) + offset && e.X > offset && e.Y > offset )
{
//you have clicked somewhere on the board. if that square isn't red, make it so, else turn it back to a normal square
if (checks[checkClicked(e.X, e.Y)] != 1)
{
checks[checkClicked(e.X, e.Y)] = 1;
}
else
{
checks[checkClicked(e.X, e.Y)] = 0;
}
}
//this is only relevant for GDI drawing code. It will invalidate the form to redraw the surface (needs to be called whenever you make a change)
this.Invalidate();
}
public int checkClicked(int mouseX, int mouseY)
{
//this method returns the int of the particular check that was clicked in the array.
return ((int)Math.Ceiling((double)(mouseX - offset) / checkSize) + (int)((Math.Ceiling((double)(mouseY - offset) / checkSize)) * boardX) - (1 + boardX));
}
public void drawCheck(Brush brush, Graphics graphics, int checkNumber)
{
//this method draws the check given the parameters.
graphics.FillRectangle(brush, ((checkNumber % boardX) * checkSize) + offset, (int)(Math.Ceiling((double)(checkNumber-(boardX-1)) / boardX) * checkSize) + offset, checkSize, checkSize);
}
I have a picturebox in windows form application that has the ability to move with arrowkeys. I want it to have certain limits to where it can go, specifically in the form. How do I do this? My class to move the target is below:
namespace AmazingPaintball
{
class Target
{
private Point p;
public Target(Point myPoi)
{
p = myPoi;
}
public Point Move(Keys key)
{
if (key == Keys.Left)
{
p.Offset(-50, 0);
}
else if (key == Keys.Right)
{
p.Offset(50, 0);
}
else if (key == Keys.Up)
{
p.Offset(0, -50);
}
else if (key == Keys.Down)
{
p.Offset(0, 50);
}
return p;
}
}
}
Below is the form1:
namespace AmazingPaintball
{
public partial class Form1 : Form
{
Random positionX = new Random();
Random positionY = new Random();
Target einstein;
int count = 0;
Paintballs pBalls = new Paintballs();
Stopwatch stopwatch = new Stopwatch();
SoundPlayer wavPlayer = new SoundPlayer(#"G:\ChefBrohansPaintballFunNew\ChefBrohansPaintballFun\Resources\singlegunshot.wav");
SoundPlayer wavPlayer2 = new SoundPlayer(#"G:\ChefBrohansPaintballFunNew\ChefBrohansPaintballFun\bin\Debug\Resources\Applause.wav");
public Form1()
{
InitializeComponent();
Point point = new Point(positionX.Next(0, 638), positionY.Next(0, 404));
einstein = new Target(point);
ptrEinstein.Location = point;
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
pBalls.paint(e.Graphics);
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
ptrEinstein.Location = einstein.Move(e.KeyData);
pictureBox1.Update();
pictureBox1.Refresh();
}
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
wavPlayer.Play();
pBalls.add(e.Location);
pictureBox1.Refresh();
count++;
}
private void Form1_Load(object sender, EventArgs e)
{
stopwatch.Start();
}
private void ptrEinstein_MouseClick(object sender, MouseEventArgs e)
{
count++;
ptrEinstein.Image = Properties.Resources.AlbertEinsteinTongue;
stopwatch.Stop();
wavPlayer2.Play();
MessageBox.Show("It took " + count + " shots and " + stopwatch.Elapsed + " seconds to hit the target");
wavPlayer2.Stop();
ptrEinstein.Image = Properties.Resources.AlbertEinsteinFace;
count = 0;
stopwatch.Reset();
stopwatch.Start();
}
}
}
The picturebox is ptrEinstein and it is able to move in the form1_keydown event.
When you're moving the picture box, first check to make sure where you're moving it to is inside the form. E.g. check if the new X + the width of the picture box is less than the width of the form, etc.
This will be incomplete because we do not have your code, but you should compare the clientSize properties to the picturebox location (taking into account the size of the picturebox):
PictureBox pb = new PictureBox();
int newX = oldX + xOffset; // xOffset is whatever you're incrementing x by
int newY = oldY + yOffset; // yOffset is whatever you're incrementing y by
if (newX < 0) {
newX = 0;
} else if (newX > this.ClientSize.Width - pb.Width) {
newX = this.ClientSize.Width - pb.Width;
}
if (newY < 0) {
newY = 0;
} else if (newY > this.ClientSize.Height - pb.Height) {
newY = this.ClientSize.Height - pb.Height;
}
// New point to move it to
Point newP = new Point(newX, newY);
I have a title-less window, as I wanted to create a window style of my own.
The title and minimize, maximize and close buttons are in a dock panel. I have added the following event handler to maximize, restore and drag the window.
The problem comes when the window is maximized.
What I have found is that whenever I do a single click on the title is restores. When I only want it to restore if it is double clicked or dragged. I can see why it is happening but unsure how to resolve this.
public void TITLEBAR_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DockPanel dp = (DockPanel)sender;
Window parentWindow = Window.GetWindow(dp);
bool doubleClick = IsDoubleClick(sender, e);
if (e.ChangedButton == MouseButton.Left && e.LeftButton == MouseButtonState.Pressed && !doubleClick)
{
if (parentWindow.WindowState == WindowState.Maximized)
{
double mouseX = e.GetPosition(parentWindow).X;
double width = parentWindow.RestoreBounds.Width;
System.Drawing.Rectangle screenBounds = getCurrentScreenBounds(parentWindow);
double x = screenBounds.Left + (mouseX - ((width / 100.00) * ((100.00 / screenBounds.Width) * mouseX)));
if (x < 0)
{
x = 0;
}
else
{
if (x + width > screenBounds.Left + screenBounds.Width)
{
x = screenBounds.Left + screenBounds.Width - width;
}
}
parentWindow.Left = x;
parentWindow.Top = screenBounds.Top;
parentWindow.WindowState = System.Windows.WindowState.Normal;
}
parentWindow.DragMove();
//MessageBox.Show("");
}
if (doubleClick)
{
if (parentWindow.WindowState == System.Windows.WindowState.Maximized)
{
parentWindow.WindowState = System.Windows.WindowState.Normal;
}
else
{
parentWindow.WindowState = System.Windows.WindowState.Maximized;
}
}
}
Along with this class:
public static class MouseButtonHelper
{
private const long k_DoubleClickSpeed = 500;
private const double k_MaxMoveDistance = 10;
private static long _LastClickTicks = 0;
private static System.Windows.Point _LastPosition;
private static WeakReference _LastSender;
public static bool IsDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
System.Windows.Point position = e.GetPosition(null);
long clickTicks = DateTime.Now.Ticks;
long elapsedTicks = clickTicks - _LastClickTicks;
long elapsedTime = elapsedTicks / TimeSpan.TicksPerMillisecond;
bool quickClick = (elapsedTime <= k_DoubleClickSpeed);
bool senderMatch = (_LastSender != null && sender.Equals(_LastSender.Target));
if (senderMatch && quickClick && position.Distance(_LastPosition) <= k_MaxMoveDistance)
{
// Double click!
_LastClickTicks = 0;
_LastSender = null;
return true;
}
// Not a double click
_LastClickTicks = clickTicks;
_LastPosition = position;
if (!quickClick)
_LastSender = new WeakReference(sender);
return false;
}
private static double Distance(this System.Windows.Point pointA, System.Windows.Point pointB)
{
double x = pointA.X - pointB.X;
double y = pointA.Y - pointB.Y;
return Math.Sqrt(x * x + y * y);
}
}
And this to work out bounds of the current screen.
public static class WindowHelper
{
public static System.Drawing.Rectangle getCurrentScreenBounds(System.Windows.Window pWnd)
{
System.Windows.Forms.Screen parentScreen = GetCurrentScreen(pWnd);
if (parentScreen == null)
{
return System.Windows.Forms.Screen.PrimaryScreen.Bounds;
}
return parentScreen.Bounds;
}
private static System.Windows.Forms.Screen GetCurrentScreen(System.Windows.Window pWnd)
{
System.Drawing.Rectangle intersectingRect = new System.Drawing.Rectangle();
System.Drawing.Rectangle windowRect = new System.Drawing.Rectangle(Convert.ToInt32(pWnd.Left), Convert.ToInt32(pWnd.Top), Convert.ToInt32(pWnd.Width), Convert.ToInt32(pWnd.Height));
int largestIntersectingArea = 0;
System.Windows.Forms.Screen curScreen = null;
foreach (System.Windows.Forms.Screen s in System.Windows.Forms.Screen.AllScreens)
{
if (s.Bounds.IntersectsWith(windowRect))
{
intersectingRect = System.Drawing.Rectangle.Intersect(s.Bounds, windowRect);
int intersectingArea = intersectingRect.Width * intersectingRect.Height;
if (intersectingArea > largestIntersectingArea)
{
largestIntersectingArea = intersectingArea;
curScreen = s;
}
}
}
return curScreen;
}
}
There is a WPF element (control) named Thumb, I use that for making drag-able parts. It has a DragDelta event which you can use to examine HorizontalOffset and VerticalOffset of the drag-able part. You can save previous values and check if new values are the same or changed; which means it is being dragged.
(Just a suggestion which worked for me).
Ok so maybe someone will find this helpful.
I changed things around so that it recognizes the drag through two events, in the MouseMove and MouseLeftButtonDown events.
MouseLeftButtonDown captures a possible start position for drag in setStartPosition().
public void TITLEBAR_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DockPanel dp = (DockPanel)sender;
Window parentWindow = Window.GetWindow(dp);
doubleClick = IsDoubleClick(sender, e);
if (e.ChangedButton == MouseButton.Left && e.LeftButton == MouseButtonState.Pressed && !doubleClick)
{
if (parentWindow.WindowState == WindowState.Maximized)
{
setStartPosition(sender, e);
}
}
if (doubleClick)
{
if (parentWindow.WindowState == System.Windows.WindowState.Maximized)
{
parentWindow.WindowState = System.Windows.WindowState.Normal;
}
else
{
parentWindow.WindowState = System.Windows.WindowState.Maximized;
}
}
}
private void TITLEBAR_MouseMove(object sender, MouseEventArgs e)
{
DockPanel dp = (DockPanel)sender;
Window parentWindow = Window.GetWindow(dp);
if (e.LeftButton == MouseButtonState.Pressed)
{
if (IsDragging(sender, e) && !doubleClick)
{
if (parentWindow.WindowState == WindowState.Maximized)
{
double mouseX = e.GetPosition(parentWindow).X;
double width = parentWindow.RestoreBounds.Width;
System.Drawing.Rectangle screenBounds = getCurrentScreenBounds(parentWindow);
double x = screenBounds.Left + (mouseX - ((width / 100.00) * ((100.00 / screenBounds.Width) * mouseX)));
if (x < 0)
{
x = 0;
}
else
{
if (x + width > screenBounds.Left + screenBounds.Width)
{
x = screenBounds.Left + screenBounds.Width - width;
}
}
parentWindow.Left = x;
parentWindow.Top = screenBounds.Top;
parentWindow.WindowState = System.Windows.WindowState.Normal;
}
parentWindow.DragMove();
}
}
}
Here is the modified class:
public static class MouseButtonHelper
{
private const long k_DoubleClickSpeed = 500;
private const double k_MaxMoveDistance = 10;
private static long _LastClickTicks = 0;
private static System.Windows.Point _LastPosition;
private static WeakReference _LastSender;
private static System.Windows.Point _DragStartPosition;
public static bool IsDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
System.Windows.Point position = e.GetPosition(null);
long clickTicks = DateTime.Now.Ticks;
long elapsedTicks = clickTicks - _LastClickTicks;
long elapsedTime = elapsedTicks / TimeSpan.TicksPerMillisecond;
bool quickClick = (elapsedTime <= k_DoubleClickSpeed);
bool senderMatch = (_LastSender != null && sender.Equals(_LastSender.Target));
if (senderMatch && quickClick && position.Distance(_LastPosition) <= k_MaxMoveDistance)
{
// Double click!
_LastClickTicks = 0;
_LastSender = null;
return true;
}
// Not a double click
_LastClickTicks = clickTicks;
_LastPosition = position;
if (!quickClick)
_LastSender = new WeakReference(sender);
return false;
}
public static void setStartPosition(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
_DragStartPosition = e.GetPosition(null);
}
public static bool IsDragging(object sender, System.Windows.Input.MouseEventArgs e)
{
System.Windows.Point mousePos = e.GetPosition(null);
System.Windows.Vector diff = _DragStartPosition - mousePos;
if (Math.Abs(diff.X) > System.Windows.SystemParameters.MinimumHorizontalDragDistance || Math.Abs(diff.Y) > System.Windows.SystemParameters.MinimumVerticalDragDistance)
{
return true;
}
return false;
}
private static double Distance(this System.Windows.Point pointA, System.Windows.Point pointB)
{
double x = pointA.X - pointB.X;
double y = pointA.Y - pointB.Y;
return Math.Sqrt(x * x + y * y);
}
}