I am a beginner.
I'm working on a drawing wpf project. I draw lines in a canvas control. I want to control zooming and panning. I save the lines in a list with the actual coordinates which I transform to display them.
It almost works.
On the other hand I don't understand why some lines are drawn outside the canvas?
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using static System.Net.Mime.MediaTypeNames;
namespace WPFcanvasZoomMove
{
public partial class MainWindow : Window
{
const double _tX = 1;
const double _tY = -1;
double _originX;
double _originY;
double _zoom;
List<Element> _elements;
public MainWindow()
{
InitializeComponent();
//RenderOptions.ProcessRenderMode=
_zoom = 1;
CanvasModel.Background = new SolidColorBrush(Colors.Black);
CanvasModel.MouseMove += CanvasModel_MouseMove;
CanvasModel.MouseWheel += CanvasModel_MouseWheel;
_elements = new List<Element>();
Element e;
e = new Element(new Point(-500, 0), new Point(500, 0), new SolidColorBrush(Colors.Blue), 2);
_elements.Add(e);
e = new Element(new Point(0, -500), new Point(0, 500), new SolidColorBrush(Colors.Blue), 2);
_elements.Add(e);
e = new Element(new Point(50, 70), new Point(100, 30), new SolidColorBrush(Colors.Red), 4);
_elements.Add(e);
//e = new Element(new Point(125, 60), new Point(175, -70), new SolidColorBrush(Colors.Green), 10);
//_elements.Add(e);
}
protected override void OnRender(DrawingContext drawingContext)
{
CanvasModel.BringIntoView();
Redraw();
}
private void MainWindow_Load(object sender, RoutedEventArgs e)
{
//_originX = CanvasModel.ActualWidth / 2;
//_originY = CanvasModel.ActualHeight / 2;
_originX = 75;
_originY = 130;
lblMouseZoomFactor.Content = $"fZ={_zoom.ToString()}";
lblMouseDeltaX.Content = $"dX={_originX.ToString()}";
lblMouseDeltaY.Content = $"dY={_originY.ToString()}";
Redraw();
}
public void Redraw()
{
DrawLine();
}
public void DrawLine()
{
CanvasModel.Children.Clear();
// Dessiner
foreach (Element e in _elements)
{
//CanvasModel.Children.Add(e.ToWorld(_dX,_dY,_zoom));
//CanvasModel.Children.Add(e.ToWorld(_originX, _originY, _zoom));
//CanvasModel.Children.Add(e.ToModel());
CanvasModel.Children.Add(e.ToWorld(_originX, _originY, _zoom));
}
}
private void CanvasModel_MouseMove(object sender, MouseEventArgs e)
{
//Matrice de transformation
Matrix m;
//Position de la souris dans le canvas (coordonnées wpf)
Point ptCanvas = e.GetPosition(this.CanvasModel);
lblMouseCanvasPositionX.Content = $"Xc={ptCanvas.X.ToString()}";
lblMouseCanvasPositionY.Content = $"Yc={ptCanvas.Y.ToString()}";
//Position de la souris dans le Model
//Translation par rapport à l'origine
m = new Matrix();
m.Translate(-_originX, -_originY);
Point ptModel = m.Transform(ptCanvas);
ptModel=new Point(ptModel.X, -ptModel.Y);
lblMouseModelPositionX.Content = $"Xm={ptModel.X.ToString()}";
lblMouseModelPositionY.Content = $"Ym={ptModel.Y.ToString()}";
//Position de la souris dans le World
//Echelle par rapport au zoom
m = new Matrix();
m.ScaleAt(_zoom, _zoom, 0, 0);
Point ptW = m.Transform(ptModel);
lblMouseWorldPositionX.Content = $"Xw={ptW.X.ToString()}";
lblMouseWorldPositionY.Content = $"Yw={ptW.Y.ToString()}";
Redraw();
}
private void CanvasModel_MouseWheel(object sender, MouseWheelEventArgs e)
{
//Debug.WriteLine($"e.delta={e.Delta}");
double kz = 1200;
_zoom += e.Delta / kz;
lblMouseZoomFactor.Content = $"fZ={_zoom.ToString()}";
Redraw();
}
}
public class Element
{
private Point _PointWorldStart;
public Point PointWorldStart
{
get { return _PointWorldStart; }
set { _PointWorldStart = value; }
}
private Point _PointWorldEnd;
public Point PointWorldEnd
{
get { return _PointWorldEnd; }
set { _PointWorldEnd = value; }
}
private Point _PointModelStart;
public Point PointModelStart
{
get { return _PointModelStart; }
set { _PointModelStart = value; }
}
private Point _PointModelEnd;
public Point PointModelEnd
{
get { return _PointModelEnd; }
set { _PointModelEnd = value; }
}
private SolidColorBrush _Brush;
public SolidColorBrush Brush
{
get { return _Brush; }
set { _Brush = value; }
}
private int _Thickness;
public int Thickness
{
get { return _Thickness; }
set { _Thickness = value; }
}
public Element()
{
_PointWorldStart = new Point(0,0);
_PointWorldEnd = new Point(0, 0);
//_SolidColorBrush = new SolidColorBrush(Color.FromRgb(0, 0, 255));
_Brush = new SolidColorBrush(Colors.Black);
_Thickness = 1;
}
public Element(Point PointStart, Point PointEnd, SolidColorBrush Brush, int Thickness)
{
_PointWorldStart = PointStart;
_PointWorldEnd = PointEnd;
_Brush = Brush;
_Thickness = Thickness;
}
public Line ToModel()
{
Line l = new Line();
l.X1 = _PointWorldStart.X;
l.Y1 = _PointWorldStart.Y;
l.X2 = _PointWorldEnd.X;
l.Y2 = _PointWorldEnd.Y;
l.StrokeThickness = _Thickness;
l.Stroke = _Brush;
return l;
}
public Line ToWorld(double deltaX, double deltaY, double zoomFactor)
{
Line l = new Line();
l.X1 = ConvertPoint.ToWorld(_PointWorldStart, deltaX, deltaY, zoomFactor).X;
l.Y1 = ConvertPoint.ToWorld(_PointWorldStart, deltaX, deltaY, zoomFactor).Y;
l.X2 = ConvertPoint.ToWorld(_PointWorldEnd, deltaX, deltaY, zoomFactor).X;
l.Y2 = ConvertPoint.ToWorld(_PointWorldEnd, deltaX, deltaY, zoomFactor).Y;
l.StrokeThickness = _Thickness;
l.Stroke = _Brush;
return l;
}
}
static class ConvertPoint
{
public static Point ToWorld(Point Point, double deltaX, double deltaY, double zoomFactor)
{
Matrix m;
Point p = new Point(Point.X,-Point.Y);
m = new Matrix();
m.Translate(deltaX,deltaY);
p = m.Transform(p);
m = new Matrix();
m.ScaleAt(zoomFactor, zoomFactor, 0, 0);
p = m.Transform(p);
Debug.WriteLine($"p={p.ToString()}");
return p;
}
}
}
I would like the drawing to stay in the canvas.
Related
I have a multi monitor setup and I want to paint a vertical and horizontal line as the user moves their cursor. The lines I want to paint should span all monitors. I'm not entirely sure how to adjust my form to make this possible since when i make it full screen it only maximizes to one monitor.
Do i have to make a form per monitor and send signals to each one when the cursor moves for it to repaint the line?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace fitAllScreens
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
FullScreen();
}
public void FullScreen()
{
List<int> xBounds = new List<int>() {};
List<int> yBounds = new List<int>() {};
foreach (Screen screen in Screen.AllScreens)
{
var bounds = screen.Bounds;
xBounds.Add(bounds.X);
xBounds.Add(bounds.Right);
yBounds.Add(bounds.Y);
yBounds.Add(bounds.Bottom);
}
int minX = xBounds.Min();
int maxX = xBounds.Max();
int minY = yBounds.Min();
int maxY = yBounds.Max();
Console.WriteLine(minX + " - " + maxX + " - " + minY + " - " + maxY);
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
var graphics = e.Graphics;
base.OnPaint(e);
// Draw ruler guides
Console.WriteLine(Cursor.Position);
var pos = this.PointToClient(Cursor.Position);
using (var pen = new Pen(Color.Red))
{
pen.DashStyle = DashStyle.Dot;
var screenBounds = Screen.PrimaryScreen.Bounds;
graphics.DrawLine(pen, pos.X, screenBounds.Y, pos.X, screenBounds.Height);
graphics.DrawLine(pen, screenBounds.X, pos.Y, screenBounds.Width, pos.Y);
}
}
}
}
I edited your code so it can fit all screens (I test it on 2 screens and it worked well).
public partial class Form1 : Form
{
int minX;
int maxX;
int minY;
int maxY;
public Form1()
{
InitializeComponent();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.FormBorderStyle = FormBorderStyle.None;
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.DoubleBuffered = true;
FullScreen();
CreateCloseButtons();
}
private void CloseButtons_Click(object sender, EventArgs e)
{
Application.Exit();
}
public void FullScreen()
{
List<int> xBounds = new List<int>() { };
List<int> yBounds = new List<int>() { };
foreach (Screen screen in Screen.AllScreens)
{
var bounds = screen.WorkingArea;
xBounds.Add(bounds.X);
xBounds.Add(bounds.Right);
yBounds.Add(bounds.Y);
yBounds.Add(bounds.Bottom);
}
minX = xBounds.Min();
maxX = xBounds.Max();
minY = yBounds.Min();
maxY = yBounds.Max();
this.Location = new Point(minX, minY);
//this.Location = this.PointToClient(new Point(minX, minY));
this.Size = new Size(maxX - minX, maxY - minY);
}
protected override void OnMouseMove(MouseEventArgs e)
{
Console.WriteLine(this.Location.X + " - " + this.Location.Y);
Console.WriteLine(this.Size.Width + " - " + this.Location.Y);
base.OnMouseMove(e);
Invalidate(false);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var pos = this.PointToClient(Cursor.Position);
using (var pen = new Pen(Color.Red))
{
pen.Width = 2;
pen.DashStyle = DashStyle.Dot;
e.Graphics.DrawLine(pen, pos.X, minY, pos.X, this.Height);
e.Graphics.DrawLine(pen, minX, pos.Y, this.Width, pos.Y);
}
}
private void CreateCloseButtons()
{
Button button1 = new System.Windows.Forms.Button();
Button button2 = new System.Windows.Forms.Button();
Button button3 = new System.Windows.Forms.Button();
Button button4 = new System.Windows.Forms.Button();
button1.Click += CloseButtons_Click;
button2.Click += CloseButtons_Click;
button3.Click += CloseButtons_Click;
button4.Click += CloseButtons_Click;
//
// top right
//
button1.BackColor = System.Drawing.Color.Red;
button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
button1.ForeColor = System.Drawing.SystemColors.ButtonFace;
button1.Location = new System.Drawing.Point(0, 0);
button1.Name = "button1";
button1.Size = new System.Drawing.Size(21, 23);
button1.TabIndex = 0;
button1.Text = "X";
button1.UseVisualStyleBackColor = false;
//
// bottom left
//
button2.BackColor = System.Drawing.Color.Red;
button2.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
button2.ForeColor = System.Drawing.SystemColors.ButtonFace;
button2.Location = new System.Drawing.Point(0, this.Height - 23);
button2.Name = "button2";
button2.Size = new System.Drawing.Size(21, 23);
button2.TabIndex = 1;
button2.Text = "X";
button2.UseVisualStyleBackColor = false;
button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
//
// bottom right
//
button3.BackColor = System.Drawing.Color.Red;
button3.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
button3.ForeColor = System.Drawing.SystemColors.ButtonFace;
button3.Location = new System.Drawing.Point(this.Width - 21, this.Height - 23);
button3.Name = "button3";
button3.Size = new System.Drawing.Size(21, 23);
button3.TabIndex = 2;
button3.Text = "X";
button3.UseVisualStyleBackColor = false;
button3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
//
// top right
//
button4.BackColor = System.Drawing.Color.Red;
button4.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
button4.ForeColor = System.Drawing.SystemColors.ButtonFace;
button4.Location = new System.Drawing.Point(this.Width - 21, 0);
button4.Name = "button4";
button4.Size = new System.Drawing.Size(21, 23);
button4.TabIndex = 3;
button4.Text = "X";
button4.UseVisualStyleBackColor = false;
button4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.Controls.Add(button4);
this.Controls.Add(button3);
this.Controls.Add(button2);
this.Controls.Add(button1);
}
}
Hi I've C# forms application. I want to Load an Image into a picturebox and Drag the Image where I want. When I'm done with Dragging I added a checkbox
to let users to click on a checkbox.
Then, user can use mouse to select a portion of image. That portion will be shown inside another picturebox. So, I did some search and came up with a solution
which actually doesn't work.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace HCRLibrarytest
{
public partial class MainForm : Form
{
private Point startingPoint = Point.Empty;
private Point movingPoint = Point.Empty;
private bool panning = false;
Image _OrginalBitmap;
Image _NewBitmap;
private bool IsSelecting = false;
private int X0, Y0, X1, Y1;
static bool isimagepositioned = false;
public MainForm()
{
InitializeComponent();
}
private void btn_openimage_Click(object sender, EventArgs e)
{
OpenFileDialog dialog2 = new OpenFileDialog
{
Filter = "Bitmap Image (*.jpeg)|*.jpeg"
};
using (OpenFileDialog dialog = dialog2)
{
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
using (StreamReader reader = new StreamReader(dialog.FileName))
{
this._OrginalBitmap = new Bitmap(dialog.FileName);
this.pb_fullimage.Image = this._OrginalBitmap;
}
}
catch (Exception exception)
{
MessageBox.Show(exception.ToString());
}
}
}
}
private void pb_fullimage_MouseUp(object sender, MouseEventArgs e)
{
if (_OrginalBitmap != null)
{
if(!isimagepositioned)
{
panning = false;
}
else
{
if (!IsSelecting) return;
IsSelecting = false;
pb_fullimage.Image = _OrginalBitmap;
int wid = Math.Abs(X0 - X1);
int hgt = Math.Abs(Y0 - Y1);
if ((wid < 1) || (hgt < 1)) return;
Bitmap area = new Bitmap(wid, hgt);
using (Graphics gr = Graphics.FromImage(area))
{
Rectangle source_rectangle = new Rectangle(Math.Min(X0, X1), Math.Min(Y0, Y1), wid, hgt);
Rectangle dest_rectangle = new Rectangle(0, 0, wid, hgt);
gr.DrawImage(pb_fullimage.Image, dest_rectangle, source_rectangle, GraphicsUnit.Pixel);
}
pb_selectedportion.Image = area;
}
}
}
private void pb_fullimage_MouseDown(object sender, MouseEventArgs e)
{
if (_OrginalBitmap != null)
{
if (!isimagepositioned)
{
panning = true;
startingPoint = new Point(e.Location.X - movingPoint.X,e.Location.Y - movingPoint.Y);
}
else
{
_NewBitmap = new Bitmap(pb_fullimage.Image);
IsSelecting = true;
X0 = e.X;
Y0 = e.Y;
}
}
}
private void pb_fullimage_MouseMove(object sender, MouseEventArgs e)
{
if (_OrginalBitmap != null)
{
if (!isimagepositioned)
{
if (panning)
{
movingPoint = new Point(e.Location.X - startingPoint.X,e.Location.Y - startingPoint.Y);
pb_fullimage.Invalidate();
}
}
else
{
if (!IsSelecting) return;
X1 = e.X;
Y1 = e.Y;
Bitmap bm = new Bitmap(_NewBitmap);
using (Graphics gr = Graphics.FromImage(bm))
{
gr.DrawRectangle(Pens.Red, Math.Min(X0, X1), Math.Min(Y0, Y1), Math.Abs(X0 - X1), Math.Abs(Y0 - Y1));
}
pb_fullimage.Image = bm;
}
}
}
private void pb_fullimage_Paint(object sender, PaintEventArgs e)
{
if (_OrginalBitmap != null && !isimagepositioned)
{
e.Graphics.Clear(Color.White);
e.Graphics.DrawImage(_OrginalBitmap, movingPoint);
}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
isimagepositioned = true;
}
else
{
isimagepositioned = false;
}
}
}
}
when I drag and check 'Image Positioned' and select using mouse move. It always gives me the the image that is relative to the original image position.
So, Can somebody help to fix this.
Since nobody answered me, I found an answer. This worked for me.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace HCRLibrarytest
{
public partial class MainForm : Form
{
public Point startingPoint = Point.Empty;
public Point movingPoint = Point.Empty;
public bool panning = false;
Image _OrginalBitmap;
public static Image _NewBitmap;
public bool IsSelecting = false;
public int X0, Y0, X1, Y1;
public MainForm()
{
InitializeComponent();
}
public void btn_openimage_Click(object sender, EventArgs e)
{
OpenFileDialog dialog2 = new OpenFileDialog
{
Filter = "Bitmap Image (*.jpeg)|*.jpeg"
};
using (OpenFileDialog dialog = dialog2)
{
if (dialog.ShowDialog() == DialogResult.OK)
{
try
{
using (StreamReader reader = new StreamReader(dialog.FileName))
{
this._OrginalBitmap = new Bitmap(dialog.FileName);
this.pb_fullimage.Image = this._OrginalBitmap;
}
}
catch (Exception exception)
{
MessageBox.Show(exception.ToString());
}
}
}
}
public void pb_fullimage_MouseUp(object sender, MouseEventArgs e)
{
if (pb_fullimage.Image != null)
{
if (!checkBox1.Checked)
{
panning = false;
}
else
{
if (!IsSelecting) return;
IsSelecting = false;
pb_fullimage.Image = _NewBitmap;
int wid = Math.Abs(X0 - X1);
int hgt = Math.Abs(Y0 - Y1);
if ((wid < 1) || (hgt < 1)) return;
Bitmap area = new Bitmap(wid, hgt);
using (Graphics gr = Graphics.FromImage(area))
{
Rectangle source_rectangle = new Rectangle(Math.Min(X0, X1), Math.Min(Y0, Y1), wid, hgt);
Rectangle dest_rectangle = new Rectangle(0, 0, wid, hgt);
gr.DrawImage(_NewBitmap, dest_rectangle, source_rectangle, GraphicsUnit.Pixel);
}
pb_selectedportion.Image = area;
}
}
}
public void pb_fullimage_MouseDown(object sender, MouseEventArgs e)
{
if (pb_fullimage.Image != null)
{
if (!checkBox1.Checked)
{
panning = true;
startingPoint = new Point(e.Location.X - movingPoint.X, e.Location.Y - movingPoint.Y);
}
else
{
IsSelecting = true;
X0 = e.X;
Y0 = e.Y;
}
}
}
public void pb_fullimage_MouseMove(object sender, MouseEventArgs e)
{
if (pb_fullimage.Image != null)
{
if (!checkBox1.Checked)
{
if (panning)
{
movingPoint = new Point(e.Location.X - startingPoint.X, e.Location.Y - startingPoint.Y);
pb_fullimage.Invalidate();
using (Bitmap bitmap = new Bitmap(pb_fullimage.ClientSize.Width, pb_fullimage.ClientSize.Height))
{
pb_fullimage.DrawToBitmap(bitmap, pb_fullimage.ClientRectangle);
try { bitmap.Save(AppDomain.CurrentDomain.BaseDirectory + "draw.jpg"); }
catch (Exception ex) { Console.Write(ex.ToString()); }
}
}
}
else
{
if (!IsSelecting) return;
X1 = e.X;
Y1 = e.Y;
Bitmap bm = new Bitmap(Bitmap.FromStream(File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "draw.jpg"))));
using (Graphics gr = Graphics.FromImage(bm))
{
gr.DrawRectangle(Pens.WhiteSmoke, Math.Min(X0, X1), Math.Min(Y0, Y1), Math.Abs(X0 - X1), Math.Abs(Y0 - Y1));
}
_NewBitmap = bm;
}
}
}
public void pb_fullimage_Paint(object sender, PaintEventArgs e)
{
if (pb_fullimage.Image != null && !checkBox1.Checked)
{
e.Graphics.Clear(Color.White);
e.Graphics.DrawImage(pb_fullimage.Image, movingPoint);
}
}
}
}
I am using Windows Form application and using one button to generate random number and draw on form. when button is clicked, It is adding a random number using Graphics.Drawing method. Problem is when I hit the button first time it works fine and add a random number i.e 11111. When I hit button again it will add a new random number (on next position) but it will also change previous numbers to new generated random number.
Updated: (Added Complete Code)
Edit: I have moved Random outside of scoop so now it does not generate same number but still its changing old random numbers to other ones.
Main Class:
using System;
using System.Collections;
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 DrawingText
{
public partial class Form1 : Form
{
private Point mouseDownPosition = new Point(0, 0);
private Point mouseMovePosition = new Point(0, 0);
private int mousePressdDown;
private ArrayList drawnItemsList;
Random rnd;
public Form1()
{
InitializeComponent();
drawnItemsList = new ArrayList();
this.rnd = new Random();
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
mouseMovePosition = e.Location;
if (e.Button == MouseButtons.Left)
mousePressdDown = 1;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
mouseDownPosition = e.Location;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (mousePressdDown == 1)
{
label1.Text = "X: " + mouseMovePosition.X.ToString();
label2.Text = "Y: " + mouseMovePosition.Y.ToString();
this.Invalidate();
}
DrawingData a = new DrawingData(mouseMovePosition, mouseDownPosition);
drawnItemsList.Add(a);
mousePressdDown = 0;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
foreach (DrawingData a in drawnItemsList)
{
draw(e.Graphics, a.old, a.cur);
}
draw(e.Graphics, mouseDownPosition, mouseMovePosition);
}
private void draw(Graphics e, Point mold, Point mcur)
{
Pen p = new Pen(Color.Black, 2);
using (Font useFont = new Font("Gotham Medium", 28, FontStyle.Bold))
{
string header2 = rnd.Next().ToString();
RectangleF header2Rect = new RectangleF();
int moldX = mold.X - 5;
int moldY = mold.Y;
header2Rect.Location = new Point(moldX, moldY);
header2Rect.Size = new Size(600, ((int)e.MeasureString(header2, useFont, 600, StringFormat.GenericTypographic).Height));
e.DrawString(header2, useFont, Brushes.Black, header2Rect);
}
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}
Drawing Data Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace DrawingText
{
[Serializable]
class DrawingData
{
private Point mold; // mouseDown position
private Point mcur; // mouseUp poslition
public DrawingData()
{
mold = new Point(0, 0);
mcur = new Point(0, 0);
}
public DrawingData(Point old, Point cur)
{
mold = old;
mcur = cur;
}
public Point old
{
get
{
return mold;
}
set
{
mold = value;
}
}
public Point cur
{
get
{
return mcur;
}
set
{
mcur = value;
}
}
}
}
3 times button clicked and it replaced old value with new one:
You need to store the random value with the point values in the DrawingData class, like this:
Main Class:
namespace DrawingText
{
public partial class Form1 : Form
{
private Point mouseDownPosition = new Point(0, 0);
private Point mouseMovePosition = new Point(0, 0);
private int mousePressdDown;
private ArrayList drawnItemsList;
Random rnd;
public Form1()
{
InitializeComponent();
drawnItemsList = new ArrayList();
this.rnd = new Random();
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (mousePressdDown == 1)
{
label1.Text = "X: " + mouseMovePosition.X.ToString();
label2.Text = "Y: " + mouseMovePosition.Y.ToString();
this.Invalidate();
}
DrawingData a = new DrawingData(mouseMovePosition, mouseDownPosition, rnd.Next().ToString());
drawnItemsList.Add(a);
mousePressdDown = 0;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
foreach (DrawingData a in drawnItemsList)
{
draw(e.Graphics, a);
}
draw(e.Graphics, mouseDownPosition, mouseMovePosition);
}
private void draw(Graphics e, DrawingData a)
{
Pen p = new Pen(Color.Black, 2);
using (Font useFont = new Font("Gotham Medium", 28, FontStyle.Bold))
{
RectangleF header2Rect = new RectangleF();
int moldX = a.old.X - 5;
int moldY = a.old.Y;
header2Rect.Location = new Point(moldX, moldY);
header2Rect.Size = new Size(600, ((int)e.MeasureString(header2, useFont, 600, StringFormat.GenericTypographic).Height));
e.DrawString(a.Rand, useFont, Brushes.Black, header2Rect);
}
}
}
}
Drawing Data Class:
namespace DrawingText
{
[Serializable]
public class DrawingData
{
private Point mold; // mouseDown position
private Point mcur; // mouseUp poslition
private string randValue; // random data value
public DrawingData()
{
mold = new Point(0, 0);
mcur = new Point(0, 0);
randValue = String.Empty;
}
public DrawingData(Point old, Point cur, string rand)
{
mold = old;
mcur = cur;
randValue = rand;
}
public Point old
{
get
{
return mold;
}
set
{
mold = value;
}
}
public Point cur
{
get
{
return mcur;
}
set
{
mcur = value;
}
}
public sting Rand
{
get
{
return randValue;
}
set
{
randValue = value;
}
}
}
You are recreating your random each time in the loop which will cause it to have the same seed, and the same first number. That's why all your numbers are the same. You should.
Move your random outside of the method and loop, and use it instead. Change the line Random rnd = new Random() to rnd = new Random(). You already have a variable in the class to hold the random.
If you want the previous random numbers to remain the same as the last time, you need to store them in a list somewhere and draw them on paint. You are currently creating a new set of random numbers each time.
This is made on the fly using graphics path:
GraphicsPath gp;
int moldX = 10;
int moldY = 10;
public Form1()
{
InitializeComponent();
gp = new GraphicsPath();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.FillPath(Brushes.Black, gp);
// if you want the numbers outlined do e.Graphics.DrawPath
}
private void button1_Click(object sender, EventArgs e)
{
AddToPath();
Invalidate();
}
private void AddToPath()
{
using (Font useFont = new Font("Gotham Medium", 28, FontStyle.Bold))
{
Random rnd = new Random();
string header2 = rnd.Next().ToString();
int strsize = TextRenderer.MeasureText(header2, useFont).Height;
StringFormat format = StringFormat.GenericDefault;
gp.AddString(header2, useFont.FontFamily, 1, 28, new Point(moldX, moldY), format);
moldX += 5;
moldY += strsize;
}
}
This is the code:
private void hsMagnfier_OnMouseDown(object sender)
{
int x = mLastCursorPosition.X;
int y = mLastCursorPosition.Y;
MagnifierForm magnifier = new MagnifierForm(mConfiguration, System.Windows.Forms.Cursor.Position);//mLastCursorPosition);
magnifier.Show();
}
This code above is in a Form which I can drag over the screen.
Then when I click on an icon it's doing the magnifier.Show(); and the magnifier form is shown up where the mouse current position is.
But if I click on it again so now the position of the new form the magnifier is in my Form1 center. And not where the mouse current position as in the first time.
This is the MagnifierForm code maybe first time it's in the current mouse position but in the next time/s it's in the center of Form1 ?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.IO;
using System.Drawing.Imaging;
namespace ScreenVideoRecorder
{
public partial class MagnifierForm : Form
{
public MagnifierForm(Configuration configuration, Point startPoint)
{
InitializeComponent();
//--- My Init ---
mConfiguration = configuration;
FormBorderStyle = FormBorderStyle.None;
ShowInTaskbar = mConfiguration.ShowInTaskbar;
TopMost = mConfiguration.TopMostWindow;
Width = mConfiguration.MagnifierWidth;
Height = mConfiguration.MagnifierHeight;
// Make the window (the form) circular
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(ClientRectangle);
Region = new Region(gp);
mImageMagnifier = Properties.Resources.magnifierGlass;
mTimer = new Timer();
mTimer.Enabled = true;
mTimer.Interval = 20;
mTimer.Tick += new EventHandler(HandleTimer);
mScreenImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
mStartPoint = startPoint;
mTargetPoint = startPoint;
if (mConfiguration.ShowInTaskbar)
ShowInTaskbar = true;
else
ShowInTaskbar = false;
}
protected override void OnShown(EventArgs e)
{
RepositionAndShow();
}
private delegate void RepositionAndShowDelegate();
private void RepositionAndShow()
{
if (InvokeRequired)
{
Invoke(new RepositionAndShowDelegate(RepositionAndShow));
}
else
{
// Capture the screen image now!
Graphics g = Graphics.FromImage(mScreenImage);
g.CopyFromScreen(0, 0, 0, 0, new Size(mScreenImage.Width, mScreenImage.Height));
g.Dispose();
if (mConfiguration.HideMouseCursor)
Cursor.Hide();
else
Cursor = Cursors.Cross;
Capture = true;
if (mConfiguration.RememberLastPoint)
{
mCurrentPoint = mLastMagnifierPosition;
Cursor.Position = mLastMagnifierPosition;
Left = (int)mCurrentPoint.X - Width / 2;
Top = (int)mCurrentPoint.Y - Height / 2;
}
else
{
mCurrentPoint = Cursor.Position;
}
Show();
}
}
void HandleTimer(object sender, EventArgs e)
{
float dx = mConfiguration.SpeedFactor * (mTargetPoint.X - mCurrentPoint.X);
float dy = mConfiguration.SpeedFactor * (mTargetPoint.Y - mCurrentPoint.Y);
if (mFirstTime)
{
mFirstTime = false;
mCurrentPoint.X = mTargetPoint.X;
mCurrentPoint.Y = mTargetPoint.Y;
Left = (int)mCurrentPoint.X - Width / 2;
Top = (int)mCurrentPoint.Y - Height / 2;
return;
}
mCurrentPoint.X += dx;
mCurrentPoint.Y += dy;
if (Math.Abs(dx) < 1 && Math.Abs(dy) < 1)
{
mTimer.Enabled = false;
}
else
{
// Update location
Left = (int)mCurrentPoint.X - Width / 2;
Top = (int)mCurrentPoint.Y - Height / 2;
mLastMagnifierPosition = new Point((int)mCurrentPoint.X, (int)mCurrentPoint.Y);
}
Refresh();
}
protected override void OnMouseDown(MouseEventArgs e)
{
mOffset = new Point(Width / 2 - e.X, Height / 2 - e.Y);
mCurrentPoint = PointToScreen(new Point(e.X + mOffset.X, e.Y + mOffset.Y));
mTargetPoint = mCurrentPoint;
mTimer.Enabled = true;
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (mConfiguration.CloseOnMouseUp)
{
Close();
mScreenImage.Dispose();
}
Cursor.Show();
Cursor.Position = mStartPoint;
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mTargetPoint = PointToScreen(new Point(e.X + mOffset.X, e.Y + mOffset.Y));
mTimer.Enabled = true;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
if (mConfiguration.DoubleBuffered)
{
// Do not paint background (required for double buffering)!
}
else
{
base.OnPaintBackground(e);
}
}
protected override void OnPaint(PaintEventArgs e)
{
if (mBufferImage == null)
{
mBufferImage = new Bitmap(Width, Height);
}
Graphics bufferGrf = Graphics.FromImage(mBufferImage);
Graphics g;
if (mConfiguration.DoubleBuffered)
{
g = bufferGrf;
}
else
{
g = e.Graphics;
}
if (mScreenImage != null)
{
Rectangle dest = new Rectangle(0, 0, Width, Height);
int w = (int)(Width / mConfiguration.ZoomFactor);
int h = (int)(Height / mConfiguration.ZoomFactor);
int x = Left - w / 2 + Width / 2;
int y = Top - h / 2 + Height / 2;
g.DrawImage(
mScreenImage,
dest,
x, y,
w, h,
GraphicsUnit.Pixel);
}
if (mImageMagnifier != null)
{
g.DrawImage(mImageMagnifier, 0, 0, Width, Height);
}
if (mConfiguration.DoubleBuffered)
{
e.Graphics.DrawImage(mBufferImage, 0, 0, Width, Height);
}
}
//--- Data Members ---
#region Data Members
private Timer mTimer;
private Configuration mConfiguration;
private Image mImageMagnifier;
private Image mBufferImage = null;
private Image mScreenImage = null;
private Point mStartPoint;
private PointF mTargetPoint;
private PointF mCurrentPoint;
private Point mOffset;
private bool mFirstTime = true;
private static Point mLastMagnifierPosition = Cursor.Position;
#endregion
}
}
The first time the new Form the magnifier is shown up where my mouse cursour is.
The next time i click on it's showing the magnifier form in the center of Form1 and not where the mouse cursour is.
Why is that ? When i clikc on the icon again it's still doing the
System.Windows.Forms.Cursor.Position
Again. Strange.
Consider you have two forms - Master and Child
If you are calling Child from Master on MouseUp event(for example), write the code in MouseUp event of Master form
ChildForm obj=new ChildForm();
obj.pntLocation = new Point(Cursor.Position.X, Cursor.Position.Y);
obj.ShowDialog();
Declare a variable inside the Child for location
public Point pntLocation;
Now set location inside the Form_Load of Child
this.Location = pntLocation;
Ok found that the part that doing it is here in the Magnifier form:
mConfiguration.RememberLastPoint = false;
if (mConfiguration.RememberLastPoint)
{
mCurrentPoint = mLastMagnifierPosition;
Cursor.Position = mLastMagnifierPosition;
Left = (int)mCurrentPoint.X - Width / 2;
Top = (int)mCurrentPoint.Y - Height / 2;
}
else
{
mCurrentPoint = Cursor.Position;
}
So I added for now the line: mConfiguration.RememberLastPoint = false; which did the job for now.
Greetings
I genereated a terrain with this equation:
H(x,y) = (abs(sin(x * y)) + abs(sin(0,2 * x) + sin(0,4 * y)) + abs(cos(0,12 * x) + cos(0,47 * y))) * e^(0.005*(x+y))
Now, this gives me a mix of featuresize, and a nice slope. This works fine, when I plot it using scilab.
I tried to import this in a c# application.
The terrain is created in this code:
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX;
using System.Collections.Generic;
namespace Kamera_eins
{
public partial class Terrain : Form
{
public double[,] DTM;
string response ;
public Terrain()
{
InitializeComponent();
response = "";
DTM = new double[2048/4,2048/4];
}
public void BoxTheSky()
{
}
public void BoxTheLand()
{
mesh();
surf();
}
public void begin()
{
}
public void mesh()
{
response = "";
int i = new int();
int j = new int();
i = 0;
j = 0;
for (i=0;i<2048/4 ;i++ ) {
for (j=0;j<2048/4 ;j++ ) {
DTM[i,j] = Math.Abs (Math.Sin (j*i)) + Math.Abs(Math.Sin(0.2*i) * Math.Sin(0.4*j) ) + Math.Abs(Math.Cos(0.12* i) * Math.Cos(0.47*j));
DTM[i,j] = Math.Pow(Math.E, (0.012* (i + j)));
}
}
response = "DTM mesh ready";
}
public void surf()
{
}
}
}
This is kept in a file called terrain.cs, and i make this a winform, because i plan to add a simple textbox, where i can later make some sort of realtime log of the process.
Now, there is another file, and in that file, intend to display this terrain. this second file goes as follows:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Data;
using System.IO;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX.DirectInput;
namespace Kamera_eins
{
public class viewport : Form
{
public Microsoft.DirectX.Direct3D.Device device = null;
public PresentParameters presentparameter = new PresentParameters();
public bool device_exists;
public bool show;
public int HEIGHT;
public int WIDTH;
public string paintDesc;
private float angle ;
private CustomVertex.PositionColored[] vertices;
public double[,] heightData;
private int[] indices;
private IndexBuffer ib;
private VertexBuffer vb;
private Microsoft.DirectX.DirectInput.Device keyb;
//public
public viewport()
{
this.ClientSize = new System.Drawing.Size(600, 600);
this.Text = "Terrain viewport";
WIDTH = 2048 / 4;
HEIGHT = 2048 / 4;
heightData = new double[HEIGHT,WIDTH];
keyb = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard);
keyb.SetCooperativeLevel(this, CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);
keyb.Acquire();
presentparameter.Windowed = true;
presentparameter.SwapEffect = SwapEffect.Discard;
presentparameter.AutoDepthStencilFormat = DepthFormat.D16;
presentparameter.EnableAutoDepthStencil = true;
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
try {
device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentparameter);
device.DeviceLost += new EventHandler(this.InvalidateDeviceObjects);
device.DeviceReset += new EventHandler(this.RestoreDeviceObjects);
device.Disposing += new EventHandler(this.DeleteDeviceObjects);
device.DeviceResizing += new CancelEventHandler(this.EnvironmentResizing);
device_exists = true;
} catch (Exception DirectException) {
device_exists = false;
}
}
private void setcamera()
{
device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1f, 50f);
device.Transform.View = Matrix.LookAtLH (new Vector3(0, 0, 100), new Vector3(0, 0, 0) , new Vector3(0,0,1) );
device.RenderState.Lighting = false;
device.RenderState.FillMode = FillMode.WireFrame;
device.RenderState.CullMode = Cull.None;
}
public void declareVertex()
{
vb = new VertexBuffer(typeof(CustomVertex.PositionColored), HEIGHT*WIDTH, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Default);
vertices = new CustomVertex.PositionColored[HEIGHT*WIDTH];
for (int x=0;x< WIDTH;x++) {
for (int y=0; y< HEIGHT;y++) {
vertices[x + y * WIDTH].Position = new Vector3(x, y, (float)heightData[x,y]);
int r = Convert.ToInt32(205 * heightData[x,y] / 200 );
if(r>254)
r = 254;
vertices[x + y * WIDTH].Color = Color.FromArgb( r , 120 , 120).ToArgb();
}
}
vb.SetData(vertices, 0, LockFlags.None);
}
public void declareIndex()
{
ib = new IndexBuffer(typeof(int), (WIDTH-1)*(HEIGHT-1)*6, device, Usage.WriteOnly, Pool.Default);
indices = new int[(WIDTH-1)*(HEIGHT-1)*6];
for (int x=0;x< WIDTH-1;x++) {
for (int y=0; y< HEIGHT-1;y++) {
indices[(x+y*(WIDTH-1))*6] = (x+1)+(y+1)*WIDTH;
indices[(x+y*(WIDTH-1))*6+1] = (x+1)+y*WIDTH;
indices[(x+y*(WIDTH-1))*6+2] = x+y*WIDTH;
indices[(x+y*(WIDTH-1))*6+3] = (x+1)+(y+1)*WIDTH;
indices[(x+y*(WIDTH-1))*6+4] = x+y*WIDTH;
indices[(x+y*(WIDTH-1))*6+5] = x+(y+1)*WIDTH;
}
}
ib.SetData(indices, 0, LockFlags.None);
}
protected override void Dispose (bool disposing)
{
base.Dispose(disposing);
MessageBox.Show("");
}
protected virtual void InvalidateDeviceObjects(object sender, EventArgs e)
{
}
protected virtual void RestoreDeviceObjects(object sender, EventArgs e)
{
}
protected virtual void DeleteDeviceObjects(object sender, EventArgs e)
{
}
protected virtual void EnvironmentResizing(object sender, CancelEventArgs e)
{
}
public void run()
{
while(this.Created)
{
render();
setcamera();
// optional: loading the height using functional call:
// loadheight();
Application.DoEvents();
}
}
public void render()
{
if (device != null)
{
device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
device.BeginScene();
//display terrain
device.VertexFormat = CustomVertex.PositionColored.Format;
device.SetStreamSource(0, vb, 0);
device.Indices = ib;
device.Transform.World = Matrix.Translation(-HEIGHT/2, -WIDTH/2, 0)*Matrix.RotationZ(angle) ;
device.DrawIndexedPrimitives(PrimitiveType.TriangleFan, 0, 0, WIDTH*HEIGHT, 0, indices.Length/3);
//turn off lights now
device.EndScene();
device.Present();
this.Invalidate();
readkeyboard();
}
}
void readkeyboard()
{
KeyboardState keys = keyb.GetCurrentKeyboardState();
if (keys[Key.Delete])
{
angle+=0.03f;
}
if (keys[Key.Next])
{
angle-=0.03f;
}
}
public void openport()
{
}
protected override void OnPaint(PaintEventArgs e)
{
render();
setcamera();
}
}
}
Now, yet a third file calls the world creation and display:
void MainFormLoad(object sender, EventArgs e)
{
world = new World();
world.setterrain();
}
the surf and box-somthing functions do not yet do anything.
All what i get now, is just a black window (the device.clear(... ) part) - i tried to adjust the camera .. no success
please help, i want to show the terrain in the window ....