Calculate points coordinates of an arc - c#

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 -).

Related

How to rotate a Vector3 of dimensions by a Vector3 of angles?

I have a Vector 3 of how many blocks in a grid a piece is along each axis. For example if one of these vectors was ( 1, 2, 1 ) it would be 1 block long on the x-axis, 2 blocks long on the y-axis, and one block long on the z-axis. I also have a Vector 3 of angles that denote rotations along each axis. For example if one of these vectors was ( 90, 180, 0 ) the piece would be rotated by 90 degrees around the x-axis, 180 degrees around the y-axis, and 0 degrees around the z-axis. What I can't figure out is how to rotate the dimensions of a piece by its vector of rotation angles so i know what points in space its occupying.
public class Block
{
private Vector3 localOrientation;
private Vector3 dimensions;
public Vector3 GetRotatedDimensions()
{
//your implementation here
}
}
If I understand correctly, there is something fundamentally wrong with your question. There can be no "rotated dimensions". Let's use a rectangle to demonstrate this. (I didn't undestand correctly)
Suppose there's this initial rectangle:
and you rotate it. This is what you get:
Using a single Vector2, you can't differentiate a "rotated x*y rectangle" from a "initial (x')*(y') rectangle". To sufficiently describe the position of a rectangle, you need to keep the size AND the rotation in your block-describing variable.
Is x' and y' what you wanted to know? I doubt it. Oh, you do? Great!
In 3 dimensions, I would define what you're looking for as
The minimum dimensions of a rectangular box that
1. has its faces parallel to the XY, XZ and YZ planes and
2. contains another rectangular box of known dimensions and orientation.
There are possibly more elegant solutions, but I'd brute force it like this:
Make 8 Vector3 objects (one for each vertex of your block),
Rotate all of them around the x-axis.
Rotate them (the new ones you got from "2") around the y-axis.
Rotate them (the new ones you got from "3") around the z-axis.
Find the min and max values of the x, y and z coordinates among all your points.
Your new dimensions would be (x_max-x_min), (y_max-y_min), (z_max-z_min).
I'm not 100% sure about this though, so make sure you verify the results!

Calculate pixel position between two reference points

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));

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.

C# Winform XNA Collision

I'm interested in knowing how I would go about detecting a primitive circle touching another primitive circle?
So, if I had a circle with 5,10 and another one with 5,13 with each of them having a radius of 2. well the distance formula is the Pythagorean theorem. which is sqrt((x2-x1)^2 + (y2-y1)^2) = distance and if this distance is less than or equal to the sum of their radius. the sum of the radius is 4? since each circle has a radi of 2? Is this kinda waht you mean?
You can check if the distance between their center is less or equal to the sum of their radius

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