Calculate pixel position between two reference points - c#

I'm actually facing a problem I can't solve myself. So I'm asking you guys for help. Hope somebody can help me.
The Problem:
My task is to graphically display measured values. I do have two reference points. I created a sketch witch might explain the problem better:
As you can see in the picture above the two lines (0.20 and 0.05) are my reference points. As you know the canvas' coordinate system is inverse. So the Point (0|0) is in the upper left corner.
What I need is one (or maybe more) formula(s) to calculate the pixel position of e.g. the Point 0.13. I had many approaches to set up a formula myself but with no luck. The points drawn in the image are variable. The height and the reference points are pretty much static.
Thanks for your help in advance!

Given that yMin and yMin are the lower and upper bounds of the visible range of your measurement values (which might be -0.05 and 0.3 in the picture's graph), you would calculate the y value of a position relative to the Canvas origin like this:
var y = 0.13;
var canvasY = canvas.ActualHeight * (1.0 - (y - yMin) / (yMax - yMin));

Related

Calculate points coordinates of an arc

My question is probably more about maths rather than programming, but I hope that is not a problem.
In my app, I am calculating some movement paths, consisting of pixel coordinates (only calculating, not displaying them). I am now trying to smoothen the turn, which are now too sharp, so I would like to use some arc here. I found how I could draw the exact arc I need, using code like this:
e.Graphics.DrawArc(myPen, myPoint.X, myPoints.Y, 50, 50, 180, 90);
Basically what I know are three points (the arc will be between two of these, third is now the turn's corner), the height and width of the arc, the initial and wanted course/heading/angle. I tried this in an app that visualizes the path later, and it works. However, I need to calculate some coordinates on the arc, to add to the array of Points that I save as the path. Anyone knows how? I would need about 5 points for an arc of this size (the number of points will change however)
Thanks
DrawArc draws a part of an ellipse or a circle in your case (regarding the 4th and 5th parameter.) The radius of your circle is 25. The math of a circle is: x^2 + y^2 = r^2.
Therefore, I think you can calculate points on this circle by calculating:
Y = myPoint.Y + 25 +/- Sqrt(625 - (X - myPoint.X - 25)^2).
Let X run from myPoint.X to myPoint.X + 50 and you will find some corresponding Y's.
Because it is a circle, each X has 2 Y values (Therefore, +/- in the formula; you need to calculate the + and the -).

How to sort found chessboard corners?

I have a question about sorting found corners from chessboard.
I'm doing my program in C# using OpenCVSharp.
I need to sort found corners which are points described by X and Y.
This is the part of my code:
...
CvPoint2D32f[] corners;
bool found = Cv.FindChessboardCorners(gray, board_sz, out corners, out corner_count,
ChessboardFlag.NormalizeImage | ChessboardFlag.FilterQuads);
Cv.FindCornerSubPix(gray, corners, corner_count, new CvSize(11,11), new CvSize(-1,-1),
Cv.TermCriteria(CriteriaType.Epsilon | CriteriaType.Iteration, 30, 0.1));
Cv.DrawChessboardCorners(img1, board_sz, corners, found);
...
After that I'm displaying found corners in ImageBox:
see good order in all pictures
and this is the order of corners what I need always, but when I rotate the chessboard a bit - found corners changes like this:
see bad order in all pictures
I need always the same (like in picture 1) order of these points so I decided to use:
var ordered = corners.OrderBy(p => p.Y).ThenBy(p => p.X);
corners = ordered.ToArray();
but it doesn't work like I want:
see bad result 1 in all pictures
see bad result 2 in all pictures
The main point is that my chessboard won't be rotated too much, just for a little angle.
The second point is that the corners must be ordered from the first white square on the top left side of the board.
I know, that the base point (0,0) is on the left top corner of the image and the positive values of Y are increasing in the direction to the bottom of image and positive values of X are increasing in direction to the right side of image.
I'm working on the program to obtain this ordering (these pistures are edited in picture editor):
see example 1 in all pictures
see example 2 in all pictures
Thanks for any help.
Please find below some examples for how OpenCV's findChessboardCorners might return the corner point list and how drawChessboardCorners might display the corners.
For more clarity the order of indices of the subscribing quadrilateral is added as 0,1,2,3.
Basically there are 4 possible rotations of the result leading to the initial red marker being either:
topLeft
topRight
bottomLeft
bottomRight
So when you'd like to resort you can take this knowledge into account and change the order of indices accordingly. The good news is that with this approach you don't have to look at all the x,y values. It's sufficient to compare the first and last value in the list to find out what the rotation is.
To simplify the sorting you might want to "reshape" the list to an array that fits the chesspattern that you supplied to findChessBoardCorners in the fist place e.g. 9x9. In Python numpy there is a function for that i don't know how this would be done in C#.
Work on straightened points. Determine the slope of the image, for instance by taking the difference of the upper right and upper left points. See Rotation (mathematics). Instead of taking the cos you could as well take -diff.Y (the minus because we want to rotate back) and diff.X for the sin. The effect of taking these "wrong" values will result in a scaling.
Now determine the minimum and maximum of x and y of these straightened points. You get two pieces of information from these: 1) an offset from the coordinate origin. 2) The size of the board. Now rescale the transformed point to make them have coordinates between 0.0 and 8.0. Now if the image was perfect all the points’ coordinates should have integer values.
Because they don't, round the coordinates to make them all integers. Sorting these integer coordinates by y and then by x should yield your desired order. This is because the points on the same horizontal line now really have the same y value. This was not the case before. Since they probably all had different y-coordinates, only the second sorting by x had an effect.
In order to sort the original points, put the transformed ones and the original ones into the same class or struct (e.g. a Tuple) and sort them together.

Always getting the correct axis to move on regardless of direction. 2D

I'm struggling to think of the best way of asking this question so forgive me if I don't make much sense but if I move on an an axis, what's the best way of replicating that movement on the opposite axis?
My approach so far has been:
Get the distance from point A to B.
Flip the axis(So X = Y and Y = X).
Move from point A with this new direction.
Look at the graph below,
The problem I'm getting is this, horizontally/vertically it works fine, so for example if the direction was right, when flipped the direction given would be downwards you'd move down (if using Cartesian coordinate system) if you flip the axis round.
However do it on a diagonal and I run into problems, if I move positive x and positive y and then flip the axis, I still move on the positive for both. What I really want is either a negative x, positive y or a positive X, negative y.
Please can someone explain the mathematical explanation, I feel like I know this but my head seems to be muddled with different tried and tested solutions.
Edit:
It sounds like you're essentially trying to reflect points across the line y=x (using microsoft style screen coordinates where (0,0) is the top left corner). If so, (20,20) should not change because it lies on that line. What would you want it to become?
Edit:
I just double checked my work. Given a non-directed line from (x1,y1) to (x2,y2), the perpendicular line of equal length with the same midpoint goes from
((y2-y1+x1+x2)/2,(x1-x2+y1+y2)/2) to ((y1-y2+x1+x2)/2,(x2-x1+y1+y2)/2)

get the pixel count between two points in a bitmap

I am beginner in C#.NET .I am on a project to process approach maps.this map contains the surrounding area of a runway,where the flight can fly in order to land.
this map is a bitmap image.it contains longitudes and latitudes on the borders of the image!
now the aim of the project is to get the geological coordinates(lats/long) of points on the map,(when clicked or hovered on that point by mouse,) based on the given geological coordinates on the border of the map.so if we give the input for a point with its lats/long coordinates the other points on the map can be interpolated.
suppose there be X pixels between any two longitudes and Y pixels between any two latitudes.if we set a reference point ,then depending on the distance(number of pixels from the reference point in x and y direction individually) of the pixel that is being hovered or clicked by mouse pointer we can get the lats/longitudes of that point in a small window(may be like tool tip or pop up).
the math surrounding the interpolation can be:
new lat= ref lat + [ref lat(only minutes)/Y] *(vertical distance between reference point and new point in pixels)
new long= ref long - [ref long(only minutes)/X] *(horizontal distance between reference point and new point in pixels).
there is a point called mid point on the centre of the run way(at the centre of the graph).i also need to find the angle made by line joining midpoint and new point(where the mouse hovers or clicks) with the verticle of the map.
so any one please give me ideas how to start the project and what are things (tool bar controls,methods) i require to build the gui containing picture window and pop up window(containing information about that point or pixel) where ever i click the mouse .thanks in advance.
The question asked in the headline is answered as follows:
double distance = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
That's the distance between two points on a plane, and hence on a bitmap.
The question asked in the body isn't answered easily at all. If you have a given map, the function defining the distance between two coordinates may not be linear. Here's an article on Map projection that shows some of the different map types. To be able to calculate what you need, you first need to know what kind of map you're actually working on, and hence adjust your formulas accordingly.
If your map is only of small size, this may not make much of a difference. You were talking about a runway at one point, if this is just for one airport, then projection isn't necessarily an issue. If you're working out distances between two runways of different airports, that will be a different matter.
Your question is quite specific to your needs and has a few elements that could be questions in their own right. You might want to break it down into several questions and or research each item independently. e.g.
You'll want to look into WPF or Windows Forms.
You'll need to learn how to calculate the angle between two points.

Calculating the bounding points for the area of a "Pie Segment" and "sub areas"

Background:
I was recently playing around with GDI+ to draw a "Disc" displaying a sweeping color change through 360 degrees. (I dug up some HSL to RGB code to loop through HSL(1,1,1) -> HSL(360,1,1))
Regarding the disc, I first drew a full solid circle using the above, and then a second circle in Grey over the center to give the following
So this is all fine... but I realised that GDI+ is insulating us from a lot of the tricky match that's going on here by way of the FillPie method. Also, FillPie requires you to supply a bounding rectangle for the pie as opposed to a Radius Length. It also does a full segment fill and doesnt allow you to specify a part of that segment only.
Question:
Can anyone point me in the direction of some Math functions or give any explanation on what forumla I would need to calculate the area & plot points of the following "Green Filled Area" given:
Point `c` - an x,y co-ordinate
Angle `A` - an angle from horizontal
Angle `B - an angle from horizontal where `B` - `A` == the sweep angle
Length `r` - a distance from `c`
Length `r2` - a distance from `c` where `r2` - `r` == the `height` of the segment to be filled.
Links to Math sources are fine but I've had a quick google & look at Wolfram Math and could find what I was looking for. Also, if there was some way to generate a sequence of bounding (x,y) co-or's that could be passed as a Point[] to Graphics.FillPolygon, that'd be cool too.
The area is the difference of the outer and inner disc parts. The area of a disc part is proportional to the angle sweep:
area = (b-a)*((r+r2)^2-r^2)/2
a and b must be expressed in radians.
For b-a = 2*Pi, area = Pi*(r+r2)^2 - Pi*r^2 is the difference of the areas of the outer and inner discs.
You can generate points on the inner / outer circle using
x = cx + r * cos(t) / x = cx + (r+r2) * cos(t)
y = cy + r * sin(t) / y = cy + (r+r2) * sin(t)
Where t varies from a to b.
Hope this helps. The second part provides a method for calculating the area of a sector of a circle
http://www.wikihow.com/Calculate-the-Area-of-a-Circle
The area of a segment of a circle is simply the angle of the arc (in radians) times the radius. So the area of the green circle is obviously:
(B-A) * r2
You need to draw lines (this pseudo code):
for aa from A to B
set color to required color // you could use aa in an equation with HSL to get something like your sample
x1=r*cos(aa)+x
y1=r*sin(aa)+y
x2=r1*cos(aa)+x
y2=r1*sin(aa)+y
draw line between (x1,y1) and (x2,y2)
for a small-enough increment in the angles, and small-enough radii, this should be OK.
The points you're looking for are (x1,y1) and (x2,y2) for each angle aa

Categories

Resources