Drawing circles with increasing radius in C# - c#

I am using the below code to draw the circles(reading centres from a csv file) with increasing radius. The increase in radius is 5 units per circle.
namespace MATLAB_file
{
public partial class Form1 : Form
{
string[] read;
float th;
int c = 0;
int r;
public List<PointF> circleCoordinates = new List<PointF>();
int rl;
public Form1()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
Pen linePen = new Pen(System.Drawing.Color.CornflowerBlue);
Graphics grphx = this.CreateGraphics();
grphx.Clear(this.BackColor);
foreach (PointF point in this.circleCoordinates)
{
Pen redPen1 = new Pen(Color.Red, 100);
e.Graphics.DrawArc(Pens.Red, point.X, point.Y, 1, 1, 0, 120F);
}
linePen.Dispose();
base.OnPaint(e);
}
private void Form1_Load(object sender, EventArgs e)
{
double xx, yy;
int i;
int n = 0;
float[] centre1 = new float[1000];
System.IO.StreamReader sr;
sr = new System.IO.StreamReader("centers.txt", true);
char[] seperators = { ',' };
string data = sr.ReadLine();
read = data.Split(new Char[] { ',' });
rl = read.Length;
int a1 = rl / 2;
for (c = 0; c < rl; c++)
{
centre1[c] = float.Parse(read[c]);
}
while (r < 200)
{
for (i = 0; i < a1; i++)
{
while (th < 360)
{
xx = r * Math.Cos(th) + centre1[2 * i] + 100;
xx1 = (float)xx;
yy = r * Math.Sin(th) + centre1[2 * i + 1] + 100;
yy1 = (float)yy;
this.circleCoordinates.Add(new PointF(xx1, yy1));
this.Invalidate();
th = th + .360F;
}
th = 0;
}
r = r + 5;
}
}
}
}
The above code is displaying all the circles but I do not want all circles to be displayed on canvas, rather only one circle should show with gradual increase in radius
Please suggest how to delete the previous drawn circle on drawing new one. Is there any other way to do it, if my later use includes removal of certain section of circles based on "th" values?

If you move the Clear call within the foreach you will see only the last drawn circle, though this could be achieved with drawing only the Last circleCoordinates too.
foreach (PointF point in this.circleCoordinates)
{
grphx.Clear(this.BackColor);
Pen redPen1 = new Pen(Color.Red, 100);
e.Graphics.DrawArc(Pens.Red, point.X, point.Y, 1, 1, 0, 120F);
}
An alternative interpretation:
You want animation, which generates the onPaint events (by timer ticks or on user input) and you increase a counter to select the circle to draw.
For that, you will need a new member in your program, like int Index; and you could select the circle based on this, using something the following code snippet (assuming you always have at least 1 circleCoordinates, animation restarts after it finished):
PointF point = this.circleCoordinates[Index % circleCoordinates.Length];
or (last circle remain on the screen after the animation)
PointF point = this.circleCoordinates[Math.Min(Index, circleCoordinates.Length - 1)];

Related

Plasma effect in WinForms, how to create continous loop

I'm trying to create some simple graphics ("plasma" effect) with C# and Winforms.
I have two classes in my code, (main)Form1 and Plasmadraw.
In Plasmadraw I have following setup:
class Plasmadraw
{
int y;
int x;
double i;
double pii = 3.1415;
public void Draw(Graphics gfx, int addition)
{
for (int i = 0; i < 23040; i++)
{
x = x + 10;
if (x == 1920)
{
x = 0;
y = y + 10;
}
if (y == 1200)
{
y = 0;
}
double v = Math.Sin((x * 0.5) + i * 0.001 * addition);
double c = v * pii;
double d = c + (2 * pii / 3);
double f = c + (6 * pii / 3);
double r = 255 * Math.Abs(Math.Sin(c));
double g = 255 * Math.Abs(Math.Sin(d));
double b = 255 * Math.Abs(Math.Sin(f));
int r1 = (int)r;
int g1 = (int)g;
int b1 = (int)b;
Color e = Color.FromArgb(r1, g1, b1);
SolidBrush brush = new SolidBrush(e);
Rectangle rect = new Rectangle(x, y, 10, 10);
gfx.FillRectangle(brush, rect);
}
}
}
and then in Form1 I have Paint event:
private void Form1_Paint(object sender, PaintEventArgs e)
{
Plasmadraw plasmaeffect = new Plasmadraw();
for (int a = 0; a < 30; a++)
{
plasmaeffect.Draw(e.Graphics, a);
Invalidate();
}
Is this somehow completely wrong way to build the logic ? I've managed to create some graphics effects (moving sprites etc.) by creating a list and then running through the list with Foreach in Paint event (& Invalidate()). However, I'd like to learn some new way to do things, rather than copying the old way.

c# How to create new row if theirs no space on the first row

Hello the code below works perfectly but i was wondering on how i could implement code that once The row of balls cant fit in the picture box in the first row it creates a new row below that row and so on.
{
//calculate the number of rows
int ballRows = HEIGHT / (SIZE + GAP);
// sets the seed posion in the picturebox
Rectangle recCircle = new Rectangle(LEFT, TOP,SIZE,SIZE);
Graphics paper = pictureBoxBowl.CreateGraphics();
Pen pen1 = new Pen(Color.Gray, 2);
// variable for amount of balls
int ballAmount = 0;
try
{
//changes text value to interger
ballAmount = int.Parse(textBoxNumSeeds.Text);
}
catch (Exception ex)
{
//tells user of error and clears and focuses the textbox
MessageBox.Show("invalid numeric input try again");
textBoxNumSeeds.Clear();
textBoxNumSeeds.Focus();
return;
}
//makes y position for the circle rows
int yPos = TOP;
int xPos = LEFT;
//creates new row under previous row
for (int cols = 0; cols < ballAmount; cols++)
{
SolidBrush SeedColour = null;
int randBallCol = rand.Next(40) + 1;
//if random ball colour is between 1 - 100 then set to blue
if (randBallCol >= 1 && randBallCol <= 100)
{
SeedColour = new SolidBrush(Color.Gray);
}
//changes new circle location by changing y position and adding gap and radius to it
recCircle.Location = new Point(xPos, yPos);
//displays the circles based on recCircle dimensions
paper.FillEllipse(SeedColour, recCircle);
paper.DrawEllipse(pen1, recCircle);
//updates the xposition of the columns
xPos = xPos + SIZE + GAP;
}
You did not specify what platform you are using, but let's assume WinForms for simplicity.
You need to reset the yPos when the next ball x-Position will be outside the size of the paper rectangle.
something like this just below the line where you update the x position right at the bottom.
int xNext = xPos + SIZE + GAP;
if (xNext > e.ClipRectangle.Width)
{
yPos = yPos + SIZE;
xPos = 0;
}
However its better to use the Paint event.
I set up a small WinForms app and it looks like this.
public partial class Form1 : Form
{
int HEIGHT = 5;
int SIZE = 10;
int GAP = 2;
int LEFT = 0;
int TOP = 0;
Rectangle _recCircle;
int ballAmount = 0;
Random _rand;
public Form1()
{
InitializeComponent();
_recCircle = new Rectangle(LEFT, TOP, SIZE, SIZE);
_rand = new Random(1);
}
private void button1_Click(object sender, EventArgs e)
{
try
{
//changes text value to interger
ballAmount = int.Parse(textBoxNumSeeds.Text);
}
catch (Exception ex)
{
//tells user of error and clears and focuses the textbox
MessageBox.Show("invalid numeric input try again");
textBoxNumSeeds.Clear();
textBoxNumSeeds.Focus();
return;
}
pictureBoxBowl.Invalidate();
}
private void pictureBoxBowl_Paint(object sender, PaintEventArgs e)
{
//makes y position for the circle rows
int yPos = TOP;
int xPos = LEFT;
int xNext = 0;
//creates new row under previous row
for (int cols = 0; cols < ballAmount; cols++)
{
SolidBrush SeedColour = null;
SeedColour = new SolidBrush(Color.FromArgb(_rand.Next(255), _rand.Next(255), _rand.Next(255)));
//changes new circle location by changing y position and adding gap and radius to it
_recCircle.Location = new Point(xPos, yPos);
//displays the circles based on recCircle dimensions
e.Graphics.FillEllipse(SeedColour, _recCircle);
e.Graphics.DrawEllipse(new Pen(SeedColour), _recCircle);
//updates the xposition of the columns
xPos = xPos + SIZE + GAP;
//test if a new row is required
xNext = xPos + SIZE + GAP;
if (xNext > e.ClipRectangle.Width)
{
yPos = yPos + SIZE;
xPos = 0;
}
}
}
}
and gives you this result.

How to enable drawing on a picture box in C#

I am trying to draw a network topology consists of many nodes to be like a 3D nodes using the idea of projection, but when I click the button that should implement the code nothing appears!!!! the following is the main code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Media;
using System.Text;
using System.Windows.Forms;
using AUV_Topology.AUV_Topology;
using AUV_Topology;
namespace AUV_Topology
{
public partial class Form2 : Form
{
private int iSetupDisplay = -1; // used for making drawing on the graphics
static int NodeNum = 0; // an int number is given for each node
static bool deploymentButtonWasClicked = false; // flag to check if button "Deploy" is clicked
static Sink sink; // sink object from sink class
static SensorNode[] SNs; // array of SNs
static int[,] SNsLocation; // to store SN locations
static int[,] SNsNighbors; // to store each SN nighbors
static int[] SinkNighbors; // to store each SN nighbors
static int transmissionRange; // the transmission range for each sensor node
static double sensorNodeIntialEnergy; // in order to store the energy filled in the text box in the GUI
System.IO.StreamWriter writer; // declare a writer object from the straem writer class
static Random r = new Random(); // in order to generate a random number
static AUV[] auv; // array of AUVs objects from AUV class
static int rows, columns; // to get the number of rows and columns from the text boxes in the GUI
static int[,] cellsCenters; // an array to store the indexes (col & row) for each center for each cell in the grid topology
static int[] columnsXs; // the index of each X cordinates in each column
static int[] rowsYs; // the index of each Y cordinates
static int numOfCells; // compute the number of cells by multpling the rows with columns
static int cellSide; // to compute the length of each side for each cell
public Form2()
{
InitializeComponent();
// Create a file for output named TraceFile.txt.
Stream myFile = File.Create("C:/Users/AMCT/Desktop/TraceFile2.txt");
TextWriterTraceListener myTextListener = new TextWriterTraceListener(myFile);
Trace.Listeners.Add(myTextListener);
}
private void Form2_Load(object sender, EventArgs e)
{
}
public delegate void UpdateControlsDelegate();
[TypeConverter(typeof(ExpandableObjectConverter))]
public struct Point3D
{
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
public Point3D(int x, int y, int z) : this()
{
this.X = x;
this.Y = y;
this.Z = z;
}
}
public static SoundPlayer player = new SoundPlayer("C:/Users/AMCT/Desktop/project/C#-Code-VisualStudio-2010/GAAPS/Sonar_pings.wav");
public static int tr;
//***Deployment***//
#region nodesDeployment
private void nodesDeployment_Click_1(object sender, EventArgs e)
{
//chromosome size
rows = 10;
columns = 10;
int numOfGridCells = rows * columns; // Calculate the total number of the cells for the grid topology
tr = Convert.ToInt32(TransRange.Text);
calculateCellsCenters(200, 200, 700, 700, numOfGridCells, 500, 500); // Compute all the center points (Xc,Yc) for all cells of the partitioned region (grid)
if (NumSN.Text != string.Empty) // to check that the user has entered the number of nodes for this topology
{
topology2.Visible = true;
NodeNum = Convert.ToInt32(NumSN.Text); // get the number from the text box
sensorNodeIntialEnergy = Convert.ToDouble(SNEnergy.Text);
Point3D[] auvLocation2D = new Point3D[4];
for (int i = 0; i < 4; i++)
auvLocation2D[i] = new Point3D(cellsCenters[0, 0], cellsCenters[1, 8], 700 - i * 100);
Point3D p3d = new Point3D(542, 600, 210);
PointF point2Dsink = Project(p3d);
sink = new Sink("Sink", 1, point2Dsink.X, point2Dsink.Y, 100);
auv = new AUV[4];
for (int i = 0; i < 4; i++)
{
PointF point2D = Project(auvLocation2D[i]);
int d = 700 - i * 100;
auv[i] = new AUV(point2D.X, point2D.Y, d, sink, i);
}
SNs = new SensorNode[NodeNum];
for (int i = 0; i < NodeNum; i++)
SNs[i] = new SensorNode(i, "SN" + i, r.Next(355, 750) % (topology2.Width), sensorNodeIntialEnergy, sink, auv[0], 0);
nodesCoordinations(); // choose XY coordinates for each sensor node
generateRoutingTable(); // build the routing table for each sensor node
deploymentButtonWasClicked = true;
}
makeDrawing(); // Draw
}
#endregion
//***Nodes Coordinates***//
#region Nodes Coordinates ( used by deployment process )
public void nodesCoordinations()
{
SNsLocation = new int[2, NodeNum]; // build an array of size n which is equal to the number of nodes that was chosen by the user to store all SNs locations
# region SNs Locations
for (int i = 0; i < NodeNum; i++)
if (NodeNum != 0)
{
SNsLocation[0, i] = r.Next(300, 800) % (topology2.Width); // choose random X coordinate between 300 & 800 pixel
SNsLocation[1, i] = r.Next(260, 725) % (topology2.Width); // choose random Y coordinate between 260 & 725 pixel
}
}
# endregion
public void generateRoutingTable()
{
/// Size of SNsNighbors Array = [node #, Nighbors #]
double D; // Euclidean distance
SNsNighbors = new int[NodeNum, NodeNum];
SinkNighbors = new int[NodeNum];
transmissionRange = Convert.ToInt32(TransRange.Text);
/// This Method estimate the Euclidean distance between SNs = (D)
/// Suppose that the transmission rane for all nodes = 150
/// if d <= Transmission Rang of SNi, SNi can communicate with SNj
for (int i = 0; i < NodeNum; i++) // For all SNs
for (int j = 0; j < NodeNum; j++) // For all SNs
{
if (i != j)
{
double Xn = SNsLocation[0, i]; // 0 for x - axis
double Yn = SNsLocation[1, i]; // 1 for y - axis
double Xs = SNsLocation[0, j]; // 0 for x - axis
double Ys = SNsLocation[1, j]; // 1 for y - axis
D = Math.Pow((Math.Pow(Xn - Xs, 2) + Math.Pow(Yn - Ys, 2)), 0.5);
// the transmission range is 150
if (D <= transmissionRange)
SNsNighbors[i, j] = 1; // SNj is nighbore for SNi
else
SNsNighbors[i, j] = 0; // SNj is NOT nighbore for SNi
}
else
SNsNighbors[i, j] = 0; // SNj is NOT nighbore for SNi
}
}
#endregion nodesDeployment
//***Paint Handlers***//
#region Paint handlers
private void topology_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Font font = new Font("Times New Roman", 7.0f); // choose the type of font and its size
StringFormat format = new StringFormat(); // declare string format
format.Alignment = StringAlignment.Center; // declare string alignment
Graphics g = e.Graphics;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; // declare the quality for the drawings
Pen transmissionRangeColor = Pens.LightCyan; // the color used to draw the ellipse which repesents the transmission range for each node
Pen nodeNieghbors = Pens.LightSeaGreen; // the color used to draw the green lines between sensor nodes which indicates direct connection between nodes
Pen sinkNieghbors = Pens.Azure;
Brush nodeName = Brushes.White; // the color used for strings used to name the nodes
Brush auvSendMsg = Brushes.Red; // the color used for strings used to name the nodes
#region Display Sink
if (deploymentButtonWasClicked) // chech if the "Deploy" button was clicked
{
DrawImage("C:/Users/AMCT/Desktop/project/C#-Code-VisualStudio-2010/GAAPS/Sink.png", e.Graphics, sink.sinkX, sink.sinkY, 35, 45);
DrawString("Sink", e.Graphics, font, nodeName, new Point3D(600, 600 + 34, 233), 5);// Display the sink name
#region Draw Grid
topology2.Invalidate();
DrawGrid(numOfCells, cellSide, 800, e.Graphics);
DrawGrid(numOfCells, cellSide, 700, e.Graphics);
DrawGrid(numOfCells, cellSide, 600, e.Graphics);
DrawGrid(numOfCells, cellSide, 500, e.Graphics);
DrawGrid(numOfCells, cellSide, 400, e.Graphics);
for (int j = 0; j < rows; j++)
for (int i = 0; i < columns; i++)
{
DrawRectangle(e.Graphics, Brushes.SteelBlue, new Point3D(cellsCenters[0, i], cellsCenters[1, j], 800));
DrawRectangle(e.Graphics, Brushes.SteelBlue, new Point3D(cellsCenters[0, i], cellsCenters[1, j], 700));
DrawRectangle(e.Graphics, Brushes.SteelBlue, new Point3D(cellsCenters[0, i], cellsCenters[1, j], 600));
DrawRectangle(e.Graphics, Brushes.SteelBlue, new Point3D(cellsCenters[0, i], cellsCenters[1, j], 500));
DrawRectangle(e.Graphics, Brushes.SteelBlue, new Point3D(cellsCenters[0, i], cellsCenters[1, j], 400));
}
base.OnPaint(e);
#endregion
#region Display Sensor Nodes
/// node[0,i] means >> x-axis
/// node [1,i] means >> y-axis
for (int n = 0; n < NodeNum; n++)
{
DrawSensor(new Point3D(SNsLocation[0, n], SNsLocation[1, n], 760), new Point3D(SNsLocation[0, n], SNsLocation[1, n], SNs[n].snDepth), e.Graphics);
//DrawTransmissionRange(e.Graphics, transmissionRangeColor, new Point3D(SNsLocation[0, n],SNsLocation[1, n],SNs[n].snDepth), transmissionRange);
DrawString("SN" + (n + 1), e.Graphics, font, nodeName, new Point3D(SNsLocation[0, n] - 30, SNsLocation[1, n] - 10, SNs[n].snDepth), 12); // display node name
/*for (int i = 0; i < NodeNum - 1; i++)
{
if (SNsNighbors[n, i] == 1) // Green line between nieghbors
DrawLine(e.Graphics, nodeNieghbors, new Point3D(SNsLocation[0, n] + 5, SNsLocation[1, n] + 5, SNs[n].snDepth), new Point3D(SNsLocation[0, i] + 5, SNsLocation[1, i] + 5,SNs[i].snDepth));
}*/
}
#endregion
#region AUV-Animation
for (int i = 0; i < 4; i++)
{
DrawImage("C:/Users/AMCT/Desktop/project/C#-Code-VisualStudio-2010/GAAPS/AUVs-Icon.png", e.Graphics, auv[i].auvX, auv[i].auvY, 45, 20);
base.OnPaint(e);
}
}
#endregion
# endregion
// finish painting
}
/// <summary>
/// Draws a sensor at the specified position(s)
/// </summary>
private void DrawSensor(Point3D from, Point3D to, Graphics gr)
{
DrawLine(gr, Pens.Maroon, from, to);
DrawSphere(gr, Pens.Black, Brushes.Gold, to, 6);
}
/// <summary>
/// Draws a sensor at the specified position(s)
/// </summary>
private void DrawSendingSensor(Point3D from, Point3D to, Graphics gr)
{
DrawLine(gr, Pens.Maroon, from, to);
DrawSphere(gr, Pens.Black, Brushes.Black, to, 6);
}
/// <summary>
/// Draws a sphere as a Circle at the specified position
/// </summary>
private void DrawSphere(Graphics gr, Pen outline, Brush fill, Point3D center, float radius)
{
PointF center2D = Project(center);
gr.FillEllipse(fill, center2D.X - radius, center2D.Y - radius, radius * 2, radius * 2);
gr.DrawEllipse(outline, center2D.X - radius, center2D.Y - radius, radius * 2, radius * 2);
}
/// <summary>
/// Draws the grid at the specified depth
/// </summary>
private void DrawGrid(int numOfCells, int cellSize, int depth, Graphics gr)
{
Pen p = Pens.SteelBlue;
for (int i = 0; i < Math.Sqrt(numOfCells) + 1; i++)
{
// Vertical
DrawLine(gr, p, new Point3D(i * cellSize + 200, 200, depth), new Point3D(i * cellSize + 200, 700, depth));
// Horizontal
DrawLine(gr, p, new Point3D(200, i * cellSize + 200, depth), new Point3D(700, i * cellSize + 200, depth));
}
}
/// <summary>
/// Draws a line from one 3DPoint to another
/// </summary>
private void DrawLine(Graphics graphics, Pen pen, Point3D p1, Point3D p2)
{
PointF pointFrom = Project(p1);
PointF pointTo = Project(p2);
graphics.DrawLine(pen, pointFrom, pointTo);
}
/// <summary>
/// Draws a small Rectangle to represent the center point for each cell in the grid
/// </summary>
private void DrawRectangle(Graphics graphics, Brush brush, Point3D center)
{
PointF center2D = Project(center);
graphics.FillRectangle(brush, center2D.X, center2D.Y, 2, 2);
}
/// <summary>
/// Projects a Point3D to a PointF
/// </summary>
///
/// <summary>
/// Draws a string at the specified position
/// </summary>
private void DrawString(String s, Graphics gr, Font f, Brush fill, Point3D center, float radius)
{
PointF center2D = Project(center);
gr.DrawString(s, f, fill, center2D.X - radius, center2D.Y - radius);
}
/// <summary>
/// Draws a string at the specified position
/// </summary>
private void DrawImage(String path, Graphics gr, float x, float y, int rectX, int rectY)
{
gr.DrawImage(new Bitmap(path), new Rectangle((int)x, (int)y, rectX, rectY)); // draw AUV
}
/// <summary>
/// Draws a transmission range for each node at the specified position
/// </summary>
private void DrawTransmissionRange(Graphics gr, Pen color, Point3D center, int tRange)
{
PointF center2D = Project(center);
gr.DrawEllipse(color, center2D.X - (tRange / 2) + 5, center2D.Y - (tRange / 2) + 5, tRange, tRange); // draw the tranmission range of node
}
/// <summary>
/// Converts from 3D point to 2D point
/// </summary>
private PointF Project(Point3D p)
{
Perspective per = new Perspective();
return per.Project(p);
}
#endregion
#region Cells Center Points
public void calculateCellsCenters(int intialPointX, int intialPointY, int lastPointX, int lastPointY, int cells, int squareGridX, int squareGridY)
{
double diagonalLengthEachCell;
numOfCells = cells;
int netArea = squareGridX * squareGridY;
double cellArea = netArea / numOfCells;
FileStream fs = new FileStream("C:/Users/AMCT/Desktop/testPositions.txt", FileMode.Append, FileAccess.Write);
cellSide = (int)Math.Sqrt(cellArea);
int centerPointEachCell;
columnsXs = new int[columns + 1];
cellsCenters = new int[2, rows]; // 0 for the point on the x axis and 1 for the point on the y axis so this is why the first element of size 2
rowsYs = new int[rows + 1];
diagonalLengthEachCell = cellSide * Math.Sqrt(2);
centerPointEachCell = (int)diagonalLengthEachCell / 3;
columnsXs[0] = intialPointX; // to let the first point for the first column equal to 300 later on
//Calculate The Columns Points
for (int k = 1; k < (columns + 1); k++)
columnsXs[k] = columnsXs[k - 1] + cellSide;
rowsYs[0] = intialPointY; // its equal to 175 in our case to let the first pint for the first column equal to 200 later on
//Calculate The Rows Points
for (int s = 1; s < (rows + 1); s++)
rowsYs[s] = rowsYs[s - 1] + cellSide;
/***calculate-centers***/
using (StreamWriter sw = new StreamWriter(fs))
{
for (int i = 0; i < rows; i++)
{
cellsCenters[1, i] = rowsYs[i] + centerPointEachCell;
for (int j = 0; j < columns; j++)
{
cellsCenters[0, j] = columnsXs[j] + centerPointEachCell;
sw.Write("({0},{1}) ", cellsCenters[0, j], cellsCenters[1, i]);
}
sw.WriteLine();
}
}
}
#endregion
public void makeDrawing()
{
iSetupDisplay = 0;
if (iSetupDisplay != -1)
{
iSetupDisplay += 10;
if (iSetupDisplay >= topology2.Width)
iSetupDisplay = -1;
topology2.Refresh();
}
}
}
}
I used this method in the previous code to enable the drawing:
public void makeDrawing()
{
iSetupDisplay = 0;
if (iSetupDisplay != -1)
{
iSetupDisplay += 10;
if (iSetupDisplay >= topology2.Width)
iSetupDisplay = -1;
topology2.Refresh();
}
}
But I can't get the things painted on the picture box as I want! The following code is the code I use to make the projection:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using AUVtopology;
namespace AUV_Topology
{
[TypeConverter(typeof(ExpandableObjectConverter))]
public class Perspective
{
public float X_shift { get; set; }
public float Y_shift { get; set; }
public float X_x { get; set; }
public float X_y { get; set; }
public float X_z { get; set; }
public float Y_x { get; set; }
public float Y_y { get; set; }
public float Y_z { get; set; }
public Perspective()
{
this.X_shift = 420;
this.Y_shift = -400;
this.X_x = -0.4f;
this.X_y = 1.0f;
this.X_z = 0.0f;
this.Y_x = 0.4f;
this.Y_y = 0.0f;
this.Y_z = 1.0f;
}
public PointF Project(Form1.Point3D p)
{
return new PointF(X_shift + X_x * p.X + X_y * p.Y + X_z * p.Z, Y_shift + Y_x * p.X + Y_y * p.Y + Y_z * p.Z);
}
public PointF Project(Form2.Point3D p)
{
return new PointF(X_shift + X_x * p.X + X_y * p.Y + X_z * p.Z, Y_shift + Y_x * p.X + Y_y * p.Y + Y_z * p.Z);
}
}
public class PerspectiveGrid : Control
{
private Perspective _perspective;
public Perspective Perspective
{
get { return _perspective; }
set
{
_perspective = value;
Invalidate();
}
}
public PerspectiveGrid()
{
Perspective = new Perspective
{
X_shift = 420,
Y_shift = -400,
X_x = -0.4f,
X_y = 1.0f,
X_z = 0.0f,
Y_x = 0.4f,
Y_y = 0.0f,
Y_z = 1.0f,
};
}
}
}
Is the problem in the method that I use to enable drawing or something else?!
It's easy. You just need to get graphics context of the image box.
Graphics g = Graphics.FromImage(this.pictureBox1.Image);
After you do that, you use the "g" in my example to do any line drawing, etc that you want to do. Not that this will still require you to invalidate the picture box after drawing to it, but you don't have to have your drawing code in
Form_Paint, and you don't need to mess with buffering settings. Personally i prefer this method to drawing in the Form_paint since it is persistent and doesn't have to be redrawn every frame (manually).
To prove it works:

Problems while moving picturebox on ellipse

I want to make a program that simulate planets moving in solar system but some planet is going out of the orbit.
Picture 1
Picture 2
Here I try to move the planets around the sun.
planetDay is number of days on that planet reported to a day of earth
The planets is not following the orbit and i think here is the problem but I'm not sure, when I modify the location of planet I convert X and Y to int and when I do this I round that numbers
private void MovePlanets()
{
double x;
double y;
int k = 0;
foreach (PictureBox pic in pictureBox1.Controls)
{
if (pic.Name == "sun")
{
continue;
}
x = sun.Location.X + (rectangle[k].Width / 2 * Math.Cos(planetDay[k] + alpha));
y = sun.Location.Y + (rectangle[k].Height / 2 * Math.Sin(planetDay[k] + alpha));
pic.Location = new Point(Convert.ToInt32(x), Convert.ToInt32(y));
k++;
if (k == 8)
{
k = 0;
}
}
alpha += 0.1;
}
Here I generate the rectangle that I use to draw the ellipses
private void Orbit()
{
int x1 = 30;
foreach (PictureBox pic in pictureBox1.Controls)
{
if (pic.Name == "sun")
{
continue;
}
Rectangle r = new Rectangle
(
pic.Location.X + pic.Size.Width / 2,
(sun.Location.Y + sun.Size.Width / 2) - x1,
((sun.Location.X + sun.Size.Width / 2) - (pic.Location.X + pic.Size.Width / 2)) * 2,
x1 * 2
);
rectangle.Add(r);
x1 += 36;
}
}
And here I draw the ellipses
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Pen p = new Pen(Color.White, 1f);
foreach (Rectangle rec in rectangle)
{
e.Graphics.DrawEllipse(p, rec);
}
}
Can someone help me with that problem ?

How to create a "sharp" gradient in Windows Forms?

I need to fill a rectangle with a black to white (transparent) gradient. However, I could only find a GradientBrush class and all examples I found showed smooth transition and I want sharp bars. That's what I need:
You need to average the colors between your start color and your end color. Here is a routine that does all that, using an averaging formula found here: Generate Color Gradient in C#
private void PaintGradientBars(Graphics g, Rectangle r,
Color startColor, Color endColor, int numBars) {
int rMin = startColor.R;
int gMin = startColor.G;
int bMin = startColor.B;
int rMax = endColor.R;
int gMax = endColor.G;
int bMax = endColor.B;
int left = 0;
for (int i = 0; i < numBars; i++) {
int rAvg = rMin + (int)((rMax - rMin) * i / numBars);
int gAvg = gMin + (int)((gMax - gMin) * i / numBars);
int bAvg = bMin + (int)((bMax - bMin) * i / numBars);
Color useColor = Color.FromArgb(rAvg, gAvg, bAvg);
int width = (r.Width - left) / (numBars - i);
using (SolidBrush br = new SolidBrush(useColor)) {
g.FillRectangle(br, new Rectangle(left, 0, width, r.Height));
}
left += width;
}
}
Then you make a simple call:
private void panel1_Paint(object sender, PaintEventArgs e) {
PaintGradientBars(e.Graphics, panel1.ClientRectangle,
Color.Blue, Color.Green, 5);
}
Resulting in:
in this code i use picturebox, play with 'k' and 'i'
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
int k = 20;
Color mycolor = new Color();
for (int i = 0; i < 10; i++)
{
mycolor = Color.FromArgb(i * k, i * k, i * k);
SolidBrush mybrash = new SolidBrush(mycolor);
e.Graphics.FillRectangle((Brush)mybrash, 0 + i * k, 0, k, k);
}
}
Good luck!

Categories

Resources