I am trying to develop a program using OpenTK. The purpose of this program is to load a STL (stereolithography) file in ASCII format, then render it in OpenTK, and keep track of the selected object using name stack. In this program, I use the mouse right click to get the selected object.
The brief explanation of STL file is here:
https://en.wikipedia.org/wiki/STL_(file_format)
In my code, I am using 2 STL files. The first STL file is a simple geometry (file size 8 kb). The second STL file is a complex geometry (file size 1167 kb). When I used the first STL file and run my code, it just worked fine when I use my mouse right click function.
However, when I used second STL file and run my code (follow by mouse right click), I got this Fatal Execution Engine Error Exception. I am not sure why I get this error. Is it because of the file size is too big? But I can render this second file into OpenTK. Is it because I have to set a large enough buff size here to avoid this exception?
Do you have any idea why this is happening? Is there any method to avoid this error/exception?
The link for these two STL files are here:
https://drive.google.com/drive/folders/1v9bUzqVx1a1_KbnSXCQ5LREoQaAFUn2D?usp=sharing
Here are my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
namespace OpenTK3D
{
public class Game3D
{
private GameWindow window;
private float zoom;
private bool hasRotationStarted;
private int startX;
private int startY;
private float xRotAngle;
private float yRotAngle;
private bool hasPanningStarted;
private float xTrans;
private float yTrans;
private int BUFSIZE = 512;
private string filePath = #"C:\Users\mpelmt\Desktop\ISF forming direction optimization\verify_65_40_yForming_noFlange.STL";
private double angleLimit = 60;
public Game3D(GameWindow wd)
{
this.window = wd;
var zBoundary = zBoundaryValue(filePath);
hasRotationStarted = false;
startX = 0;
startY = 0;
xRotAngle = 28;
yRotAngle = -45;
zoom = -(float)zBoundary;
hasPanningStarted = false;
xTrans = 0;
yTrans = 0;
start();
}
public void start()
{
window.Load += loaded;
window.Resize += resize;
window.RenderFrame += renderFrame;
window.MouseDown += mouseLeftPress;
window.MouseUp += mouseRelease;
window.MouseMove += mouseDragEvent;
window.MouseWheel += MouseWheelHandler;
window.MouseDown += wheelPressEvent;
window.MouseUp += wheelReleaseEvent;
window.MouseMove += wheelDragEvent;
window.MouseDown += select;
window.Run(1.0 / 60.0);
}
private List<double> getAllSTLData(string path)
{
string[] text = System.IO.File.ReadAllLines(path);
List<double> allData = new List<double>();
foreach (var line in text)
{
if (line.Contains("facet normal"))
{
var normal = Array.ConvertAll(line.Remove(0, 16).Split(' '), double.Parse);
allData.AddRange(normal);
}
if (line.Contains("vertex"))
{
var position = Array.ConvertAll(line.Remove(0, 16).Split(' '), double.Parse);
allData.AddRange(position);
}
}
return allData;
}
private Dictionary<int, List<double>> getAllFacets(string path)
{
var allSTLData = getAllSTLData(path);
var allFacet = new Dictionary<int, List<double>>();
for (int i = 0; i < (allSTLData.Count) / 12; i++)
{
allFacet.Add(i + 1, allSTLData.GetRange(12 * i, 12));
}
return allFacet;
}
private double yBoundaryValue(string path)
{
var allFacets = getAllFacets(path);
var listOfY = new List<double>();
foreach (KeyValuePair<int, List<double>> kp in allFacets)
{
var vertex = kp.Value.GetRange(3, 9);
listOfY.Add(vertex[1]);
listOfY.Add(vertex[4]);
listOfY.Add(vertex[7]);
}
return listOfY.Max() - listOfY.Min();
}
private double xBoundaryValue(string path)
{
var allFacets = getAllFacets(path);
var listOfX = new List<double>();
foreach (KeyValuePair<int, List<double>> kp in allFacets)
{
var vertex = kp.Value.GetRange(3, 9);
listOfX.Add(vertex[0]);
listOfX.Add(vertex[3]);
listOfX.Add(vertex[6]);
}
return listOfX.Max() - listOfX.Min();
}
private double zBoundaryValue(string path)
{
var allFacets = getAllFacets(path);
var listOfZ = new List<double>();
foreach (KeyValuePair<int, List<double>> kp in allFacets)
{
var vertex = kp.Value.GetRange(3, 9);
listOfZ.Add(vertex[2]);
listOfZ.Add(vertex[5]);
listOfZ.Add(vertex[8]);
}
return listOfZ.Max() - listOfZ.Min();
}
private List<double> getAngleRangeWithinLimit(double angleLimit)
{
var result = new List<double>();
var section = (int)angleLimit / 5;
var remain = angleLimit % 5;
for (int i = 0; i < section; i++)
{
result.Add(5 * i);
result.Add(5 * i + 5);
}
if (remain != 0)
{
result.Add(result.Last());
result.Add(result.Last() + remain);
}
return result;
}
public Dictionary<int, List<double>> pickSelectFacetsByAngleInYForm(string path, double angleLimit)
{
var result = new Dictionary<int, List<double>>();
var allFacets = getAllFacets(path);
var angleRange = getAngleRangeWithinLimit(angleLimit);
foreach (KeyValuePair<int, List<double>> kp in allFacets)
{
var data = kp.Value;
var id = kp.Key;
var tempList = new List<double>();
var angle = Math.Acos(Math.Abs(data[1])) * 180 / (Math.PI);
for (int i = 0; i < angleRange.Count / 2; i++)
{
if (angle >= angleLimit)
{
tempList.AddRange(data);
tempList.Add(angleLimit + 1);
break;
}
else if (angle >= angleRange[2 * i] && angle <= angleRange[2 * i + 1])
{
tempList.AddRange(data);
tempList.Add(angleRange[2 * i + 1]);
break;
}
}
result.Add(id, tempList);
}
return result;
}
public void renderColorPlotYForm(string path, double angleLimit)
{
var plotData = pickSelectFacetsByAngleInYForm(path, angleLimit);
foreach (KeyValuePair<int, List<double>> kv in plotData)
{
var id = kv.Key;
var data = kv.Value;
GL.Begin(BeginMode.Triangles);
var colorRange = data.Last();
if (colorRange == 5)
{
// green
GL.Color3(0.0, 1.0, 0.0);
}
if (colorRange == angleLimit + 1)
{
//red
GL.Color3(1.0, 0.0, 0.0);
}
if (colorRange == 30)
{
// yellow
GL.Color3(1.0, 1.0, 0.0);
}
if (colorRange < 30 && colorRange > 5)
{
var diff = 30 - colorRange;
var ratio = diff / 25;
GL.Color3(1 - ratio, 1, 0);
}
if (colorRange > 30 && colorRange < angleLimit + 1)
{
var ratio = (angleLimit - colorRange) / angleLimit;
GL.Color3(1, 1 - ratio, 0);
}
var listOfVertex = data.GetRange(3, 9);
for (int i = 0; i < 3; i++)
{
var vertex = listOfVertex.GetRange(3 * i, 3);
GL.Vertex3(vertex[0], vertex[1], vertex[2]);
}
GL.End();
}
}
public void pickSelectColorPlotYForm(string path, double angleLimit)
{
var plotData = pickSelectFacetsByAngleInYForm(path, angleLimit);
foreach (KeyValuePair<int, List<double>> kv in plotData)
{
var id = kv.Key;
var data = kv.Value;
GL.LoadName(id);
GL.Begin(BeginMode.Triangles);
var colorRange = data.Last();
if (colorRange == 5)
{
// green
GL.Color3(0.0, 1.0, 0.0);
}
if (colorRange == angleLimit + 1)
{
//red
GL.Color3(1.0, 0.0, 0.0);
}
if (colorRange == 30)
{
// yellow
GL.Color3(1.0, 1.0, 0.0);
}
if (colorRange < 30 && colorRange > 5)
{
var diff = 30 - colorRange;
var ratio = diff / 25;
GL.Color3(1 - ratio, 1, 0);
}
if (colorRange > 30 && colorRange < angleLimit + 1)
{
var ratio = (angleLimit - colorRange) / angleLimit;
GL.Color3(1, 1 - ratio, 0);
}
var listOfVertex = data.GetRange(3, 9);
for (int i = 0; i < 3; i++)
{
var vertex = listOfVertex.GetRange(3 * i, 3);
GL.Vertex3(vertex[0], vertex[1], vertex[2]);
}
GL.End();
}
}
public void loaded(object o, EventArgs e)
{
GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL.Enable(EnableCap.DepthTest);
}
public void renderFrame(object o, EventArgs e)
{
var xBoundary = xBoundaryValue(filePath);
var yBoundary = yBoundaryValue(filePath);
var zBoundary = zBoundaryValue(filePath);
var xCen = xBoundary / 2;
var yCen = yBoundary / 2;
var zCen = zBoundary / 2;
GL.LoadIdentity();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Translate(xTrans, yTrans, zoom*3);
GL.Rotate(xRotAngle, 1.0, 0, 0);
GL.Rotate(yRotAngle, 0, 1, 0);
renderColorPlotYForm(filePath, angleLimit);
window.SwapBuffers();
}
public void resize(object o, EventArgs e)
{
var zBoundary = zBoundaryValue(filePath);
GL.Viewport(0, 0, window.Width, window.Height);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
// the fov must be radian
var matrix = Matrix4.CreatePerspectiveFieldOfView(45.0f*(MathHelper.Pi)/180, window.Width / window.Height, 1.0f, (float)zBoundary * (float)zBoundary);
GL.LoadMatrix(ref matrix);
GL.MatrixMode(MatrixMode.Modelview);
}
private void processHits(int hits, int[] buffer)
{
Console.WriteLine("hit: {0}", hits);
if (hits > 0)
{
int choose = buffer[3];
int depth = buffer[1];
for (int i = 0; i < hits; i++)
{
if (buffer[i * 4 + 1] < depth)
{
choose = buffer[i * 4 + 3];
depth = buffer[i * 4 + 1];
}
}
Console.WriteLine("choosen: {0}", choose);
}
}
private void GluPickMatrix(double x, double y, double deltax, double deltay, int[] viewport)
{
if (deltax <= 0 || deltay <= 0)
{
return;
}
GL.Translate((viewport[2] - 2 * (x - viewport[0])) / deltax, (viewport[3] - 2 * (y - viewport[1])) / deltay, 0);
GL.Scale(viewport[2] / deltax, viewport[3] / deltay, 1.0);
}
public void select(object o, MouseEventArgs e)
{
var zBoundary = zBoundaryValue(filePath);
var mouse = Mouse.GetState();
if (mouse[MouseButton.Right])
{
var buffer = new int[BUFSIZE];
var viewPort = new int[4];
int hits;
GL.GetInteger(GetPName.Viewport, viewPort);
GL.SelectBuffer(BUFSIZE, buffer);
GL.RenderMode(RenderingMode.Select);
GL.InitNames();
GL.PushName(0);
GL.MatrixMode(MatrixMode.Projection);
GL.PushMatrix();
GL.LoadIdentity();
GluPickMatrix(e.Mouse.X, viewPort[3] - e.Mouse.Y, 5.0, 5.0, viewPort);
var matrix = Matrix4.CreatePerspectiveFieldOfView(45.0f * (MathHelper.Pi) / 180, window.Width / window.Height, 1.0f, (float)zBoundary * (float)zBoundary);
GL.MultMatrix(ref matrix);
GL.MatrixMode(MatrixMode.Modelview);
pickSelectColorPlotYForm(filePath, angleLimit);
GL.MatrixMode(MatrixMode.Projection);
GL.PopMatrix();
GL.MatrixMode(MatrixMode.Modelview);
GL.Flush();
hits = GL.RenderMode(RenderingMode.Render);
processHits(hits, buffer);
}
}
public void mouseLeftPress(object sender, MouseEventArgs e)
{
if (e.Mouse.LeftButton == ButtonState.Pressed)
{
hasRotationStarted = true;
startX = e.Mouse.X;
startY = e.Mouse.Y;
}
}
public void mouseRelease(object sender, MouseEventArgs e)
{
if (e.Mouse.LeftButton == ButtonState.Released)
{
hasRotationStarted = false;
}
}
public void mouseDragEvent(object sender, MouseEventArgs e)
{
if (hasRotationStarted == true && e.Mouse.X != e.Mouse.Y)
{
xRotAngle = xRotAngle + (e.Mouse.Y - startY);
yRotAngle = yRotAngle + (e.Mouse.X - startX);
startX = e.Mouse.X;
startY = e.Mouse.Y;
}
}
public void MouseWheelHandler(object sender, MouseWheelEventArgs e)
{
var xBoundary = xBoundaryValue(filePath);
if (e.Delta > 0)
{
zoom += 0.1f * (float)xBoundary;
}
if (e.Delta < 0)
{
zoom -= 0.1f * (float)xBoundary;
}
}
public void wheelPressEvent(object sender, MouseEventArgs e)
{
if (e.Mouse.MiddleButton == ButtonState.Pressed)
{
hasPanningStarted = true;
startX = e.Mouse.X;
startY = e.Mouse.Y;
}
}
public void wheelReleaseEvent(object sender, MouseEventArgs e)
{
if (e.Mouse.MiddleButton == ButtonState.Released)
{
hasPanningStarted = false;
}
}
public void wheelDragEvent(object sender, MouseEventArgs e)
{
if (hasPanningStarted == true)
{
xTrans = xTrans + 2 * (e.Mouse.X - startX);
yTrans = yTrans - 2 * (e.Mouse.Y - startY);
startX = e.Mouse.X;
startY = e.Mouse.Y;
}
}
}
}
Here is the main function:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;
namespace OpenTK3D
{
class Program
{
static void Main(string[] args)
{
var window = new GameWindow(500, 500);
var gm = new Game3D(window);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Press enter to finish...");
Console.ReadLine();
}
}
}
This is the result when I run my code using the first STL file (it works fine):
When I run my code using the second STL file, I got this Fatal Execution Engine Error:
Related
I'm currently trying to learn how to use multithreading in C# and I'm really struggling with letting the user choose how many threads to use from a UI.
I have, with the help of a few sources, written the code to mask a image using the median filter and now want to apply multithreading (1-64).
I know how threads work, but I'm struggling to find a way to implement it in this program.
Can someone please help me understand by not showing me the code needed, but explaining where threading should be implemented and how to allow the user to choose the amount of threads.
Code
class ExtBitmap
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing.Imaging;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Drawing.Drawing2D;
namespace EilandFotoPRAK1
{
public static class ExtBitmap
{
public static Bitmap CopyToSquareCanvas(this Bitmap sourceBitmap, int canvasWidthLenght)
{
float ratio = 1.0f;
int maxSide = sourceBitmap.Width > sourceBitmap.Height ?
sourceBitmap.Width : sourceBitmap.Height;
ratio = (float)maxSide / (float)canvasWidthLenght;
Bitmap bitmapResult = (sourceBitmap.Width > sourceBitmap.Height ?
new Bitmap(canvasWidthLenght, (int)(sourceBitmap.Height / ratio))
: new Bitmap((int)(sourceBitmap.Width / ratio), canvasWidthLenght));
using (Graphics graphicsResult = Graphics.FromImage(bitmapResult))
{
graphicsResult.CompositingQuality = CompositingQuality.HighQuality;
graphicsResult.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphicsResult.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphicsResult.DrawImage(sourceBitmap,
new Rectangle(0, 0,
bitmapResult.Width, bitmapResult.Height),
new Rectangle(0, 0,
sourceBitmap.Width, sourceBitmap.Height),
GraphicsUnit.Pixel);
graphicsResult.Flush();
}
return bitmapResult;
}
public static Bitmap MedianFilter(this Bitmap sourceBitmap,
int matrixSize,
int bias = 0,
bool grayscale = false)
{
BitmapData sourceData =
sourceBitmap.LockBits(new Rectangle(0, 0,
sourceBitmap.Width, sourceBitmap.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb);
byte[] pixelBuffer = new byte[sourceData.Stride *
sourceData.Height];
byte[] resultBuffer = new byte[sourceData.Stride *
sourceData.Height];
Marshal.Copy(sourceData.Scan0, pixelBuffer, 0,
pixelBuffer.Length);
sourceBitmap.UnlockBits(sourceData);
if (grayscale == true)
{
float rgb = 0;
for (int k = 0; k < pixelBuffer.Length; k += 4)
{
rgb = pixelBuffer[k] * 0.11f;
rgb += pixelBuffer[k + 1] * 0.59f;
rgb += pixelBuffer[k + 2] * 0.3f;
pixelBuffer[k] = (byte)rgb;
pixelBuffer[k + 1] = pixelBuffer[k];
pixelBuffer[k + 2] = pixelBuffer[k];
pixelBuffer[k + 3] = 255;
}
}
int filterOffset = (matrixSize - 1) / 2;
int calcOffset = 0;
int byteOffset = 0;
List<int> neighbourPixels = new List<int>();
byte[] middlePixel;
for (int offsetY = filterOffset; offsetY <
sourceBitmap.Height - filterOffset; offsetY++)
{
for (int offsetX = filterOffset; offsetX <
sourceBitmap.Width - filterOffset; offsetX++)
{
byteOffset = offsetY *
sourceData.Stride +
offsetX * 4;
neighbourPixels.Clear();
for (int filterY = -filterOffset;
filterY <= filterOffset; filterY++)
{
for (int filterX = -filterOffset;
filterX <= filterOffset; filterX++)
{
calcOffset = byteOffset +
(filterX * 4) +
(filterY * sourceData.Stride);
neighbourPixels.Add(BitConverter.ToInt32(
pixelBuffer, calcOffset));
}
}
neighbourPixels.Sort();
middlePixel = BitConverter.GetBytes(
neighbourPixels[filterOffset]);
resultBuffer[byteOffset] = middlePixel[0];
resultBuffer[byteOffset + 1] = middlePixel[1];
resultBuffer[byteOffset + 2] = middlePixel[2];
resultBuffer[byteOffset + 3] = middlePixel[3];
}
}
Bitmap resultBitmap = new Bitmap(sourceBitmap.Width,
sourceBitmap.Height);
BitmapData resultData =
resultBitmap.LockBits(new Rectangle(0, 0,
resultBitmap.Width, resultBitmap.Height),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb);
Marshal.Copy(resultBuffer, 0, resultData.Scan0,
resultBuffer.Length);
resultBitmap.UnlockBits(resultData);
return resultBitmap;
}
}
}
FrmPhoto class
---------------------------------------How the GUI Looks
public partial class FrmPhoto : Form
{
private Bitmap originalBitmap = null;
private Bitmap previewBitmap = null;
private Bitmap resultBitmap = null;
public FrmPhoto()
{
InitializeComponent();
cmbEdge.SelectedIndex = 0;
}
private void btnOpen_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Title = "Select an image file.";
dialog.Filter = "Png Images(*.png)|*.png|Jpeg Images(*.jpg)|*.jpg";
dialog.Filter += "|Bitmap Images(*.bmp)|*.bmp";
if (dialog.ShowDialog() == DialogResult.OK)
{
StreamReader streamReader = new StreamReader(dialog.FileName);
originalBitmap = (Bitmap)Bitmap.FromStream(streamReader.BaseStream);
streamReader.Close();
previewBitmap = originalBitmap.CopyToSquareCanvas(pix1.Width);
pix1.Image = previewBitmap;
}
}
private void ApplyFilter(bool preview)
{
if (previewBitmap == null || cmbEdge.SelectedIndex == -1)
{
return;
}
Bitmap selectedSource = null;
Bitmap bitmapResult = null;
if (preview == true)
{
selectedSource = previewBitmap;
}
else
{
selectedSource = originalBitmap;
}
if (selectedSource != null)
{
if (cmbEdge.SelectedItem.ToString() == "None")
{
bitmapResult = selectedSource;
}
else if (cmbEdge.SelectedItem.ToString() == "Median 3x3")
{
bitmapResult = selectedSource.MedianFilter(3);
}
else if (cmbEdge.SelectedItem.ToString() == "Median 5x5")
{
bitmapResult = selectedSource.MedianFilter(5);
}
else if (cmbEdge.SelectedItem.ToString() == "Median 7x7")
{
bitmapResult = selectedSource.MedianFilter(7);
}
else if (cmbEdge.SelectedItem.ToString() == "Median 9x9")
{
bitmapResult = selectedSource.MedianFilter(9);
}
else if (cmbEdge.SelectedItem.ToString() == "Median 11x11")
{
bitmapResult = selectedSource.MedianFilter(11);
}
else if (cmbEdge.SelectedItem.ToString() == "Median 13x13")
{
bitmapResult = selectedSource.MedianFilter(13);
}
}
if (bitmapResult != null)
{
if (preview == true)
{
pix1.Image = bitmapResult;
}
else
{
resultBitmap = bitmapResult;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
ApplyFilter(true);
}
}
We can use Parallel.For method that will make parallelization for us.
We have to make all variables that are modified inside the parallel loop are local.
int filterOffset = (matrixSize - 1) / 2;
//int calcOffset = 0;
//int byteOffset = 0;
//List<int> neighbourPixels = new List<int>();
//byte[] middlePixel;
var w = sourceBitmap.Width - filterOffset;
for (int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++)
{
Parallel.For(filterOffset, w, offsetX =>
{
var byteOffset = offsetY * sourceData.Stride + offsetX * 4; // local
var neighbourPixels = new List<int>(); // local
//neighbourPixels.Clear();
for (int filterY = -filterOffset; filterY <= filterOffset; filterY++)
{
for (int filterX = -filterOffset; filterX <= filterOffset; filterX++)
{
var calcOffset = byteOffset + (filterX * 4) + (filterY * sourceData.Stride); // local
neighbourPixels.Add(BitConverter.ToInt32(pixelBuffer, calcOffset));
}
}
neighbourPixels.Sort();
var middlePixel = BitConverter.GetBytes(neighbourPixels[filterOffset]); // local
resultBuffer[byteOffset] = middlePixel[0];
resultBuffer[byteOffset + 1] = middlePixel[1];
resultBuffer[byteOffset + 2] = middlePixel[2];
resultBuffer[byteOffset + 3] = middlePixel[3];
});
};
This gives more than a two time increase in performance on my machine (2 physical cores, 4 logical).
Parallelization of the outer loop would certainly give more acceleration. However, to make it much more difficult.
In a similar way it is possible to make a parallelization of the grayscale filter.
I'm converting a fractal renderer from Java to C# for an assignment and I think I have everything set up but the fractal itself won't render.
This is a photo of when I run the program:
And here is how my files are laid out in the folder that contains the project itself:
This is the code that I am using for the actually rendering itself which I think has no errors but if I've missed something extremely obvious then I'm sorry for wasting all of your time:
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 WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
init();
start();
this.DoubleBuffered = true;
}
//code to convert HSB to RGB from HSB.cs. All your code so i made it take up less space.
public struct HSBColor
{
float h;
float s;
float b;
int a;
public HSBColor(float h, float s, float b) { this.a = 0xff; this.h = Math.Min(Math.Max(h, 0), 255); this.s = Math.Min(Math.Max(s, 0), 255); this.b = Math.Min(Math.Max(b, 0), 255); }
public HSBColor(int a, float h, float s, float b) { this.a = a; this.h = Math.Min(Math.Max(h, 0), 255); this.s = Math.Min(Math.Max(s, 0), 255); this.b = Math.Min(Math.Max(b, 0), 255); }
public float H { get { return h; } }
public float S { get { return s; } }
public float B { get { return b; } }
public int A { get { return a; } }
public Color Color { get { return FromHSB(this); } }
public static Color FromHSB(HSBColor hsbColor)
{
float r = hsbColor.b;
float g = hsbColor.b;
float b = hsbColor.b;
if (hsbColor.s != 0)
{
float max = hsbColor.b; float dif = hsbColor.b * hsbColor.s / 255f; float min = hsbColor.b - dif; float h = hsbColor.h * 360f / 255f;
if (h < 60f) { r = max; g = h * dif / 60f + min; b = min; }
else if (h < 120f) { r = -(h - 120f) * dif / 60f + min; g = max; b = min; }
else if (h < 180f) { r = min; g = max; b = (h - 120f) * dif / 60f + min; }
else if (h < 240f) { r = min; g = -(h - 240f) * dif / 60f + min; b = max; }
else if (h < 300f) { r = (h - 240f) * dif / 60f + min; g = min; b = max; }
else if (h <= 360f) { r = max; g = min; b = -(h - 360f) * dif / 60 + min; }
else { r = 0; g = 0; b = 0; }
}
return Color.FromArgb(hsbColor.a, (int)Math.Round(Math.Min(Math.Max(r, 0), 255)), (int)Math.Round(Math.Min(Math.Max(g, 0), 255)), (int)Math.Round(Math.Min(Math.Max(b, 0), 255)));
}
}
private const int MAX = 256; // max iterations
private const double SX = -2.025; // start value real
private const double SY = -1.125; // start value imaginary
private const double EX = 0.6; // end value real
private const double EY = 1.125; // end value imaginary
private static int x1, y1, xs, ys, xe, ye;
private static double xstart, ystart, xende, yende, xzoom, yzoom;
private static float xy;
private int c = 0;
//private Image picture; Taken out, not needed
// create rectangle variable JGB
Rectangle rec;
private Graphics g1;
//private Cursor c1, c2; Taken out, not needed
private System.Drawing.Bitmap bitmap;
public void init()
{
//setSize(640, 480); changed this code to JGB:
this.Size = new Size(640, 480);
// Taken all lines out below. Not needed.
/*finished = false;
addMouseListener(this);
addMouseMotionListener(this);
c1 = new Cursor(Cursor.WAIT_CURSOR);
c2 = new Cursor(Cursor.CROSSHAIR_CURSOR); */
x1 = 640;
y1 = 480;
xy = (float)x1 / (float)y1;
//picture = createImage(x1, y1); Taken out and replaced with JGB:
bitmap = new Bitmap(x1, y1);
//g1 = picture.getGraphics(); changed to get my bitmap
g1 = Graphics.FromImage(bitmap);
//finished = true; Finished variable deleted so not needed
}
//Code below didnt appear to do anything so i deleted it
/*public void destroy() // delete all instances
{
if (finished)
{
removeMouseListener(this);
removeMouseMotionListener(this);
picture = null;
g1 = null;
c1 = null;
c2 = null;
System.gc(); // garbage collection
}
} */
public void start()
{
//action = false;
//rectangle = false;
initvalues();
// added dialog box for instance loading and save varaibles needed for position and zoom to text file
DialogResult dialog = MessageBox.Show("Would You Like to Load Your Last Instance?", "Load Instance?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
if (dialog == DialogResult.Yes)
{
string[] lines = System.IO.File.ReadAllLines(#"C:\Users\Public\Writelines.txt");
xzoom = System.Convert.ToDouble(lines[0]);
yzoom = System.Convert.ToDouble(lines[1]);
xstart = System.Convert.ToDouble(lines[2]);
ystart = System.Convert.ToDouble(lines[3]);
}
else
{
xzoom = (xende - xstart) / (double)x1;
yzoom = (yende - ystart) / (double)y1;
}
mandelbrot();
}
public void stop()
{
}
/*public void paint(Graphics g, PaintEventArgs e)
{
update(g);
}
public void update(Graphics g)
{
//g.DrawImage(picture, 0, 0);
}*/
private void mandelbrot()
{
int x, y;
float h, b, alt = 0.0f;
Color color;
Pen pen = new Pen(Color.Black);
for (x = 0; x < x1; x += 2)
for (y = 0; y < y1; y++)
{
h = pointcolour(xstart + xzoom * (double)x, ystart + yzoom * (double)y, c);
if (h != alt)
{
b = 1.0f - h * h;
color = HSBColor.FromHSB(new HSBColor(h * 255, 0.8f * 255, b * 255));
pen = new Pen(color);
alt = h;
}
g1.DrawLine(pen, x, y, x + 1, y);
}
}
private float pointcolour(double xwert, double ywert, int j)
{
double r = 0.0, i = 0.0, m = 0.0;
// int j = 0;
while ((j < MAX) && (m < 4.0))
{
j++;
m = r * r - i * i;
i = 2.0 * r * i + ywert;
r = m + xwert;
}
return (float)j / (float)MAX;
}
private void initvalues()
{
xstart = SX;
ystart = SY;
xende = EX;
yende = EY;
if ((float)((xende - xstart) / (yende - ystart)) != xy)
xstart = xende - (yende - ystart) * (double)xy;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g1 = e.Graphics;
g1.DrawImage(bitmap, 0, 0, x1, y1);
using (Pen pen = new Pen(Color.White, 2))
{
e.Graphics.DrawRectangle(pen, rec);
}
Invalidate();
}
//added load method
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
xe = e.X;
ye = e.Y;
if (xs < xe)
{
if (ys < ye) rec = new Rectangle(xs, ys, (xe - xs), (ye - ys));
else rec = new Rectangle(xs, ye, (xe - xs), (ys - ye));
}
else
{
if (ys < ye) rec = new Rectangle(xe, ys, (xs - xe), (ye - ys));
else rec = new Rectangle(xe, ye, (xs - xe), (ys - ye));
}
this.Invalidate();
}
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// e.consume();
xs = e.X;
ys = e.Y; // starting point y
this.Invalidate();
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
rec = new Rectangle(0, 0, 0, 0);
if (e.Button == MouseButtons.Left)
{
int z, w;
//e.consume();
//xe = e.X;
//ye = e.Y;
if (xs > xe)
{
z = xs;
xs = xe;
xe = z;
}
if (ys > ye)
{
z = ys;
ys = ye;
ye = z;
}
w = (xe - xs);
z = (ye - ys);
if ((w < 2) && (z < 2)) initvalues();
else
{
if (((float)w > (float)z * xy)) ye = (int)((float)ys + (float)w / xy);
else xe = (int)((float)xs + (float)z * xy);
xende = xstart + xzoom * (double)xe;
yende = ystart + yzoom * (double)ye;
xstart += xzoom * (double)xs;
ystart += yzoom * (double)ys;
}
xzoom = (xende - xstart) / (double)x1;
yzoom = (yende - ystart) / (double)y1;
mandelbrot();
string stringxzoom = xzoom.ToString();
string stringyzoom = yzoom.ToString();
string stringystart = ystart.ToString();
string stringxstart = xstart.ToString();
string[] lines = { stringxzoom, stringyzoom, stringxstart, stringystart };
System.IO.File.WriteAllLines(#"C:\Users\Public\Writelines.txt", lines);
this.Invalidate();
//Repaint();
}
}
private void restartToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Restart();
}
private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void menuToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
}
}
Change your Form1() code into these
InitializeComponent();
init();
start();
this.DoubleBuffered = true;
this.pictureBox1.Image = bitmap;
You took out the InitializeComponent call (which should be automatically generated) and you never set the resulting bitmap as the image of the pictureBox. Also, you might wanna set the picturebox Size mode to Zoom and enlarge it.
For an assignment I've had to convert a fractal rendering program from Java to C# and I think I've done it but when i try to run it I get the error that is present in the title and I have no idea why it is happening. This is the code for the renderer itself which presents me with no errors:
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 Form1
{
public partial class Form1 : Form
{
public Form1()
{
init();
start();
this.DoubleBuffered = true;
}
//code to convert HSB to RGB from HSB.cs. All your code so i made it take up less space.
public struct HSBColor
{
float h;
float s;
float b;
int a;
public HSBColor(float h, float s, float b) { this.a = 0xff; this.h = Math.Min(Math.Max(h, 0), 255); this.s = Math.Min(Math.Max(s, 0), 255); this.b = Math.Min(Math.Max(b, 0), 255); }
public HSBColor(int a, float h, float s, float b) { this.a = a; this.h = Math.Min(Math.Max(h, 0), 255); this.s = Math.Min(Math.Max(s, 0), 255); this.b = Math.Min(Math.Max(b, 0), 255); }
public float H { get { return h; } }
public float S { get { return s; } }
public float B { get { return b; } }
public int A { get { return a; } }
public Color Color { get { return FromHSB(this); } }
public static Color FromHSB(HSBColor hsbColor)
{
float r = hsbColor.b;
float g = hsbColor.b;
float b = hsbColor.b;
if (hsbColor.s != 0)
{
float max = hsbColor.b; float dif = hsbColor.b * hsbColor.s / 255f; float min = hsbColor.b - dif; float h = hsbColor.h * 360f / 255f;
if (h < 60f) { r = max; g = h * dif / 60f + min; b = min; }
else if (h < 120f) { r = -(h - 120f) * dif / 60f + min; g = max; b = min; }
else if (h < 180f) { r = min; g = max; b = (h - 120f) * dif / 60f + min; }
else if (h < 240f) { r = min; g = -(h - 240f) * dif / 60f + min; b = max; }
else if (h < 300f) { r = (h - 240f) * dif / 60f + min; g = min; b = max; }
else if (h <= 360f) { r = max; g = min; b = -(h - 360f) * dif / 60 + min; }
else { r = 0; g = 0; b = 0; }
}
return Color.FromArgb(hsbColor.a, (int)Math.Round(Math.Min(Math.Max(r, 0), 255)), (int)Math.Round(Math.Min(Math.Max(g, 0), 255)), (int)Math.Round(Math.Min(Math.Max(b, 0), 255)));
}
}
private const int MAX = 256; // max iterations
private const double SX = -2.025; // start value real
private const double SY = -1.125; // start value imaginary
private const double EX = 0.6; // end value real
private const double EY = 1.125; // end value imaginary
private static int x1, y1, xs, ys, xe, ye;
private static double xstart, ystart, xende, yende, xzoom, yzoom;
private static float xy;
private int c = 0;
//private Image picture; Taken out, not needed
// create rectangle variable JGB
Rectangle rec;
private Graphics g1;
//private Cursor c1, c2; Taken out, not needed
private System.Drawing.Bitmap bitmap;
public void init()
{
//setSize(640, 480); changed this code to JGB:
this.Size = new Size(640, 480);
// Taken all lines out below. Not needed.
/*finished = false;
addMouseListener(this);
addMouseMotionListener(this);
c1 = new Cursor(Cursor.WAIT_CURSOR);
c2 = new Cursor(Cursor.CROSSHAIR_CURSOR); */
x1 = 640;
y1 = 480;
xy = (float)x1 / (float)y1;
//picture = createImage(x1, y1); Taken out and replaced with JGB:
bitmap = new Bitmap(x1, y1);
//g1 = picture.getGraphics(); changed to get my bitmap
g1 = Graphics.FromImage(bitmap);
//finished = true; Finished variable deleted so not needed
}
//Code below didnt appear to do anything so i deleted it
/*public void destroy() // delete all instances
{
if (finished)
{
removeMouseListener(this);
removeMouseMotionListener(this);
picture = null;
g1 = null;
c1 = null;
c2 = null;
System.gc(); // garbage collection
}
} */
public void start()
{
//action = false;
//rectangle = false;
initvalues();
// added dialog box for instance loading and save varaibles needed for position and zoom to text file
DialogResult dialog = MessageBox.Show("Would You Like to Load Your Last Instance?", "Load Instance?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
if (dialog == DialogResult.Yes)
{
string[] lines = System.IO.File.ReadAllLines(#"C:\Users\Public\Writelines.txt");
xzoom = System.Convert.ToDouble(lines[0]);
yzoom = System.Convert.ToDouble(lines[1]);
xstart = System.Convert.ToDouble(lines[2]);
ystart = System.Convert.ToDouble(lines[3]);
}
else
{
xzoom = (xende - xstart) / (double)x1;
yzoom = (yende - ystart) / (double)y1;
}
mandelbrot();
}
public void stop()
{
}
/*public void paint(Graphics g, PaintEventArgs e)
{
update(g);
}
public void update(Graphics g)
{
//g.DrawImage(picture, 0, 0);
}*/
private void mandelbrot()
{
int x, y;
float h, b, alt = 0.0f;
Color color;
Pen pen = new Pen(Color.Black);
for (x = 0; x < x1; x += 2)
for (y = 0; y < y1; y++)
{
h = pointcolour(xstart + xzoom * (double)x, ystart + yzoom * (double)y, c);
if (h != alt)
{
b = 1.0f - h * h;
color = HSBColor.FromHSB(new HSBColor(h * 255, 0.8f * 255, b * 255));
pen = new Pen(color);
alt = h;
}
g1.DrawLine(pen, x, y, x + 1, y);
}
}
private float pointcolour(double xwert, double ywert, int j)
{
double r = 0.0, i = 0.0, m = 0.0;
// int j = 0;
while ((j < MAX) && (m < 4.0))
{
j++;
m = r * r - i * i;
i = 2.0 * r * i + ywert;
r = m + xwert;
}
return (float)j / (float)MAX;
}
private void initvalues()
{
xstart = SX;
ystart = SY;
xende = EX;
yende = EY;
if ((float)((xende - xstart) / (yende - ystart)) != xy)
xstart = xende - (yende - ystart) * (double)xy;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g1 = e.Graphics;
g1.DrawImage(bitmap, 0, 0, x1, y1);
using (Pen pen = new Pen(Color.White, 2))
{
e.Graphics.DrawRectangle(pen, rec);
}
Invalidate();
}
//added load method
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
xe = e.X;
ye = e.Y;
if (xs < xe)
{
if (ys < ye) rec = new Rectangle(xs, ys, (xe - xs), (ye - ys));
else rec = new Rectangle(xs, ye, (xe - xs), (ys - ye));
}
else
{
if (ys < ye) rec = new Rectangle(xe, ys, (xs - xe), (ye - ys));
else rec = new Rectangle(xe, ye, (xs - xe), (ys - ye));
}
this.Invalidate();
}
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// e.consume();
xs = e.X;
ys = e.Y; // starting point y
this.Invalidate();
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
rec = new Rectangle(0, 0, 0, 0);
if (e.Button == MouseButtons.Left)
{
int z, w;
//e.consume();
//xe = e.X;
//ye = e.Y;
if (xs > xe)
{
z = xs;
xs = xe;
xe = z;
}
if (ys > ye)
{
z = ys;
ys = ye;
ye = z;
}
w = (xe - xs);
z = (ye - ys);
if ((w < 2) && (z < 2)) initvalues();
else
{
if (((float)w > (float)z * xy)) ye = (int)((float)ys + (float)w / xy);
else xe = (int)((float)xs + (float)z * xy);
xende = xstart + xzoom * (double)xe;
yende = ystart + yzoom * (double)ye;
xstart += xzoom * (double)xs;
ystart += yzoom * (double)ys;
}
xzoom = (xende - xstart) / (double)x1;
yzoom = (yende - ystart) / (double)y1;
mandelbrot();
string stringxzoom = xzoom.ToString();
string stringyzoom = yzoom.ToString();
string stringystart = ystart.ToString();
string stringxstart = xstart.ToString();
string[] lines = { stringxzoom, stringyzoom, stringxstart, stringystart };
System.IO.File.WriteAllLines(#"C:\Users\Public\Writelines.txt", lines);
this.Invalidate();
//Repaint();
}
}
private void restartToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Restart();
}
private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void menuToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
}
}
and this is the code that is used for the form designer which was auto generated and I'm not sure why an error is being presented because I've never had one before:
namespace WindowsFormsApplication1
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Text = "Form1";
}
#endregion
}
}
I believe it is caused because your namespaces are not the same. Since the partial code generated by the designer doesn't inherit from Form, you don't have a method to override. Once you make the two classes tie together properly by matching the namespaces, it should work.
To fix it, you can either change the namespace of the designer code to match your namespace of Form1:
namespace Form1
{
partial class Form1
{
//...
}
}
Or change your form to match the designer:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
//....
}
}
Edit the project properties and update the Default namespace to match the desired namespace for all forms
I am creating a class with specific number of objects.When these objects are created and drawn on screen with that capacity again I reinitialize that class.The problem is that I want to reinitialize in such a way that if new objects are created then previous must be persist/drawn on the screen.I am not able to get the logic.
crShade = new CreateShade[Obj_num]; for (int i = incr_Obj; i < crShade.Length; i++) {
int r = rad.Next(0, 7); int x = 0; switch (r) {
case 0: x = 0; break; case 1: x = 120; break; case 2: x = 240; break; case 3: x = 360; break;
}
X_pos.Add(x); crShade[i] = new CreateShade(x, -60, clr[3]); _Shade.Add(crShade[i]);
}
--
public class CreateShade {
public int posX; public int posY; public Color color; Random r = new Random(); private int width = 120; private int height = 60; public static bool _Fall; public static bool check; public static List<int> y_pos = new List<int>(); int balance = 0; public CreateShade(int x, int y, Color color) {
int random = r.Next(0, 4); this.posY = y; this.posX = x; this.color = color;
}
public void draw(SpriteBatch batch) {
batch.Draw(Vimap_ScreenManager.blank, new Rectangle(posX, posY, width, height), color);
}
public void update() {
int counter = 0; if (posY != 740-balance) {
posY += 10; if (counter != y_pos.Count) {
if (new Rectangle(posX, posY, 120, 60).Intersects(new Rectangle(VimapGamePage.X_pos.ElementAt(counter), y_pos.ElementAt(counter), 120, 60))) {
balance = counter * 60;
}
else {
counter++;
}
}
//check = true;
}
else {
y_pos.Add(posY); _Fall = true; // VimapGamePage.End_Reach = true;
}
}
public void Move_X(Point p) {
if (p.X <= 240) {
if (p.X >= 0 && p.X <= 120) {
posX = 0;
}
else if (p.X > 120 && p.X <= 240) {
posX = 120;
}
}
else if (p.X > 240) {
if (p.X > 240 && p.X <= 360) {
posX = 240;
}
else if (p.X > 360 && p.X <= 480) {
posX = 360;
}
}
}
}
I have a chart on my c# windows application.
I want to zoom every point of chart when mouse on them.
like google map
I mean I don't want zoom all part of chart
I want zoom just specefic point like google map
code:
public partial class Form1 : Form
{
int[] myArrayX = new int[5];
double[] myArrayY = new double[5];
int lastX = -1;
double lastY = -0.6;
double xmax;
Graph.Chart chart;
public Form1()
{
InitializeComponent();
this.MouseWheel += new MouseEventHandler(Form1_MouseWheel);
}
void Form1_MouseWheel(object sender, MouseEventArgs e)
{
try
{
if (e.Delta > 0)
{
double xMin = chart.ChartAreas["draw"].AxisX.ScaleView.ViewMinimum;
double xMax = chart.ChartAreas["draw"].AxisX.ScaleView.ViewMaximum;
double yMin = chart.ChartAreas["draw"].AxisY.ScaleView.ViewMinimum;
double yMax = chart.ChartAreas["draw"].AxisY.ScaleView.ViewMaximum;
double posXStart = chart.ChartAreas["draw"].AxisX.PixelPositionToValue(e.Location.X) - (xMax - xMin) / 2;
double posXFinish = chart.ChartAreas["draw"].AxisX.PixelPositionToValue(e.Location.X) + (xMax - xMin) / 2;
double posYStart = chart.ChartAreas["draw"].AxisY.PixelPositionToValue(e.Location.Y) - (yMax - yMin) / 2;
double posYFinish = chart.ChartAreas["draw"].AxisY.PixelPositionToValue(e.Location.Y) + (yMax - yMin) / 2;
chart.ChartAreas["draw"].AxisX.ScaleView.Zoom(posXStart, posXFinish);
chart.ChartAreas["draw"].AxisY.ScaleView.Zoom(posYStart, posYFinish);
}
else if (e.Delta < 0)
{
ZoomOut();
}
}
catch { }
}
private void ZoomOut()
{
chart.ChartAreas["draw"].AxisX.ScaleView.ZoomReset();
chart.ChartAreas["draw"].AxisY.ScaleView.ZoomReset();
}
void CreateNewGraph()
{
// Create new Graph
chart = new Graph.Chart();
chart.Location = new System.Drawing.Point(13, 185);
chart.Size = new System.Drawing.Size(900, 500);
chart.ChartAreas.Add("draw");
chart.ChartAreas["draw"].AxisX.Minimum = 0;
chart.ChartAreas["draw"].AxisX.Maximum = 20;
chart.ChartAreas["draw"].AxisX.Interval = 1;
chart.ChartAreas["draw"].AxisX.MajorGrid.LineColor = Color.White;
chart.ChartAreas["draw"].AxisX.MajorGrid.LineDashStyle = Graph.ChartDashStyle.Dash;
chart.ChartAreas["draw"].AxisY.Minimum = -0.4;
chart.ChartAreas["draw"].AxisY.Maximum = 1;
chart.ChartAreas["draw"].AxisY.Interval = 0.2;
chart.ChartAreas["draw"].AxisY.MajorGrid.LineColor = Color.White;
chart.ChartAreas["draw"].AxisY.MajorGrid.LineDashStyle = Graph.ChartDashStyle.Dash;
chart.ChartAreas["draw"].BackColor = Color.Black;
var series = chart.Series.Add("Test");
chart.Series["Test"].ChartType = Graph.SeriesChartType.Line;
chart.Series["Test"].Color = Color.Yellow;
chart.Series["Test"].BorderWidth = 3;
chart.Legends.Add("MyLegend");
chart.Legends["MyLegend"].BorderColor = Color.YellowGreen;
// Set automatic zooming
chart.ChartAreas["draw"].AxisX.ScaleView.Zoomable = true;
chart.ChartAreas["draw"].AxisY.ScaleView.Zoomable = true;
// Set automatic scrolling
chart.ChartAreas["draw"].CursorX.AutoScroll = true;
chart.ChartAreas["draw"].CursorY.AutoScroll = true;
// Allow user selection for Zoom
chart.ChartAreas["draw"].CursorX.IsUserSelectionEnabled = true;
chart.ChartAreas["draw"].CursorY.IsUserSelectionEnabled = true;
chart.ChartAreas["draw"].AxisX.ScaleView.Zoomable = true;
chart.ChartAreas["draw"].AxisY.ScaleView.Zoomable = true;
//chart.MouseWheel += new MouseEventHandler(chart_MouseWheel);
}
private void Form1_Load(object sender, EventArgs e)
{
CreateNewGraph();
}
private void timer1_Tick(object sender, EventArgs e)
{
fillarray();
for (int i = 1; i <= 5; i += 1)
{
chart.Series["Test"].Points.AddXY(myArrayX[i - 1], myArrayY[i - 1]);
xmax = myArrayX[i - 1];
}
if (xmax >= 20)
{
chart.ChartAreas["draw"].AxisX.ScrollBar.Enabled = true;
chart.ChartAreas["draw"].AxisX.ScaleView.Zoomable = true;
chart.ChartAreas["draw"].AxisX.ScaleView.Zoom(0, xmax);
}
Controls.Add(this.chart);
}
public void fillarray()
{
for (int i = 1; i <= 5; i += 1)
{
lastX = lastX + 1;
myArrayX[i - 1] = lastX;
}
for (int i = 1; i < 5; i += 1)
{
lastY = lastY + 0.2;
myArrayY[i - 1] = lastY;
}
}
}
Asuming that you use the "standard" (since .NET 4.0) Charting Lib which is in the namespace System.Windows.Forms.DataVisualization.Charting. You can implement custom interactivity (zoom when mouse does this or that). MSDN is a good start and GIYF.
http://msdn.microsoft.com/en-us/library/dd456772(v=vs.110).aspx
There are also a lot of examples around the web.
good luck!