C# MS Charts get Y value from a generic X - c#

I have a chart with 3 lines, all of them dynamics (the points series varies any time).
For two lines I have few points, up to 20, and for the other one, that is a Spline, up to 500. (always in the same x range)
I have to verify if the Spline is between the two other lines.
In other words, for each point of the Spline get the Y value of all the lines and verify if it's in the range.
How I could achieve that?
I've already tried the follow code, but when I call an X point that is not defined in the other two Line I'll have only the Y value for the Spline:
var a = chart1.Series.Select(series => series.Points.Where(point => point.XValue == 7).ToList()).ToList();
Follow an image of the graph-like:
The blue and the yellow line are the ones "less defined", and I have to verify if the red one stays between them

It's rather a math problem than a chart problem.
To determine the mid line is in between the upper and lower bounds, it comes down to the linear interpolation of the bounds.
Suppose your upper bound (ub) is defined on five points: 1,2,5,6,9.
The easy way to do the linear interpolation is to find the two closest neighbors and do the weighted average. e.g. ub(5.5) = ub(5)/2 + ub(6)/2
There are many ways to do the 1D linear interpolation and if you search it on stackoverflow you should be able to find existing solutions.

Related

How do I connect four 2D grid points with a smooth curve in C# and give the x and y location back at a certain time?

So I'm trying to connect four grid points with x and y values together with a smooth curve. Given a parameter 'time' I want to receive the x and y locations of the point on the curve at that time.
I've tried multiple options like quadratic bezier curves and such but can't seem to figure it out.
There's no need to visualize it in Unity, wpf or any other way. I don't need a draw method or anything like that. I simply need the position value of the point in the curve.
This is the sort of curve I am looking for:
Thank you in advance for helping me!
Simple approach is using Catmull-Rom splines.
Example of implementation
Some more variants
Note that parameter t varies from 0 to 1 at every point-point interval, so you can map your "position" onto corresponding interval. For example, if position varies from 0 to 1, mutliply it by 3. Integer part of result is interval number, fractional part - parameter t at this interval.

Algorithm to generate equally distributed points in a polygon

I am looking for an algorithm to generate equally distributed points inside a polygon.
Here is the scenario:
I have a polygon specified by the coordinates of the points at the corners (x, y) for each point. And I have the number of points to generate inside the polygon.
For example lets say I have a polygon containing 5 points: (1, 1) ; (1, 2) ; (2, 3) ; (3, 2) ; and (3, 1)
And I need to generate 20 equally distanced points inside that polygon.
Note: Some polygons may not support equally distributed points, but I'm looking to distribute the points in a way to cover all the region of the polygon with as much consistency as possible. (what i mean is I don't want a part with a lot more points than another)
Is there an algorithm to do so? or maybe a library
I am working on a C# application, but any language is ok, since I only need the algorithm and I can translate it.
Thanks a lot for any help
The simple approach I use is:
Triangulate the polygon. Ear clipping is entirely adequate, as all you need is a dissection of the polygon into a set of non-overlapping triangles.
Compute the area of each triangle. Sample from each triangle proportionally to the area of that triangle relative to the whole. This costs only a single uniform random number per sample.
Once a point is determined to have come from a given triangle, sample uniformly over the triangle. This is itself easier than you might think.
So really it all comes down to how do you sample within a triangle. This is easily enough done. A triangle is defined by 3 vertices. I'll call them P1, P2, P3.
Pick ANY edge of the triangle. Generate a point (P4) that lies uniformly along that edge. Thus if P1 and P2 are the coordinates of the corresponding end points, then P will be a uniformly sampled point along that edge, if r has uniform distribution on the interval [0,1].
P4 = (1-r)*P1 + r*P2
Next, sample along the line segment between P3 and P4, but do so non-uniformly. If s is a uniform random number on the interval [0,1], then
P5 = (1-sqrt(s))*P3 + sqrt(s)*P4
r and s are independent pseudo-random numbers of course. Then P5 will be randomly sampled, uniform over the triangle.
The nice thing is it needs no rejection scheme to implement, so long, thin polygons are not a problem. And for each sample, the cost is only in the need to generate three random numbers per event. Since ear clipping is rather simply done and an efficient task, the sampling will be efficient, even for nasty looking polygons or non-convex polygons.
An easy way to do this is this:
Calculate the bounding box
Generate points in that box
Discard all points not in the polygon of interest
This approach generates a certain amount of wasted points. For a triangle, it is never more than 50%. For arbitrary polygons this can be arbitrarily high so you need to see if it works for you.
For arbitrary polys you can decompose the polygon into triangles first which allows you to get to a guaranteed upper bound of wasted points: 50%.
For equally distanced points, generate points from a space-filling curve (and discard all points that are not in the polygon).
You can use Lloyd’s algorithm:
https://en.m.wikipedia.org/wiki/Lloyd%27s_algorithm
You can try the {spatialEco} package (https://cran.r-project.org/web/packages/spatialEco/index.html)
and apply the function sample.poly (https://www.rdocumentation.org/packages/spatialEco/versions/1.3-2/topics/sample.poly)
You can try this code:
library(rgeos)
library(spatialEco)
mypoly = readWKT("POLYGON((1 1,5 1,5 5,1 5,1 1))")
plot(mypoly)
points = sample.poly(mypoly, n= 20, type = "regular")
#points2 = sample.poly(mypoly, n= 20, type = "stratified")
#another type which may answer your problem
plot(points, col="red", add=T)
The easy answer comes from an easier question: How to generate a given number of randomly distributed points from the uniform distribution that will all fit inside a given polygon?
The easy answer is this: find the bounding box of your polygon (let's say it's [a,b] x [c,d]), then keep generating pairs of real numbers, one from U(a,b), the other from U(b,c), until you have n coordinate pairs that fit inside your polygon. This is simple to program, but, if your polygon is very jagged, or thin and skewed, very wasteful and slow.
For a better answer, find the smallest rotated rectangular bounding box, and do the above in transformed coordinates.
Genettic algorithms can do it rather quickly
Reffer to GENETIC ALGORITHMS FOR GRAPH LAYOUTS WITH GEOMETRIC CONSTRAINTS
You can use Force-Directed Graph for that...
Look at http://en.wikipedia.org/wiki/Force-based_algorithms_(graph_drawing)
it defiantly can throw you a bone.
I didn't try it ever,
but i remmember there is a possiblity to set a Fix for some Vertices in the Graph
Your Algorithm will eventually be like
Create a Graph G = Closed Path of the Vertices in V
Fix the Vertecies in place
Add N Verticies to the Graph and Fully connect them with Edges with equal tension value 1.0
Run_force_graph(G)
Scale Graph to bounded Box of
Though it wont be absolute because some convex shapes may produce wiered results (take a Star)
LASTLY: didn't read , but it seems relevant by the title and abstract
take a look at Consistent Graph Layout for Weighted Graphs
Hope this helps...
A better answer comes from a better question. Suppose you want to put a set of n watchtowers to cover a polygon. You could see this as an optimization problem: find the 2n coordinates of the n points that will minimize a cost function (or maximize a value function) that fits your goal. One possible cost function could calculate, for each point, the distance to its closest neighbor or the boundary of the polygon, whichever is less, and calculate the variance of this sequence as a measure of "non-uniformity". You could use a random set of n points, obtained as above, as your initial solution.
I've seen such a "watchtower problem" in some book. Algorithms, calculus, or optimization.
#Youssef: sorry about the delay; a friend came, and a network hiccuped.
#others: have some patience, don't be so trigger-happy.

Fast algorithm to find the x closest points to a given point on a plane

I would like to find a fast algorithm in order to find the x closest points to a given point on a plane.
We are actually dealing with not too many points (between 1,000 and 100,000), but I need the x closest points for every of these points. (where x usually will be between 5 and 20.)
I need to write it in C#.
A bit more context about the use case: These points are coordinates on a map. (I know, this means we are not exactly talking about a plane, but I hope to avoid dealing with projection issues.) In the end points that have many other points close to them should be displayed in red, points that have not too many points close to them should be displayed green. Between these two extremees the points are on a color gradient.
What you need is a data structure appropriate for organizing points in a plane. The K-D-Tree is often used in such situations. See k-d tree on Wikipedia.
Here, I found a general description of Geometric Algorithms
UPDATE
I ported a Java implementation of a KD-tree to C#. Please see User:Ojd/KD-Tree on RoboWiki. You can download the code there or you can download CySoft.Collections.zip directly from my homepage (only download, no docu).
For a given point (not all of them) and as the number of points is not extreme, you could calculate the distance from each point:
var points = new List<Point>();
Point source = ...
....
var closestPoints = points.Where(point => point != source).
OrderBy(point => NotReallyDistanceButShouldDo(source, point)).
Take(20);
private double NotReallyDistanceButShouldDo(Point source, Point target)
{
return Math.Pow(target.X - source.X, 2) + Math.Pow(target.Y - source.Y, 2);
}
(I've used x = 20)
The calculation are based on doubles so the fpu should be able to do a decent job here.
Note that you might get better performance if Point is a class rather than a struct.
You need to create a distance function, then calculate distance for every point and sort the results, and take the first x.
If the results must be 100% accurate then you can use the standard distance function:
d = SQRT((x2 - x1)^2 + (y2 - y1)^2)
To make this more efficent. lets say the distance is k. Take all points with x coordinates between x-k and x+k. similarly take, y-k and y+k. So you have removed all excess coordinates. now make distance by (x-x1)^2 + (y-y1)^2. Make a min heap of k elements on them , and add them to the heap if new point < min(heap). You now have the k minimum elements in the heap.

How to merge two polygons (arrays of objects) programatically?

[edit: I tried to rewrote my question a bit because it seems, that nobody understands what I want... and I thought, that it is a hard algorithm only for me :) ]
Problem I am facing is joining of individual polygons. Each is a 4-point polygon. The final result is then a merge / union of two polygons.
Following image shows one version of possible result (results may vary, because that black filled part can be different for each result).
I start with something like:
Polygon one = [A,B,C,D]; // (A/B/C/D) might look like : new Point {x = 10, y = 15}
Polygon two = [E,F,G,H];
And I need an algorithm for calculating union of these two sets, so I will get result like:
Polygon total = [I,J,K,L,M,N]; // = new points
I don't have to visualize it (even when I do..), I just need the set of points defining new polygon (union of those two), because my final result will be a centroid of that merged polygon.
I already have algorithm to calculate centroid based on set of input points. But I need to get the right points first.
So far, I have found mentions about convex-hull algorithm, but I am afraid that it would generate following polygon (which is wrong):
EDIT:
So different way, how to look at this problem:
I have a program, that is able to work with objects, that are represented by 4 points. Each point has two attributes (x coordinate, y coordinate).
Then the program is able to draw lines between these points. These lines will then look like a square, rectangle or polygon.. this result depends on given coordinates, but I know, that I will be always using points, that will generate polygons. Once the points are connected, the program is able to fill this connected area. Once this is drawn, you can see following image:
BUT: The program doesn't know, that he just made a polygon. He only knows, that he got 4 points from me, he connected them and filled them.
Then I have second object (=polygon), which is defined by another set of points (different coordinates). Program again doesn't know that he's creating a filled polygon.. he just did some operations with 4 given points. Result in this case is another polygon:
Now, we just draw two polygons at display.. and we gave them such coordinates, that they overlap each other. The result looks like this (considering only the filled area):
My program just draw two polygons. Fine. You can see at your screen only one polygon (because there are two overlaping = they look like one piece) and I need to count the centroid of that ONE piece.
I already have an algorithm, that will accept a set of points (representing a points forming polygon) and counting a centroid from these points. But I can't use the algorithm now, because I can't give him the needed points, because I do not know them.
Here are the points, that I want as a result:
So my algorithm should start with points A,B,C,D,E,F,G,H and he should give me points I,J,K,L,M,N as a result.
Summary: I need to count a centroid of polygon which is result of union/merge of two individual polygons, that are overlapping.
And I thought, that union of two polygons would be enough to explain :)
Here http://www.codeproject.com/KB/recipes/Wykobi.aspx is a collection of Computational Geometry algorithms. At least you can start from there.

How to fill a square with smaller squares/rectangles?

In my office at work, we are not allowed to paint the walls, so I have decided to frame out squares and rectangles, attach some nice fabric to them, and arrange them on the wall.
I am trying to write a method which will take my input dimensions (9' x 8' 8") and min/max size (1' x 3', 2', 4', etc..) and generate a random pattern of squares and rectangles to fill the wall. I tried doing this by hand, but I'm just not happy with the layout that I got, and it takes about 35 minutes each time I want to 'randomize' the layout.
One solution is to start with x*y squares and randomly merge squares together to form rectangles. You'll want to give differing weights to different size squares to keep the algorithm from just ending up with loads of tiny rectangles (i.e. large rectangles should probably have a higher chance of being picked for merging until they get too big).
Sounds like a Treemap
Another idea:
1. Randomly generate points on the wall
Use as many points as the number of rectangles you want
Introduce sampling bias to get cooler patterns
2. Build the kd-tree of these points
The kd-tree will split the space in a number of rectangles. There might be too much structure for what you want, but its still a neat geeky algorithm.
(see: http://en.wikipedia.org/wiki/Kd-tree)
Edit: Just looked at JTreeMap, looks a bit like this is what its doing.
If you're talking on a pure programing problem ;) There is a technique called Bin Packing that tries to pack a number of bins into the smallest area possible. There's loads of material out there:
http://en.wikipedia.org/wiki/Bin_packing_problem
http://mathworld.wolfram.com/Bin-PackingProblem.html
http://www.cs.sunysb.edu/~algorith/files/bin-packing.shtml
So you 'could' create a load of random squares and run it through a bin packer to generate your pattern.
I've not implemented a bin packing algorithm myself but I've seen it done by a colleague for a Nike website. Best of luck
Since you can pick the size of the rectangles, this is not a hard problem.
I'd say you can do something as simple as:
Pick an (x,y) coordinate that is not currently inside a rectangle.
Pick a second (x,y) coordinate so that when you draw a rectangle between
the two coordinates, it won't overlap anything. The bounding box of
valid points is just bounded by the nearest rectangles' walls.
Draw that rectangle.
Repeat until, say, you have 90% of the area covered. At that point you
can either stop, or fill in the remaining holes with as big rectangles
as possible.
It might be interesting to parametrize the generation of points, and then make a genetic algorithm. The fitness function will be how much you like the arrangement - it would draw hundreds of arrangements for you, and you would rate them on a scale of 1-10. It would then take the best ones and tweak those, and repeat until you get an arrangement you really like.
Bin packing or square packing?
Bin packing:
http://www.cs.sunysb.edu/~algorith/files/bin-packing.shtml
Square packing:
http://www.maa.org/editorial/mathgames/mathgames_12_01_03.html
This actually sounds more like an old school random square painting demo, circa 8-bit computing days, especially if you don't mind overlaps. But if you want to be especially geeky, create random squares and solve for the packing problem.
Building off Philippe Beaudoin answer.
There are treemap implementations in other languages that you can also use. In Ruby with RubyTreeMap you could do
require 'Treemap'
require 'Treemap/image_output.rb'
root = Treemap::Node.new 0.upto(100){|i| root.new_child(:size => rand) }
output = Treemap::ImageOutput.new do |o|
o.width = 800
o.height = 600
end
output.to_png(root, "C:/output/test.png")
However it sorts the rectangles, so it doesn't look very random, but it could be a start. See rubytreemap.rubyforge.org/docs/index.html for more info
I would generate everything in a spiral slowly going in. If at any point you reach a point where your solution is proven to be 'unsolvable' (IE, can't put any squares in the remaining middle to satisfy the constraints), go to an earlier draft and change some square until you find a happy solution.
Pseudocode would look something like:
public Board GenerateSquares(direction, board, prevSquare)
{
Rectangle[] rs = generateAllPossibleNextRectangles(direction, prevSquare, board);
for(/*all possible next rectangles in some random order*/)){
if(board.add(rs[x]){
//see if you need to change direction)
Board nBoard = GenerateSquares(direction, board, rs[x]);
if(nBoard != null) return nBoard; //done
else board.remove(rs[x]);
}
}
//all possibilities tried, none worked
return null;
}
}
I suggest:
Start by setting up a polygon with four vertices to be eaten in varying size (up to maxside) rectangle lumps:
public double[] fillBoard(double width, double height, double maxside) {
double[] dest = new int[0];
double[] poly = new int[10];
poly[0] = 0; poly[1] = 0; poly[2] = width; poly[3] = 0;
poly[4] = width; poly[5] = height; poly[6] = 0; poly[7] = height;
poly[8] = 0; poly[9] = 0;
...
return dest; /* x,y pairs */
}
Then choose a random vertex, find polygon lines within (inclusive) 2 X maxside of the line.
Find x values of all vertical lines and y values of all horizontal lines. Create ratings for the "goodness" of choosing each x and y value, and equations to generate ratings for values in between the values. Goodness is measured as reducing number of lines in remaining polygon. Generate three options for each range of values between two x coordinates or two y coordinates, using pseudo-random generator. Rate and choose pairs of x and pair of y values on weighted average basis leaning towards good options. Apply new rectangle to list by cutting its shape from the poly array and adding rectangle coordinates to the dest array.
Question does not state a minimum side parameter. But if one is needed, algorithm should (upon hitting a hitch with a gap being too small) not include too small candidates in selection lists (whic will occasionally make them empty) and deselect a number of the surrounding rectangles in a certain radius of the problem with size and perform new regeneration attempts of that area, and hopefully the problem area, until the criteria are met. Recursion can remove progressively larger areas if a smaller relaying of tiles fails.
EDIT
Do some hit testing to eliminate potential overlaps. And eat some spinach before starting the typing. ;)
Define input area;
Draw vertical lines at several random horizontal locations through the entire height;
Draw horizontal lines at several vertical positions through the entire width;
Shift some "columns" up or down by arbitrary amounts;
Shift some "rows" left or right by arbitrary amounts (it may be required to subdivide some cells to obtain full horizontal seams;
Remove seams as aesthetically required.
This graphical method has similarities to Brian's answer.

Categories