I'm using a device that receives a pressure reading in a 4-20MA, converts it to a voltage and scales that within a range and then charts the data in a line graph, live. I am scaling the y-axis and have buttons in place to adjust the y-axis scale during runtime depending on how big the range is needed. So in otherwords, if the pressure starts at 0 psi, then jumps all the way to 20,000, I want the chart to show -100 (minimum - only so that if PSI is at 0, its visible) to 0, 100, 200, ..., 19800, 19900, 20000. But instead if pressure is at say 19743, the scale is "-43, 43, 143, ..., 19843, 19943" something like that. Is there a way to change this so it only counts by "whole hundreds" or something?
My y-axis interval is jumping by 50's so the axis can go 0, 50, 100,... or 0, 100, 200, etc. and so on (Able to jump 500 psi at a time if desired). But I just want to y-axis numbers to show whole hundreds, if that makes sense.
My maximum y-value is the max incoming value (I'm comparing 3 input values) and adding 1,000 to that. So if the current max pressure is 19,000 psi, the chart should show -100 to 20,0000.
My comparisons of incoming values - The names are "RawIn#" but these are already scaled. Bad variable naming, I know.
if (rawIn0 > rawIn1)
{
maxY = Convert.ToInt32(rawIn0);
}
else if (rawIn1 > rawIn0)
{
maxY = Convert.ToInt32(rawIn1);
}
if (maxY < rawIn2)
{
maxY = Convert.ToInt32(rawIn2);
}
if (maxY > absoluteMaxY)
{
absoluteMaxY = maxY;
}
if (rawIn0 > rawIn1)
{
minY = Convert.ToInt32(rawIn1);
}
else if (rawIn1 > rawIn0)
{
minY = Convert.ToInt32(rawIn0);
}
if (minY > rawIn2)
{
minY = Convert.ToInt32(rawIn2);
}
The current way I'm scaling the chart. MinY is always 0. So minimum = -100.
chart1.ChartAreas[0].AxisY.Maximum = absoluteMaxY + 1000;
chart1.ChartAreas[0].AxisY.Minimum = minY - 100;
My buttons on runtime to increase and decrease the interval. The higher the // interval, the easier it is to see the entire chart with less y-axis lines.
private void yValueSizeInc_Click(object sender, EventArgs e)
{
if (chart1.ChartAreas[0].AxisY.Interval < 50)
{
chart1.ChartAreas[0].AxisY.Interval = 50;
}
else
{
chart1.ChartAreas[0].AxisY.Interval += 50;
}
Properties.Settings.Default.pressureInterval =
(int)chart1.ChartAreas[0].AxisY.Interval;
yValueSize.Text = chart1.ChartAreas[0].AxisY.Interval.ToString();
}
private void yValueSizeDec_Click(object sender, EventArgs e)
{
if (chart1.ChartAreas[0].AxisY.Interval <= 50)
{
chart1.ChartAreas[0].AxisY.Interval = 50;
}
else
{
chart1.ChartAreas[0].AxisY.Interval -= 50;
}
Properties.Settings.Default.pressureInterval = (int)
chart1.ChartAreas[0].AxisY.Interval;
yValueSize.Text = chart1.ChartAreas[0].AxisY.Interval.ToString();
}
Pressure count can be seen not uniform
Related
This is my first project in c# and I'm trying to create plots from data.
I'm struggling with drawing minor and major grid lines and labels on a logarithmic scale.
I've set the scale to logarithmic, set the base to 10 and both major and minor intervals to 1, and it works great, however, the interval starts with the minimum value on scale, so for example if data starts at 30M (I'm dealing with frequencies) the next major tick is at 300M and 3G, which is not as it should be.
Is there a way to set major grid to 1, 10, 100 etc, independent of what data is displayed? i've tried changing intervals, base and offset but have not achieved much.
area.AxisX.IsLogarithmic = true;
area.AxisX.LogarithmBase = 10;
area.AxisX.Interval = 1;
//area.AxisX.IntervalOffset = 10000;
area.AxisX.IntervalAutoMode = IntervalAutoMode.FixedCount;
area.AxisX.MajorGrid.Enabled = true;
area.AxisX.MajorTickMark.Enabled = true;
area.AxisX.MinorGrid.Enabled = true;
area.AxisX.MinorGrid.Interval = 1;
area.AxisX.MinorTickMark.Enabled = true;
area.AxisX.MinorTickMark.Interval = 1;
area.AxisX.Minimum = minMaxXY[0]; // in this example 30 M
area.AxisX.Maximum = minMaxXY[1]; // in this example 1 G
here's the link to the current grid
https://ibb.co/3WkxLfc
Thank you for your time and answers!
Thanks to TaW replay I managed to get my program working.
Here is my solution using customLabels location to draw the grid lines.
private void Chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
if (e.Chart.ChartAreas.Count > 0) // I don't yet truly understand when this event occurs,
// so I got plenty of null references.
{
Graphics g = e.ChartGraphics.Graphics;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
Color minorGridColor = Color.Gainsboro;
ChartArea area = e.Chart.ChartAreas[0];
double aymin = area.AxisY.Minimum;
double aymax = area.AxisY.Maximum;
int y0 = (int)area.AxisY.ValueToPixelPosition(aymin);
int y1 = (int)area.AxisY.ValueToPixelPosition(aymax);
foreach (var label in chart1.ChartAreas[0].AxisX.CustomLabels)
{
double xposition = area.AxisX.ValueToPixelPosition(Math.Pow(10, label.FromPosition + 0.1));
if (xposition > area.AxisX.ValueToPixelPosition(minMaxXY[0]) && xposition < area.AxisX.ValueToPixelPosition(minMaxXY[1]))
//this prevents drawing of lines outside of the chart area
{
int x = (int)xposition;
using (Pen dashed_pen = new Pen(Color.FromArgb(10, 0, 0, 0), 1))
{
dashed_pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
g.DrawLine(dashed_pen, x, y0, x, y1);
}
}
}
}
}
I also found the CustomLabel.GridTicks Property, but for some reason it did not work.
Trying to make a simple bacteria-killing game using WinForm in C#, but the bacteria (I am using Panel for the time being) doesn't seem to move around at random.
Specifically, the problem I am having is, the bacteria tries to move towards the upper left corner and move around there only. Ideally, the bacteria needs to move around the rectangle range evenly, but I am not sure how to achieve that.
Look at the gif file below.
As you can see the red Panel moves around the upper left corner only. How can I get it to move everywhere evenly and randomly?
Here is my code:
private Panel _pnlBacteria; //Panel representing a piece of bacteria
private Random r = new Random(); //For randomly-generated values
private int _prevX; //Stores the previous X location
private int _prevY; //Stores the previous Y location
public Form1()
{
InitializeComponent();
_pnlBacteria = new Panel();
/* Get more property assignments to this._pnlBacteria (omitted) */
//Bacteria's start position is also randomly selected
_prevX = r.Next(50, 300);
_prevY = r.Next(50, 500);
}
//Timer runs every 100 seconds changing the location of the bacteria
private void TmrMoveBacteria_Tick(object sender, EventArgs e)
{
int x, y;
//Get random values for X and Y based on where the bacteria was previously
//and move randomly within ±10 range. Also it cannot go off the screen.
do
{
x = r.Next(_prevX - 10, _prevX + 10);
y = r.Next(_prevY - 10, _prevY + 10);
}
while ((y <= 0) || (y >= 500) || (x <= 0) || (x >= 300));
//Save the new location to be used in the next Tick round as previous values
_prevX = x;
_prevY = y;
//Apply the actual location change to the bacteria panel
_pnlBacteria.Top = y;
_pnlBacteria.Left = x;
}
I tried changing the +10 to +12, leaving -10 as it is, but now this only made the bacteria move to the bottom right corner only. I am at a loss.
Can anyone please help?
If you read the documentation of Random.next(int,int) you'll find the the lower bound is inclusive and the upper bound is exclusive, that's why -10 and +11 works.
A slightly different way to tackle this might be to choose a random direction and a random distance to travel in that direction. This will allow more movement over the form if we increase the maximum distance the bacteria can travel before changing direction.
We can also "weight" the randomness of the distance so that shorter distances are chosen more often. This will add more variety and randomness to the movement pattern, while still allowing a few long sprints to another location.
Here's an example that you can copy/paste into a new form project implementing this idea. You can play with the settings for maxDistance (the furthest distance allowed before changing direction) and stepDistance (the distance travelled on each iteration of the Timer). A smaller stepDistance will result in smoother, but slower movement. I've made it pretty small, so I've also decreased the Interval property of the Timer to speed it up.
You'll notice I also added a method to validate that the direction is valid, so that the bacteria doesn't run off the screen. I created an enum to represent directions, which made it easy to check for movement in a particular direction (i.e. if the enum value contains "North" and we're too close to the top, then it's an invalid direction - this covers "North", "NorthWest", and "Northeast" directions).
Edit: I moved the creation of the "weighted distances" list to the constructor, and modified it to select exponentially fewer items rather than linearly fewer items.
Hope it makes sense:
public partial class Form1 : Form
{
// Program Settings and Controls
private readonly Panel pnlBacteria; // Panel representing a piece of bacteria
private readonly Random random = new Random(); // For randomly-generated values
private readonly Timer tmrMoveBacteria; // Timer used for bacteria movement
private readonly int bacteriaSize = 20; // Stores the size for our bacteria
private const int maxDistance = 50; // The maximum number of moves allowed in the same direction.
private const int stepDistance = 3; // The distance to travel on each iteration of the timer. Smaller number is slower and smoother
private readonly List<int> weightedDistances; // Contains a weighted list of distances (lower numbers appear more often than higher ones)
// Bacteria state variables
private Direction direction; // Stores the current direction bacteria is moving
private int distance; // Stores the distance remaining to travel in current direction
// Represents possible directions for bacteria to move
private enum Direction
{
North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest
}
public Form1()
{
InitializeComponent();
// Initialize our weighted differences array so that 1 is
// chosen most often and maxDistance is chosen the least often
weightedDistances = new List<int>();
for (var i = 0; i < maxDistance; i++)
{
var weight = maxDistance / (i + 1);
for (var j = 0; j <= weight; j++)
{
weightedDistances.Add(i + 1);
}
}
// Give life to the bacteria
pnlBacteria = new Panel
{
BackColor = Color.Red,
Width = bacteriaSize,
Height = bacteriaSize,
Left = random.Next(0, ClientRectangle.Width - bacteriaSize),
Top = random.Next(0, ClientRectangle.Height - bacteriaSize)
};
Controls.Add(pnlBacteria);
// Start bacteria movement timer
tmrMoveBacteria = new Timer {Interval = 10};
tmrMoveBacteria.Tick += TmrMoveBacteria_Tick;
tmrMoveBacteria.Start();
}
/// <summary>
/// Sets the direction and distance fields to valid values based on the
/// current bacteria position, direction, and remaining distance
/// </summary>
private void UpdateDirectionAndDistance()
{
// Get all directions
var validDirections = Enum.GetValues(typeof(Direction)).Cast<Direction>();
// Remove invalid directions (based on the bacteria position)
if (pnlBacteria.Top < bacteriaSize) validDirections =
validDirections.Where(dir => !dir.ToString().Contains("North"));
if (pnlBacteria.Right > ClientRectangle.Width - bacteriaSize) validDirections =
validDirections.Where(dir => !dir.ToString().Contains("East"));
if (pnlBacteria.Left < bacteriaSize) validDirections =
validDirections.Where(dir => !dir.ToString().Contains("West"));
if (pnlBacteria.Bottom > ClientRectangle.Height - bacteriaSize) validDirections =
validDirections.Where(dir => !dir.ToString().Contains("South"));
// If we're supposed to keep on moving in the same
// direction and it's valid, then we can exit
if (distance > 0 && validDirections.Contains(direction)) return;
// If we got here, then we're setting a new direction and distance
distance = weightedDistances[random.Next(weightedDistances.Count)];
var directions = validDirections.Where(d => d != direction).ToList();
direction = directions[random.Next(directions.Count)];
}
/// <summary>
/// Executes on each iteration of the timer, and moves the bacteria
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TmrMoveBacteria_Tick(object sender, EventArgs e)
{
// Ensure direction and distance are valid
UpdateDirectionAndDistance();
// Move the bacteria
var dirStr = direction.ToString();
if (dirStr.Contains("North")) pnlBacteria.Top -= stepDistance;
if (dirStr.Contains("East")) pnlBacteria.Left += stepDistance;
if (dirStr.Contains("South")) pnlBacteria.Top += stepDistance;
if (dirStr.Contains("West")) pnlBacteria.Left -= stepDistance;
distance--;
}
}
The left and right arguments of r.Next are inclusive and exclusive respectively.
x = r.Next(_prevX - 10, _prevX + 10);
y = r.Next(_prevY - 10, _prevY + 10);
So the probability space of this code is a 19x19 square off center of (_prevX,_prevY) to its upper left. This means displacement is more likely towards the upper left.
If we use 11s on the right, then the probability space is a 20x20 square centered at (_prevX,_prevY). The bacteria will move more evenly. Its average displacement within its probability square is zero, so there's not a single favored direction. But the diagonal directions will be favored since diagonal displacement is the greatest on average. This may or may not be important depending on the situation.
If we use radius and direction as explained by Rufus L, then we can generate a more "natural" circular probability space. That's why it's the preferred approach.
The problem is that you are moving the object back and forth because the range is prev -+10;
x = r.Next(_prevX - 10, _prevX + 10);
y = r.Next(_prevY - 10, _prevY + 10);
you should add a direction flag for yval and xval, set it with certain probability p(less then 1/2) , when the flag is on go right/up, when its off go left/down ,
if (forwardx){
x = r.Next(_prevX , _prevX + 10);
}
else {
x = r.Next(_prevX - 10, _prevX );
}
if (forwardy){
y = r.Next(_prevY , _prevY + 10);
}
else{
y = r.Next(_prevY - 10 , _prevY );
}
forwardx = r.Next(10) == 1; //p = 0.1
forwardy = r.Next(10) == 1;
Good luck!
You should use the size of your panel.height - size of your square.height same for length instead of constants this way if the screen size changes your game will still work.
_prevX = r.Next(bateriaSize, this.Width-bacteriaSize); //this.Width Gets you the of form
_prevY = r.Next(bateriaSize, this.Height-bacteriaSize); //This.Height gets you the height of form
I am using the scroll wheel to zoom in and out on an object using the following method:
void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
lastMousePositionOnTarget = Mouse.GetPosition(grid);
double max = 255;
double min = .005;
var deltaScale = Math.Max(Math.Log(scaleTransform.ScaleX), double.Epsilon);
var delta = e.Delta > 0 ? Math.Max(e.Delta * deltaScale, .5) : Math.Min(e.Delta * deltaScale, -.5);
double newScale = Math.Max(Math.Min((delta / 250d) + scaleTransform.ScaleX, max), min);
scaleTransform.ScaleX = newScale;
scaleTransform.ScaleY = newScale;
System.Diagnostics.Debug.WriteLine(newScale);
e.Handled = true;
}
I want to have it zoom more slowly when it is zoomed in closer to the max, and faster when the number is closer to the minimum. What I currently have sort of works but not very well. How can I fix this to do what I want?
Assuming I understand this right, you want your deltaScale to be large when zoomed in, but small when zoomed out. Thereby giving you fast zooming when close and slow zooming when far.
If scaletransform.ScaleX gets smaller as you're zoomed in, try something like this:
var deltaScale = Math.Max(K * 1/(scaleTransform.ScaleX), double.Epsilon);
where K is just some const you mess around with until it feels right.
If scaletransform.ScaleX gets larger as you're zoomed in, then try something like like your log, with a larger coefficient than 1:
var deltaScale = Math.Max(5*Math.Log(scaleTransform.ScaleX), double.Epsilon);
This is my final answer, I wouldn't have been able to come up with it if not for GEEF & Pawel so a big thanks to them for giving it their best shot.
void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
double max = 255;
double min = .005;
double scaler = 4;
var deltaScale = Math.Min(Math.Max(scaler * scaleTransform.ScaleX / max, min),1) * Math.Sign(e.Delta);
double newScale = Math.Max(Math.Min(deltaScale + scaleTransform.ScaleX, max), min);
scaleTransform.ScaleX = newScale;
scaleTransform.ScaleY = newScale;
e.Handled = true;
}
I use a ratio of the current scale to the max to get the slope -- and don't allow it to go to fast (max 1) or too slow, min == the min scale. Works OK.
First of all I would not use value e.Delta for calculations (sign is of course needed). This value is not very reliable - in my experience it was close to random noise. Instead use constant value or some counter like how many times in a row zoom in was invoked and how many times in a row zoom out was invoked.
So my first try (with constant value) would look somehow like this.
void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
lastMousePositionOnTarget = Mouse.GetPosition(grid);
double max = 255;
double min = .005;
var deltaScale = Math.Max(Math.Log(scaleTransform.ScaleX), double.Epsilon);
var delta = e.Delta > 0 ? Math.Max(1 * deltaScale, .5) : Math.Min(1 * deltaScale, -.5);
double newScale = Math.Max(Math.Min((delta / 250d) + scaleTransform.ScaleX, max), min);
scaleTransform.ScaleX = newScale;
scaleTransform.ScaleY = newScale;
System.Diagnostics.Debug.WriteLine(newScale);
e.Handled = true;
}
Version with counters would look something like this.
private double counter=0;
private bool isZoomIn=true;
void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
lastMousePositionOnTarget = Mouse.GetPosition(grid);
if( (e.Delta > 0 && isZoomIn) || (e.Delta < 0 && !isZoomIn))
IncreaseCounter(counter);//is another one in a row
else
counter=1;
isZoomIn = e.Delta > 0;//we set this flag for next time
double max = 255;
double min = .005;
var deltaScale = Math.Max(Math.Log(scaleTransform.ScaleX), double.Epsilon);
var delta = e.Delta > 0 ? Math.Max(counter * deltaScale, .5) : Math.Min(counter * deltaScale, -.5);
double newScale = Math.Max(Math.Min((delta / 250d) + scaleTransform.ScaleX, max), min);
scaleTransform.ScaleX = newScale;
scaleTransform.ScaleY = newScale;
System.Diagnostics.Debug.WriteLine(newScale);
e.Handled = true;
}
Note that I used pseudofunction IncreaceCounter instead of just incrementaion because you may want something else than just linear increase.
I'm drawing a Circle made of 360 FillPie. Each FillPie color is taken from a List. I want to return a string that says at which degree is the mouse and how much is the value of the list to put it on a tooltip.
List<int> datiDisco = new List<int>();
public void Paint (Graphics grafica)
{
try
{
for (int i = 0; i < datiDisco.Count; i++)
{
Brush penna = new SolidBrush(Color.FromArgb(255, ScalaGrigi(valori[i]), ScalaGrigi(valori[i]), ScalaGrigi(valori[i])));
grafica.FillPie(penna, 0, 0, 400, 400, i, 1.0f);
}
}
catch
{
}
}
until here the code is working and i managed to draw the circle with the correct color.Now i can't figure out how i can take the coordinate of each fillpie that i have drawn. Can someone help me?
Figuring out which pie segment the mouse cursor lies in is a simple application of trigonometry, specifically an application of the inverse tangent (aka arctangent or atan).
As a quick reminder for those who've encountered this before, or as a lesson for those who haven't, let's look quickly at the tangent function. Trigonometry deals with the geometry of right triangles, and by definition a right triangle has two sides and a hypotenuse. The hypotenuse is a special name for the side of the triangle opposite the right (90° or π/2) angle. The other two sides are helpfully just called sides.
The tangent function's value is the ratio of the side opposite an angle to the side adjacent to that angle. The arctangent is the angle whose tangent is equal to that ratio. Because of the symmetry of the function we need to calculate the angle, and then add or subtract an offset depending on the quadrant to extract the 'real' angle. In diagram form this looks like:
The tangent function has discontinuities at several points, namely when the adjacent side's length is 0 (90° and 270°), so we'll have to treat those points specially.
OK, enough math, now on to the practical application.
For this demo, create a new C# WinForms project, and on the default Form1 add a PictureBox.
First, since I don't have your color generation function, I use the following list of values and helper function:
List<int> values = Enumerable.Range(0, 360).ToList();
int Rescale(int x) => (int)(((double)x / 360.0) * 255.0);
In the constructor hook up a couple events, and set some properties:
public Form1()
{
InitializeComponent();
this.pictureBox1.BorderStyle = BorderStyle.Fixed3D;
this.pictureBox1.Size = new Size(50, 50);
this.Size = new Size(450, 450);
this.DoubleBuffered = true;
this.Paint += Form1_Paint;
this.MouseMove += Form1_MouseMove;
}
To paint the circle I use a slightly modified version of your OnPaint handler:
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(Color.Black);
for (int i = 0; i < values.Count; i++)
{
Brush b = new SolidBrush(Color.FromArgb(255, Rescale(values[i]), 0, 0));
e.Graphics.FillPie(b, 0, 0, 400, 400, (float)i, 1.0f);
}
}
In the MouseMove event is where we do most of the heavy lifting:
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
this.pictureBox1.Location = new Point(e.X + 5, e.Y - 5);
int segment = (int)GetAngle(new Rectangle(0, 0, 400, 400), e.Location);
this.pictureBox1.BackColor = Color.FromArgb(255, Rescale(segment), 0, 0);
}
You may notice that since there are 360 wedges are in increments of a degree, I just truncated the angle. If you need more precision, or you decide to use segments greater than 1 degree, then you could use various rounding algorithms to round the angle to the nearest section of the pie.
At last, we're ready to implement the GetAngle function. First we calculate the center of the circle, because everything is relative to that.
int cx = (rect.Width + rect.X) / 2;
int cy = (rect.Height + rect.Y) / 2;
Next calculate the difference between the mouse's position and the center of the rectangle. (I've inverted the y coordinate to line up with 'standard' Cartesian coordinates, to make things easier, and match the coordinates you'd see in a math textbook.)
float x = pTo.X - cx;
float y = (cy - pTo.Y);
Next check for the arctangent's undefined points (and a couple of shortcuts we can take):
if ((int)x == 0)
{
if (y > 0) return 270;
else return 90;
}
else if ((int)y == 0)
{
if (x > 0) return 0;
else return 180;
}
Calculate the internal angle:
float ccwAngle = (float)Math.Atan(Math.Abs(y) / Math.Abs(x));
And map that angle to the appropriate quadrant:
if (x > 0 && y > 0)
{
}
else if (x < 0 && y > 0)
{
ccwAngle = (float)Math.PI - ccwAngle;
}
else if (x < 0 && y < 0)
{
ccwAngle = ccwAngle + (float)Math.PI;
}
else if (x > 0 && y < 0)
{
ccwAngle *= -1f;
}
Convert the angle from degrees to radians and normalize (make sure it's between 0° and 360°)
ccwAngle *= (float)(180 / Math.PI);
while (ccwAngle > 360) ccwAngle -= 360;
while (ccwAngle < 0) ccwAngle += 360;
Finally convert the counter-clockwise angle we needed to do the math into the clockwise angle that GDI uses, and return the value:
return 360f - ccwAngle;
All that together produces the final result:
(The code above is also available as a complete example in this gist)
I have an image that I want to increase the size or decrease the size if the mouse wheel is scrolled up or down accordingly. If the image reaches a set max size it will not get ant larger and vice versa if making the image smaller. The problem I am having is once you reach the maximum size of the image and continue scrolling up then go to scroll down the image will not get smaller right away until you scrolled down the same number of times you scrolled up while having the image at the max size and again reverse for making the image smaller. ScrollWheelValue is an read only property so it cannot be reset. I was trying to add some logic where if the wheel is scrolled up and the image is max size subtract 120 because 120 is what the mouse increases per scroll. Can anyone help me with this issue? Thanks very much
Original Code:
float scale = ms.ScrollWheelValue / 120;
scaleFactor = scale * scaleChange;
if (scaleFactor > MAX_SCALE)
{
scaleFactor = MAX_SCALE;
}
else if (scaleFactor < MIN_SCALE)
{
scaleFactor = MIN_SCALE;
}
New Code:
if (scaleFactor > MAX_SCALE)
{
scaleFactor = MAX_SCALE;
float newScale = ms.ScrollWheelValue / 120;
if (newScale > scale)
{
scaleCount = scaleCount - 120;
}
if (newScale < scale)
{
scaleCount = scaleCount + 120;
}
}
else if (scaleFactor < MIN_SCALE)
{
scaleFactor = MIN_SCALE;
float newScale = ms.ScrollWheelValue / 120;
if (newScale > scale)
{
scaleCount = scaleCount - 120;
}
if (newScale < scale)
{
scaleCount = scaleCount + 120;
}
}
else
{
scale = ms.ScrollWheelValue / 120 + scaleCount;
scaleFactor = scale * scaleChange;
}
If you read:
MSDN MouseState Scroll Wheel Value
You'll see that it keeps a running value from the beginning of the game. So what you want to do is check it for a change vs. the previous value and do something accordingly.
How you have it set up it seems you don't care about the actual value, just the difference since the last time they scrolled the wheel.
declare these outside of your update loop:
float prevWheelValue;
float currWheelValue;
Then in your update:
prevWheelValue = currWheelValue;
currWheelValue = ms.ScrollWheelValue;
now your checks can simply be if prevWheelValue > < or == to currWheelValue and clamp the value to the boundaries that you want.
Mathhelper.Clamp