Reputation: 381
I have a set of points I want to show on a 2000x2000 canvas. Here is an example: "61.86, 83 - 61.79, 82.91 - 61.77, 82.77 - 61.92, 82.76 - 61.75, 82.7 - 61.79, 82.58 - 61.85, 82.46 - 61.79, 82.17 - 61.72, 81.88 - 61.61, 81.61 - 61.51, 81.33 - 61.49, 81.02 - 61.33, 80.99 - 61.37, 80.83"
These points are from a 100x100 grid so the first one ought to be in the bottom right quarter of my 2000*2000 canvas.
To do this I have code that finds the biggest X and Y and then rescales.
List<double> MinAndMax(List<Node> spots)
{
List<double> retValues = new List<double>();
double xLowest = spots.Select(s => s.X).Min();
double xHighest = spots.Select(s => s.X).Max();
double xDifference = xHighest - xLowest;
double yLowest = spots.Select(s => s.Y).Min();
double yHighest = spots.Select(s => s.Y).Max();
double yDifference = yHighest - yLowest;
if (xLowest < yLowest)
retValues.Add(xLowest);
else
retValues.Add(yLowest);
if (xHighest < yHighest)
retValues.Add(yHighest);
else
retValues.Add(xHighest);
return retValues;
}
int Rescale(double oldValue, double oldMin, double oldMax, int newMin, int newMax)
{
return Convert.ToInt32(((oldValue - oldMin) * (newMax - newMin) / (oldMax - oldMin)) + newMin);
}
I call it like so:
double zoneMin, zoneMax;
int lowestCanvas = 150, highestCanvas = 1850;
List<Node> path = await PathMaker();
List<double> zoneMinMax = MinAndMax(path);
zoneMin = zoneMinMax[0];
zoneMax = zoneMinMax[1];
foreach (Node spot in path)
{
Point point = new Point();
point.X = Rescale(spot.X, zoneMin, zoneMax, lowestCanvas, highestCanvas);
point.Y = Rescale(spot.Y, zoneMin, zoneMax, lowestCanvas, highestCanvas);
NodeSpot dot = new NodeSpot()
{
Name = spot.Name,
Location = point,
IsInPath = true
};
drawingSurface1.Nodes.Add(dot);
}
drawingSurface1.Invalidate();
Instead of getting my little path nicely spread out, I get this odd clump in the bottom LEFT had quadrant.
I can't see where I am going wrong here. What do I need to do in order to have my 14 points spread out over the canvass?
Upvotes: 3
Views: 176
Reputation: 2339
Use the Graphics.PageScale Property
See also Coordinate Systems and Transformations
Upvotes: 0
Reputation: 1088
Your issue is that you are returning a single min value and a single max value. You need separate min and max values for X and Y, as the ranges in each coordinate are different. In your sample data from the question the range of X is [-61.92, 61.86] and the range of Y is [80.83, 83]. Your approach will draw a frame covering [-61.92, -61.92] to [83, 83], with most of the points in one corner.
Your test fails to catch the problem as the X and Y values are the same in the test case. Create a test case where the X values are all negative and the Y values positive, this will show the issue.
Upvotes: 1
Reputation: 155
let's take [[20, 20], [50, 50], [80, 80]] as an easy exemple.
min and max will be 20 and 80 and wanted scale is 0 to 2000.
for the point [50, 50]
(((oldValue - oldMin) * (newMax - newMin) / (oldMax - oldMin)) + newMin)
gives
((50 - 20) * (2000 - 0) / (80 - 20)) + 0
= 30*2000 / 60
= 1000 (which is half the size of the canvas)
seems coherent so the problem is not coming from the transform function
I suggest trying to debug it by printing the [X, Y] values of the "point" to be sure tho
Also print the min max of the oldScale to be sure this is not the problem
Upvotes: 0