How to display only one clock pointer in c# - c#

I'm trying to create an analog clock from scratch using C#, and I'm a little stuck at this point.
I have this code:
private void timer1_Tick(object sender, EventArgs e)
{
int seconde = DateTime.Now.Second;
spx = cx + (int)(length * Math.Sin(Math.PI * seconde / 30));
spy = cy - (int)(length * Math.Cos(Math.PI * seconde / 30));
a = new Point(spx, spy);
g.DrawLine(pen, m, a);
}
There are more variables in the form load but this is general how i draw the line for the second pointer on the clock. My problem is that it does exactly what i want. But after 60 seconds, I have 60 lines. How do I just display the good pointer line and/or delete the old lines.
Sorry if the answer to my problem is just easy. But I cant really find anything I understand as an answer.

You need to repaint the background of the clock every second before painting the new line, to remove the old line.
Of course, that would mean that for every paint of the seconds hand (or pointer) you will need to also paint the minutes hand and the hours hand, since both of them will also be deleted.
This is because winforms does not have the concept of painting in layers - everything gets painted on a single surface - so you have to first delete the old painting before you can paint a new one.

I would do it like this:
public partial class Form1 : Form
{
private int spx, spy, length;
private Pen pen = new Pen(new SolidBrush(Color.Red), 0.5f);
private Point a,m;
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
this.Refresh(); // force redraw
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
length = Math.Min(e.ClipRectangle.Height, e.ClipRectangle.Width) / 2;
if (length != 0) // can't draw when there's no space
{
m = new Point(e.ClipRectangle.Width / 2, e.ClipRectangle.Height / 2);
int seconde = DateTime.Now.Second;
spx = m.X + (int)(length * Math.Sin(Math.PI * seconde / 30));
spy = m.Y - (int)(length * Math.Cos(Math.PI * seconde / 30));
a = new Point(spx, spy);
e.Graphics.DrawLine(pen, m, a);
}
}
}
I was taught to draw in OnPaint of Winforms controls.
Guess there are many different approaches.
By doing it this way you don't have to clear your graphics manually. This happens when the control is invalidated.

Related

Error when drawing line in Graphics.DrawLine C# Visual Studio

private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics l = e.Graphics;
Pen p = new Pen(Color.Black, 1);
float angle = 0;
float len = 100;
PointF ori = new PointF(Width/2, 0);
PointF bob = new PointF(Width/2, len);
while(true)
{
bob.X = ori.X + len * (float)Math.Sin(angle);
bob.Y = ori.Y + len * (float)Math.Cos(angle);
angle += 0.001F;
l.DrawLine(p, ori.X, ori.Y, bob.X, bob.Y);
l.DrawEllipse(p, bob.X - 15, bob.Y, 30, 30);
if(angle == 360)
{
break;
}
l.Dispose();
}
}
The error line is l.DrawLine(p, ori.X, ori.Y, bob.X, bob.Y).
Error type: System.ArgumentException. Error Message: Parameter is not valid.
At first I thought the issue was with the floats but the DrawLine allows for such datatypes. It loops through once the error seems to occur when angle>0. Its magnitude doesn't seem to be the issue. Any help would be much appreciated. Thanks in advance. [UPDATE] Error seems to be with the l.Dispose
The problem is in the wrong Dispose call:
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics l = e.Graphics;
// Pen is IDisposable, that's why why wrap it into "using": it's you who created it
using (Pen p = new Pen(Color.Black, 1)) {
float angle = 0;
float len = 100;
PointF ori = new PointF(Width/2, 0);
PointF bob = new PointF(Width/2, len);
while(true)
{
bob.X = ori.X + len * (float)Math.Sin(angle);
bob.Y = ori.Y + len * (float)Math.Cos(angle);
angle += 0.001F;
l.DrawLine(p, ori.X, ori.Y, bob.X, bob.Y);
l.DrawEllipse(p, bob.X - 15, bob.Y, 30, 30);
// angle is float, that's why == is not recommended:
// (you can well have 359.99999999999999) and thus == will never be true
if (angle >= 360)
break;
// l.Dispose(); // <- Wrong: it's not you who've created it
// (let system Dispose it)
}
}
}
As an enhancement to #Dmitry's answer, I can offer this advice:
As a general rule, you shouldn't call Dispose on an object that you do not control the lifetime of. You are getting an existing Graphics instance from the Paint event. The control that raised the Paint event is what created that Graphics object, so it is responsible for calling Dispose on it when it is done with it, not you.
When you call Dispose on an object that you don't control, you effectively "rip the rug out from under" that code. This is bad, because that code could be expecting the instance to still be alive so that it can perform other operations on it. By disposing it, you don't give it that chance.
You are doing the correct thing with your Pen instance, p, though. You create it during the using statement, so you are responsible for it. The Using handles that by automatically calling Dispose when execution leave the block.
If you had created the Graphicsinstance yourself, with something likeGraphics.FromImage`, then you would be responsible for cleaning it up.

How can I draw a Hilbert Curve Fractal recursively using C# GDI+ Graphics and Windows Forms?

I am working on a project in which I need to use recursion to draw a Hilbert Curve fractal in a Windows Forms application in C#. I must use GDI+ graphics for this, but I am new to GDI+ graphics. Below is my entire code for the Form class that actually draws the curve. At the end of this post, I have included photos demonstrating my erroneous output and the expected output.
The DrawRelative() function is supposed to draw the next line segment from the current [x,y] coordinates to the new [x,y] coordinates, which are calculated by adding the xDistance and yDistance values passed into the DrawRelative() function to the xCurrent and yCurrent class properties.
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 HilbertCurveFractal
{
public partial class FractalDisplay : Form
{
public int MaxDepth { get; set; }
public int CurveType { get; set; }
public int xCurrent { get; set; }
public int yCurrent { get; set; }
public int xLength { get; set; }
public int yLength { get; set; }
public FractalDisplay(int DepthValue, int SelectedCurve)
{
InitializeComponent();
MaxDepth = DepthValue;
CurveType = SelectedCurve;
xCurrent = 250;
yCurrent = 250;
xLength = 0;
yLength = 2;
}
private void FractalDisplay_Load(object sender, EventArgs e)
{
this.DoubleBuffered = true;
if (CurveType == 1) // Run the Hilbert Curve Generator
{
GenerateHilbertCurve(MaxDepth, xLength, yLength);
}
else if (CurveType == 2) // Run the Koch Curve Generator
{
}
else if (CurveType == 3) // Run the Sierpinski Curve Generator
{
}
else
{
MessageBox.Show("Error! - No Curve Type Selected. Ending Program.");
Application.Exit();
}
}
private void GenerateHilbertCurve(int depth, int xDistance, int yDistance)
{
//if (depth == 0) // Base Case
//{
// return;
//}
//else { }
if (depth > 0)
{
GenerateHilbertCurve(depth - 1, yDistance, xDistance);
}
else { }
// Draw Part of Curve Here
DrawRelative(xDistance, yDistance);
if (depth > 0)
{
GenerateHilbertCurve(depth - 1, xDistance, yDistance);
}
else { }
// Draw Part of Curve Here
DrawRelative(yDistance, xDistance);
if (depth > 0)
{
GenerateHilbertCurve(depth - 1, xDistance, yDistance);
}
else { }
// Draw Part of Curve Here
DrawRelative((- 1 * xDistance), (-1 * yDistance));
if (depth > 0)
{
GenerateHilbertCurve(depth - 1, (-1 * yDistance), (-1 * xDistance));
}
else { }
}
// Create a New Paint Event Handler
private void DrawRelative(int xDistance, int yDistance)
{
xLength = xDistance;
yLength = yDistance;
this.Paint += new PaintEventHandler(HilbertCurve_Paint);
}
// Perform the Actual Drawing
private void HilbertCurve_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
// Discover where the new X and Y points will be
int xNew, yNew;
xNew = xCurrent + xLength;
yNew = yCurrent + yLength;
// Paint from the current position of X and Y to the new positions of X and Y
e.Graphics.DrawLine(Pens.Red, xCurrent, yCurrent, xNew, yNew);
// Update the Current Location of X and Y
xCurrent = xNew;
yCurrent = yNew;
}
}
}
The first photo (below) is the incorrect output from the Hilbert Curve function given a MaxDepth of 1.
The second photo (below) represents what I should be getting from this set of functions (given a MaxDepth value of 1 passed in).
Because it seems like the algorithm for recursion is coded correctly, I suspect that I am not using the GDI+ graphics in the proper way, or my class properties are being updated/set incorrectly somewhere in the recursive calls. What can I do to fix my drawing algorithm? Thank you in advance.
To be honest, I didn't initially understand the implementation you have for generating the points for the Hilbert curve. I'm familiar with a couple of different approaches, neither of which look like that.
But, that's an entirely different question. Your main issue at hand is really just that you don't understand how the drawing mechanism in Winforms works. Briefly: there's a Paint event, which your code should handle by drawing what needs to be drawn. Subscribing to the Paint event doesn't cause anything to happen; it's just a way of registering to be notified when drawing is supposed to occur.
Typically, one would use the Designer to subscribe to the event, by navigating to the "Events" tab of the Properties pane for an object in the Designer (e.g. your Form) and selecting the appropriate event handler (or double-clicking in the empty box next to the event to have the Designer automatically insert an empty handler for you to fill in). You can also, when handling the Paint event in your own object, simply override the OnPaint() method.
In either case, the correct technique is to establish the prerequisites for drawing, then call Invalidate() which causes the framework to then raise the Paint event, at which time you can actually draw what you want to draw.
Note that between commenter TaW and me, we have suggested two different approaches to drawing: I suggested pre-computing all of the necessary data for drawing, and then just draw that when the Paint event is raised; TaW has suggested calling the recursive method from the Paint event handler, and drawing directly as you traverse the recursive algorithm.
Both techniques are fine, but of course there are pros and cons to either, having mostly to do with the classic trade-off of time and space. With the former technique, the cost to generate the curve is incurred only once, when the parameters for the curve change. Drawing occurs more quickly, because all the code has to do is draw the pre-existing data. With the latter technique, there is no need to store the data, as each new point generated is used immediately, but of course this means all of the points have to be regenerated every time the window is redrawn.
For this particular application, in practice I don't think it matters much. At typical screen resolutions, you won't be able to make out the features of the curve long before you start to hit the limits of data storage for the points to draw. Similarly, the execution of the algorithm is so fast that there's really no harm in recalculating the points each time the window needs to be redrawn. Just keep in mind that these are trade-offs you may have to judge more closely in other scenarios.
Okay, so what's all that mean? Well, when I converted it to something that used the Graphics class correctly, I couldn't get your implementation to draw a Hilbert curve, so I changed that part of the code to use an implementation I know works. You can find a detailed discussion on how this particular implementation works here: Hilbert Curve
Concepts & Implementation
Below, I have provided two different versions of that particular Hilbert curve implementation, the first using the "retained" approach (i.e. generate the data, then draw it), and the second using the "immediate" approach (i.e. generate the data every time you want to draw the window, as the drawing is occurring):
"Retained" method:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DoubleBuffered = true;
}
private PointF[] _points;
private void FractalDisplay_Load(object sender, EventArgs e)
{
Redraw();
}
private void Redraw()
{
List<PointF> points = new List<PointF>();
GenerateHilbert(0, 0, 1, 0, 0, 1, (int)numericUpDown1.Value, points);
_points = points.ToArray();
Invalidate();
}
private void GenerateHilbert(PointF origin, float xi, float xj, float yi, float yj, int depth, List<PointF> points)
{
if (depth <= 0)
{
PointF current = origin + new SizeF((xi + yi) / 2, (xj + yj) / 2);
points.Add(current);
}
else
{
GenerateHilbert(origin, yi / 2, yj / 2, xi / 2, xj / 2, depth - 1, points);
GenerateHilbert(origin + new SizeF(xi / 2, xj / 2), xi / 2, xj / 2, yi / 2, yj / 2, depth - 1, points);
GenerateHilbert(origin + new SizeF(xi / 2 + yi / 2, xj / 2 + yj / 2), xi / 2, xj / 2, yi / 2, yj / 2, depth - 1, points);
GenerateHilbert(origin + new SizeF(xi / 2 + yi, xj / 2 + yj), -yi / 2, -yj / 2, -xi / 2, -xj / 2, depth - 1, points);
}
}
// Perform the Actual Drawing
private void HilbertCurve_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
if (_points != null)
{
float scale = Math.Min(ClientSize.Width, ClientSize.Height);
e.Graphics.ScaleTransform(scale, scale);
using (Pen pen = new Pen(Color.Red, 1 / scale))
{
e.Graphics.DrawLines(pen, _points);
}
}
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
Redraw();
}
protected override void OnClientSizeChanged(EventArgs e)
{
base.OnClientSizeChanged(e);
Invalidate();
}
}
"Immediate" method:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DoubleBuffered = true;
}
private void Redraw()
{
Invalidate();
}
private PointF GenerateHilbert(PointF origin, float xi, float xj, float yi, float yj, int depth,
PointF? previous, Graphics graphics, Pen pen)
{
if (depth <= 0)
{
PointF current = origin + new SizeF((xi + yi) / 2, (xj + yj) / 2);
if (previous != null)
{
graphics.DrawLine(pen, previous.Value, current);
}
return current;
}
else
{
previous = GenerateHilbert(origin, yi / 2, yj / 2, xi / 2, xj / 2, depth - 1, previous, graphics, pen);
previous = GenerateHilbert(origin + new SizeF(xi / 2, xj / 2), xi / 2, xj / 2, yi / 2, yj / 2, depth - 1, previous, graphics, pen);
previous = GenerateHilbert(origin + new SizeF(xi / 2 + yi / 2, xj / 2 + yj / 2), xi / 2, xj / 2, yi / 2, yj / 2, depth - 1, previous, graphics, pen);
return GenerateHilbert(origin + new SizeF(xi / 2 + yi, xj / 2 + yj), -yi / 2, -yj / 2, -xi / 2, -xj / 2, depth - 1, previous, graphics, pen);
}
}
// Perform the Actual Drawing
private void HilbertCurve_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
float scale = Math.Min(ClientSize.Width, ClientSize.Height);
e.Graphics.ScaleTransform(scale, scale);
using (Pen pen = new Pen(Color.Red, 1 / scale))
{
GenerateHilbert(new PointF(), 1, 0, 0, 1, (int)numericUpDown1.Value, null, e.Graphics, pen);
}
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
Redraw();
}
protected override void OnClientSizeChanged(EventArgs e)
{
base.OnClientSizeChanged(e);
Invalidate();
}
}
In both examples I've made some other changes which are not strictly needed for the purpose of illustrating the techniques, but which are still useful:
The curve itself is computed in unit space (i.e. a square of side length of 1), and then drawn by scaling the drawing to fit the window.
Where it makes sense, individual coordinates are passed as whole PointF values instead. This simplifies reuse of the values and adding new offsets to the X and Y values.
Since the drawing is now scaled to the window, the window is redrawn if its size changes.
For simplicity, this Form is self-contained, with a NumericUpDownControl that determines the recursion depth. I didn't include instantiation of this control; I presume you can add the appropriate control yourself in the Designer, to make the above compile.
Addendum:
I've had a chance to look over the other examples on the Internet of the algorithm that you tried to implement. Now that I understand what the basic mechanism of the algorithm is, I was able to fix your version so that it works (the main problem was that you were using instance fields to store the deltas for the algorithm, but also using the same fields to initialize the algorithm, so once the algorithm ran once, subsequent executions wouldn't work). So for the sake of completeness, here is a second "retained" version of the code, using your preferred algorithm instead of the one I used above:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DoubleBuffered = true;
}
private PointF _previousPoint;
private PointF[] _points;
private void FractalDisplay_Load(object sender, EventArgs e)
{
Redraw();
}
private void Redraw()
{
List<PointF> points = new List<PointF>();
// Start here, to provide a bit of margin within the client area of the window
_previousPoint = new PointF(0.025f, 0.025f);
points.Add(_previousPoint);
int depth = (int)numericUpDown1.Value;
float gridCellCount = (float)(Math.Pow(2, depth) - 1);
// Use only 95% of the available space in the client area. Scale
// the delta for drawing to fill that 95% width/height exactly,
// according to the number of grid cells the given depth will
// produce in each direction.
GenerateHilbert3(depth, 0, 0.95f / gridCellCount, points);
_points = points.ToArray();
Invalidate();
}
private void GenerateHilbert(int depth, float xDistance, float yDistance, List<PointF> points)
{
if (depth < 1)
{
return;
}
GenerateHilbert(depth - 1, yDistance, xDistance, points);
DrawRelative(xDistance, yDistance, points);
GenerateHilbert(depth - 1, xDistance, yDistance, points);
DrawRelative(yDistance, xDistance, points);
GenerateHilbert(depth - 1, xDistance, yDistance, points);
DrawRelative(-xDistance, -yDistance, points);
GenerateHilbert(depth - 1, -yDistance, -xDistance, points);
}
private void DrawRelative(float xDistance, float yDistance, List<PointF> points)
{
// Discover where the new X and Y points will be
PointF currentPoint = _previousPoint + new SizeF(xDistance, yDistance);
// Paint from the current position of X and Y to the new positions of X and Y
points.Add(currentPoint);
// Update the Current Location of X and Y
_previousPoint = currentPoint;
}
// Perform the Actual Drawing
private void HilbertCurve_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
if (_points != null)
{
float scale = Math.Min(ClientSize.Width, ClientSize.Height);
e.Graphics.ScaleTransform(scale, scale);
using (Pen pen = new Pen(Color.Red, 1 / scale))
{
e.Graphics.DrawLines(pen, _points);
}
}
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
Redraw();
}
protected override void OnClientSizeChanged(EventArgs e)
{
base.OnClientSizeChanged(e);
Invalidate();
}
}
As before, I've modified your implementation slightly, so that the drawing is scaled to fit within the window at all depths. This involves drawing into the unit square and then setting the transform appropriately according to the window size.
In addition to fixing the basic usage of Graphics, and the issue with the xLength and yLength fields, I also fixed a minor bug in your code (where you were recursing one level too deep) and cleaned up the recursion a bit (there's no need to repeat the depth checkā€¦just do it once, at the beginning of the recursive method).
It is of course possible to implement this in the "immediate" style as well. I think between this new code example, and the "immediate" method example above, I can leave that exercise to the reader. :)
Here is the fractal generator I came up with after heeding the advice of #Peter Duniho - The code shown does not include the form that actually gets the depth level (maxDepth) of recursion requested by the user.
public partial class HilbertDisplay : Form
{
private int maxDepth;
private int xCurrent = 0;
private int yCurrent = 0;
private int xNew = 0;
private int yNew = 0;
public HilbertDisplay(int depthEntered)
{
InitializeComponent();
maxDepth = depthEntered;
}
private void HilbertDisplay_Load(object sender, EventArgs e)
{
this.DoubleBuffered = true;
this.Update();
}
// Perform the Drawing
private void HilbertDisplay_Paint(object sender, PaintEventArgs e)
{
// Run the Hilbert Curve Generator
// Use a line segment length of 10 for Y
GenerateHilbertCurve(maxDepth, 0, 10, e);
}
// The Recursive Hilbert Curve Generator
private void GenerateHilbertCurve(int depth, int xDistance, int yDistance, PaintEventArgs e)
{
if (depth < 1)
{
return;
}
else
{
GenerateHilbertCurve(depth - 1, yDistance, xDistance, e);
// Paint from the current position of X and Y to the new positions of X and Y
FindPointRelative(xDistance, yDistance);
e.Graphics.DrawLine(Pens.Red, xCurrent, yCurrent, xNew, yNew); // Draw Part of Curve Here
UpdateCurrentLocation();
GenerateHilbertCurve(depth - 1, xDistance, yDistance, e);
// Paint from the current position of X and Y to the new positions of X and Y
FindPointRelative(yDistance, xDistance);
e.Graphics.DrawLine(Pens.Blue, xCurrent, yCurrent, xNew, yNew); // Draw Part of Curve Here
UpdateCurrentLocation();
GenerateHilbertCurve(depth - 1, xDistance, yDistance, e);
// Paint from the current position of X and Y to the new positions of X and Y
FindPointRelative(-xDistance, -yDistance);
e.Graphics.DrawLine(Pens.Green, xCurrent, yCurrent, xNew, yNew); // Draw Part of Curve Here
UpdateCurrentLocation();
GenerateHilbertCurve(depth - 1, (-1 * yDistance), (-1 * xDistance), e);
}
}
private void FindPointRelative(int xDistance, int yDistance)
{
// Discover where the new X and Y points will be
xNew = xCurrent + xDistance;
yNew = yCurrent + yDistance;
return;
}
private void UpdateCurrentLocation()
{
// Update the Current Location of X and Y
xCurrent = xNew;
yCurrent = yNew;
return;
}
}
This code, unlike that of #Peter Duniho, does not account for the form's size. This depicts a Hilbert Curve fractal up to a recursion depth of 6 or 7 on my laptop (due to limitations on window size made by my laptop screen size/resolution).
I know that my solution is not as elegant as that of #Peter Duniho, but as this is for an assignment I did not want to simply copy his code. I made edits based on his suggestions, especially in regard to the Paint event.

C# - ".FillRectangle" Not Completely Filling Rectangle

I'm using the following code as just a test for how I might use a custom progress bar in the future - it actually isn't a progress bar at all, but rather a picturebox that the code draws a rectangle on, and then fills up based on a timer.
The problem is, I'm reaching 100% before the box is filled. I've tinkered around, but not been able to locate the issue. What am I doing wrong? See code below, and imgur screenshot of the behavior on my system.
Thanks.
public partial class frmLoading : Form
{
System.Windows.Forms.Timer tLoading = new System.Windows.Forms.Timer();
Double pbLoadingUnit;
int pbLoadingWIDTH, pbLoadingHEIGHT, pbLoadingComplete;
Bitmap bmpLoading;
Graphics gLoading;
private void frmLoading_Load(object sender, EventArgs e)
{
pbLoadingWIDTH = pictureLoading.Width;
pbLoadingHEIGHT = pictureLoading.Height;
pbLoadingUnit = pbLoadingWIDTH / 100;
pbLoadingComplete = 0;
bmpLoading = new Bitmap(pbLoadingWIDTH, pbLoadingHEIGHT);
tLoading.Interval = 32;
tLoading.Tick += new EventHandler(this.tLoading_Tick);
tLoading.Start();
}
private void tLoading_Tick(object sender, EventArgs e)
{
gLoading = Graphics.FromImage(bmpLoading);
gLoading.Clear(Color.DarkSlateGray);
gLoading.FillRectangle(Brushes.DodgerBlue, new Rectangle(0, 0, (int)(pbLoadingComplete * pbLoadingUnit), pbLoadingHEIGHT));
gLoading.DrawString(pbLoadingComplete + "%", new Font("Segoe UI Semibold", pbLoadingHEIGHT / 2), Brushes.White, new PointF(pbLoadingWIDTH / 2 - pbLoadingHEIGHT, pbLoadingHEIGHT / 10));
pictureLoading.Image = bmpLoading;
pbLoadingComplete++;
if (pbLoadingComplete > 100)
{
gLoading.Dispose();
tLoading.Stop();
}
}
You should change this
pbLoadingUnit = pbLoadingWIDTH / 100;
to this
pbLoadingUnit = Convert.ToDouble(pbLoadingWIDTH) / 100;
I assume your picture width is not a multiple of a hundred.
With your old code, your pbLoadingUnit will be generate as integer since you divide integer to integer.
You may use this too :
double div = 100;
pbLoadingUnit = pbLoadingWIDTH / div;
OR
pbLoadingUnit = pbLoadingWIDTH / Convert.ToDouble(100);
The point is, you should get the double value of pbLoadingUnit.
For more information about numeric casting, you may see this link dotnetperls.com/numeric-casts
Try to put the following lines in OnResize() event of the frmLoading:
pbLoadingWIDTH = pictureLoading.Width;
pbLoadingHEIGHT = pictureLoading.Height;
pbLoadingUnit = pbLoadingWIDTH / 100;
Chances are you're getting the initial size of the pictureLoading during Load()... and not the actual width when it shows up and displayed in your form.
Also let tloading.Start() happens when you already get the appropriate size of you pictureLoading object.
you have to add this variable int pbmodal;
then calculate MOD of the unit
on form load add
pbmodal = pbLoadingWIDTH % 100;
when the completed is 100% add the modal.
Difference of division
`if (pbLoadingComplete > 100)
{
gLoading.FillRectangle(Brushes.DodgerBlue, new Rectangle(0, 0, (int)(pbLoadingComplete * pbLoadingUnit) + pbmodal, pbLoadingHEIGHT));
gLoading.DrawString(pbLoadingComplete-1 + "%", new Font("Segoe UI Semibold", pbLoadingHEIGHT / 2), Brushes.White, new PointF(pbLoadingWIDTH / 2 - pbLoadingHEIGHT, pbLoadingHEIGHT / 10));
pictureLoading.Image = bmpLoading;
}`

Draw fractal Fit inside panel using Winform?

i am trying to build a windows application in .net which draw fractal image inside the panel.It take end points of line as starting point of next line.But problem is, diagram is going outside of the panel.How do i fix drawing inside the panel
static int start_x, start_Y;
static int end_x, end_Y;
static int my_angle = 0;
static int my_length = 0;
private void Canvas_Paint(object sender, PaintEventArgs e)
{
start_x = Canvas.Width / 2;
start_Y = Canvas.Height / 2;
for (int i = 0; i < 400; i++)
{
draw_T();
}
}
public void draw_T()
{
Pen mypen = new Pen(Color.Green, 2F);
my_angle = my_angle + (45);
my_length = 100 + (1);
end_x = (int)(start_x + Math.Cos(my_angle * .0174539676) * my_length);
end_Y = (int)(start_Y + Math.Sin(my_angle * .0174539676) * my_length);
Point[] points =
{
new Point (start_x,start_Y),
new Point (end_x,end_Y)
};
Point[] points1 =
{
new Point ((end_x+start_x)/2,(end_Y+start_Y)/2),
new Point (end_x+50,end_Y-100)
};
start_x = end_x;
start_Y = end_Y;
Graphics g = Canvas.CreateGraphics();
g.DrawLines(mypen, points);
g.DrawLines(mypen, points1);
}
I'm not sure how you graphic is supposed to look but I can give you a couple of hints.
At general one first: Do make use of e.Graphics parameter! Change
public void draw_T()
To
public void draw_T(Graphics g)
and delete the line.
Graphics g = Canvas.CreateGraphics();
Change the call to
draw_T(e.Graphics);
You are leaking GDI resource by creating all those Graphcs with disposing of them and and lose time by creating them when you already have the one from the Paint event.
Next you should add a NumericUpDown for testing your algorithm and script it like this:
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
Canvas.Invalidate();
}
To work you now change the loop to
for (int i = 0; i < numericUpDown1.Value; i++)
And watch your graphics develop.
Another test could be to introduce a second pen color for the second series of point.
To play around further you could add another NumericUpDown and tie my_lengthto it..
In the end you'll see that length needs to be smaller than 101 or the Canvas needs to be as large as 700 pixels.
BTW: Neither my_angle nor my_length need to be declared at class level since they are always set in the method and used nowhere else and no other variable needs to static either, at least from what you show us..

Moving image on windows form

Is it possible to make image, which is 'standing' still, move when I hover with my mouse over the image? I'm working in vs 2012, c# and win forms and I want simple movement like gif image, something similar to that, just to make it 'alive'
And how to make that? Thank you very much
It is - you can alter the Picturebox.Location like that. Note that this is an illustration and some edge cases may exist - for example you may want to add logic that detects when the image moved so much, that mouse went out (but within the original location)
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
int x = pictureBox1.Location.X;
int y = pictureBox1.Location.Y;
pictureBox1.Location = new Point(x + 25, y + 15);
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
int x = pictureBox1.Location.X;
int y = pictureBox1.Location.Y;
pictureBox1.Location = new Point(x - 25, y - 15);
}

Categories

Resources