Specifying boundary points on GUI using c# - c#

I'm working on simulator, it has number of points. what i need is knowing how to specify the points which is the nearest one to any border of the four borders. I.e connect closed shape and ignore the points in the middle
Any suggestions?

If the boundaries form a rectangle shape which is axis aligned (like a monitor screen, for example), then you can take the four points with maximum and minimum x and y values.
You can enumerate all of the points and find the points nearest the boundaries.
Pseudocode:
var minimumX = int.MaxValue
var maximumX = int.MinValue
var minimumY = int.Maxvalue
var maximumY = int.MinValue
foreach(var point in points)
{
if (point.x < minimumX) minimumX = point.x;
if (point.x > maximumX) maximumX = point.x;
if (point.y < minimumY) minimumY = point.y;
if (point.y > maximumY) maximumY = point.y;
}
You can now use minimum and maximum x and y to create a bounding rectangle that contains all points.
A slightly more performant method would track the minimum and maximum x and y as each point is added to the field. This way, there would be no need to enumerate all points.

Related

How to get a parabola shape according to a moved point and nearest points

Being not very good at math, I have a problem with my project.
The objective is boundary correction on 3D files.
In my application, the user moves a 3D point on X-axis in order to correct or modify the boundary of the object.
I want to move the nearest boundary points in the same direction but decreasingly. I mean no point should move more than the main point. The nearest points move most and, the farthest points should move less.
On the image, the red dots represent the initial status of points. And the user pulls the P0 in the x-direction. And the other points follow it. The last status of the points is represented by violet dots.
Here is what I tried.
//On point moved event
//Get nearest boundary Points (Uses Geometry3D to get boundary points).
(var clothDMesh, _) = Utilities3D.BuildDMesh(baseMesh);
CreateClothModel(clothDMesh);
var boundryVertices = nodes.Where(ro => ro.Value.isBorder).Select(ro => ro.Value.vertex).ToList();
var refPoint = CustomPoint.FromPoint3D(movedPoint);
//Gets the delta X.
var deltaX = p.X - initialX;
//Gets nearest country points, so 15 points above and 15 points below to move only a given number of points (I know maybe this should be calculated according to delta).
var nearestPoints = refPoint.GetNearesPoints(boundryVertices, 30);
foreach (var item in nearestPoints)
{
//This is only one of what I tried as a function. None of them worked correctly.
item.X += deltaX - (deltaX * 1/ Math.Pow(item.Distance, 2));
}
Any help will be appreciated.
Thanks in advance.
Here's the math part:
I call "a" your "deltaX".
We also need a second parameter: "b", the maximum height of the red dots. I assume it is symetrical and "-b" would be the minimum height of the red dots.
So, if you look for the value X, horizontal move, in fonction of the coordinate Y of the dot:
X = a - a * Y * Y / (b * b);
You can verify that for Y = 0, you obtain X = a and for Y = b (or -b) you get X = 0.
You have your parabola (X is function of Y^2).

C#: How to generate random locations nearby map's center in GMap.NET?

Is there any way to generate random locations nearby map's center within a specific radius in my Form?
I can obtain the center of the map with the following line:
var center = gMapControl2.Position;
I did some research and came across to this post but it's in Java.
Generate a random number for R between RMax and RMin. Generate a different number for theta between 0 and 360. Now use basic trigonometry to convert to (x,y).
This approach seems most intuitive to me because the problem as stated is fundamentally radially symmetric. It also gives you (R, Theta) for any other computations you may want to do.
Assume that center is (x0,y0) and we are looking for a random location (x,y) with maximum distance maxDist from the center.
We know that
(x-x0)*(x-x0) + (y-y0)+(y-y0) <= maxDist *maxDist
So first we find a random value for x in the appropriate distance then find a random value for y:
int x = random.Next(-1* maxDist, maxDist);
int maxY =(int) Math.Floor(Math.Sqrt(maxDist * maxDist - x * x));
int y = random.Next(-1*maxY, maxY);
y += y0;
x += x0;

How do I calculate opposite of a vector, add some slack

How can i calulate a valid range (RED) for my object's (BLACK) traveling direction (GREEN). The green is a Vector2 where x and y range is -1 to 1.
What I'm trying to do here is to create rocket fuel burn effekt. So what i got is
rocket speed (float)
rocket direction (Vector2 x = [-1, 1], y = [-1, 1])
I may think that rocket speed does not matter as fuel burn effect (particle) is created on position with its own speed.
A cheap and cheerful trick with 2D vectors is to transpose the x and y, then flip the sign on one of them to get the perpendicular vector (pseudo code):
Vector2 perpendicular ( -original.y, original.x ) // Or original.y, -original.x
Then you could do something like:
direction + perpendicular * rand(-0.3 , 0.3)
Update: having realised the question asks for the opposite vector (too busy looking at the picture!) I figure I had better answer that too. Multiply 'direction' by -1 to get the opposite vector. So this:
perpendicular * rand(-0.3 , 0.3) - direction
should give you a random direction vector somewhere in your range (not normalised, but close enough for these purposes). Then you can multiply that result by a random number depending on how long you want the tail.
If to expend upon OlduwanSteve's answer, you can make is such that it's somewhat physically accurate.
You want to create several vectors that will represent the expulsion (the red lines).
First define the number of vectors you want to represent the expulsion with - lets mark it n.
You want to get a set of n numbers which sum up to Vx. These numbers will be the x components of the expulsion vectors. You can do this like so (semi-pseudo code):
SumX = Vx;
for (i = 0; i < n; i++)
{
Ax[i] = -rand(0..SumX); // Ax is the array of all expulsion vectors x components
SumX -= Ax[i];
}
Now you'll want to calculate Ay (the y components of the expulsion vectors). This is quite similar to calculating the, except that SumY = 0.
Here instead of splitting up SumY among n elements, you need to decide a maximal y component. Best way I can think of to select this is to define a maximal allowed angle for the expulsion vectors and define the maximal Vy using: maxVy = minVx*tan(maxAlpha).
Now you can get Ay using this (semi-pseudo code):
SumY = maxVy*2; // The actual range is (-maxVy, maxVy), but using (0, 2*maxVy) is simpler IMO
for (i = 0; i < n; i++)
{
Ay[i] = rand(0..SumY);
SumY -= Ay[i];
}
for (i = 0; i < n; i++)
{
Ay[i] -= maxVy; // Translate the range back to (-maxVy, maxVy) from (0, 2*maxVy)
}
Now you have arrays of both the x and y components of the expulsion vectors. Iterate over both arrays and pair up elements to create the vectors (you don't have to iterate both arrays in the same order).
Notes:
• I align the axes in my calculations such that X is parallel to the objects speed vector (the green line).
• The calculation for maxVy does NOT guarantee that a vector of angle maxAlpha will be produced, it only guarantees that no vector of larger angle will be.
• The lines Ay[i] = rand(0..SumY) and Ax[i] = -rand(0..SumX) may lead to vectors with components of size 0. This may lead to annoying scenarios, I'd recommend to handle away such cases (for instance "while rand returns zero, call it again").

find the center point of coordinate 2d array c#

Is there a formula to average all the x, y coordinates and find the location in the dead center of them.
I have 100x100 squares and inside them are large clumps of 1x1 red and black points, I want to determine out of the red points which one is in the middle.
I looked into line of best fit formulas but I am not sure if this is what I need.
Sometimes all the red will be on one side, or the other side. I want to essentially draw a line then find the center point of that line, or just find the center point of the red squares only. based on the 100x100 grid.
List<Point> dots = new List<Point>();
int totalX = 0, totalY = 0;
foreach (Point p in dots)
{
totalX += p.X;
totalY += p.Y;
}
int centerX = totalX / dots.Count;
int centerY = totalY / dots.Count;
Simply average separately the x coordinates and the y coordinates, the result will be the coordinates of the "center".
What if there are two or more subsets of red points ? Do you want the black point inside them?
Otherwis, if I understood your question, just give a weight of 1 to red points and 0 to blacks. Then do the weighted mean on X and Y coordinate

Graphic transformations

I'm working with data (stuff like Sin/Cosin waves, etc) that repeat with frequency M.
I've written a simple display control where it takes the data and paints connected lines to represent the data in a pretty picture.
My question is, the data is given where if painted onto a bitmap, quadrant 1 data is in quadrant 3 and quadrant 2 data is in quadrant 4 (and vice versa).
The bitmap is of width M and hight array.Max - array.Min.
Is there a simple transform for changing the data so it will display in the appropriate quadrants?
A good way of thinking about it is that (0,0) in world coordinates is divided between
(0,0), (width, 0), (0,height), (width, height)
which would (width/2, height/2) in image coordinates.
From there, the transform would be:
Data(x,y) => x = ABS(x - (width/2)), y = ABS(y - (Height/2))
Graphics.ScaleTransform is not a good idea because it will affect not only layout but also drawing itself (thickness of strokes, texts and so on).
I suggest you to prepare points list and then perform a transformation to them using the Matrix class. This is a small example I made for you, hope it will be helpful.
private PointF[] sourcePoints = GenerateFunctionPoints();
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.Clear(Color.Black);
// Wee need to perform transformation on a copy of a points array.
PointF[] points = (PointF[])sourcePoints.Clone();
// The way to calculate width and height of our drawing.
// Of course this operation may be performed outside this method for better performance.
float drawingWidth = points.Max(p => p.X) - points.Min(p => p.X);
float drawingHeight = points.Max(p => p.Y) - points.Min(p => p.Y);
// Calculate the scale aspect we need to apply to points.
float scaleAspect = Math.Min(ClientSize.Width / drawingWidth, ClientSize.Height / drawingHeight);
// This matrix transofrmation allow us to scale and translate points so the (0,0) point will be
// in the center of the screen. X and Y axis will be scaled to fit the drawing on the screen.
// Also the Y axis will be inverted.
Matrix matrix = new Matrix();
matrix.Scale(scaleAspect, -scaleAspect);
matrix.Translate(drawingWidth / 2, -drawingHeight / 2);
// Perform a transformation and draw curve using out points.
matrix.TransformPoints(points);
e.Graphics.DrawCurve(Pens.Green, points);
}
private static PointF[] GenerateFunctionPoints()
{
List<PointF> result = new List<PointF>();
for (double x = -Math.PI; x < Math.PI; x = x + 0.1)
{
double y = Math.Sin(x);
result.Add(new PointF((float)x, (float)y));
}
return result.ToArray();
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
Invalidate();
}
Try to invert the y-axis using
g.ScaleTransform(1, -1);
Also remember that for drawing in a scaled context, if you have to, Pen for example takes width as Single in some of its constructors, meaning inversely proportional fractional values can be used to make an invariant compensation for the effect of ScaleTransform.
UPDATE: forget that, Pen has its own local ScaleTransform, so both x an y can be compensated for.

Categories