i'm working on a small c# program that uses xinput to read the xbox 360 thumb stick.
i have no problem with reading the coordinates and normalizing the values so i get a float between -1 and +1 for X and Y directions.
the problem i have is that the stick itself is physically limited to a circle and in my case i would like to "stretch out" the coordinates so it becomes more of a square than a circle.
the reason is that each direction is controlling a motor and if i move the stick for example top right i would like both X and Y to become 1.
since the stick is circular this is not possible and this also makes it impossible to make both motors run at full speed.
any advice?
So you want a point on a circle of radius r to be mapped to a point on a square of radius r on the same ray through the origin. Toward that goal you have to compute the radius using the usual formula
r = sqrt(x*x+y*y)
and then from that the scale factor
f = r / max ( abs(x), abs(y) )
and in the end replace x by f*x and y by f*y.
One can vary this computation by noting that the factor is
f = sqrt ( 1 + (x*x)/(y*y) )
if abs(y) > abs(x) and
f = sqrt ( 1 + (y*y)/(x*x) )
in the opposite case. Or by noting that the largest coordinate gets replaced by r and the smaller scaled accordingly, which also does not reduce the logistics by much.
Related
We have a monitoring application that can monitor in intervals like 5 minutes, 15 minutes, 1 hour, etc. That's represented on the x-axis; The y-axis is also scalable and have values like 1.2345 - 1.5567 or can be switched to values like 26000 - 30000, etc.
Once the scale is set on the x and y axis, they don't dynamically change without a whole complete data refresh.
That being said, we only want certain people to be notified depending on the clock angle, of say, the last 5 intervals along the y axis.
The clock angles will never go counter-clockwise past 0/12; likewise, they'll never go past 6 clockwise.
I know the 3 o'clock angle is obvious when the x axis value is exactly the same as it was 5 intervals ago.
But how does one even start coding for everything in between? I can get the differences in x values easily (in the example graphic below, it's 0.3), and the difference in the y-axis in the below graphic is 4.
So with trigonometry that's opposite over adjacent, which means a tan operation I believe? If so, 0.3/5 doesn't seem to yield any values that seem like a clock angle.
Since I can't get any farther than that, I have no idea how it would be coded in C# other than calculating the differences.
Any help would be greatly appreciated!
You should be using atan2 (wiki , docs)
From the wiki:
atan2(y, x) returns the angle θ between the ray to the point (x, y) and the positive x axis, confined to (−π, π]
Note that the result is in radians, so you need to convert it if you want degrees
As stated, one radian is equal to 180/π degrees. Thus, to convert from radians to degrees, multiply by 180/π.
A couple of things here. First I think what you are asking for is the angle φ below, given two data points (x1,y1) and (x2,y2).
The problem here is that the angle is measuring the indicated triangle in pixels and not in x, y units.
So it is incorrect to do var φ = Math.Atan( (y2-y1)/(x2-x1) ); because the x and y axis have different units and angles are always dimensionless.
What additional information is needed, is the size of the graph area in pixels, as well as the range of values. Alternatively, the scaling gx,gy in pixels/unit for both axis.
For example, if the x-axis needs 45 pixels to span 1 grid of 1 hour (60 minutes) then te scaling is double gx = 45/60.0, and if the y-axis needs also 45 pixels to span 1 grid of 0.1 value then double gy = 45/0.1.
Then you can use this to calculate the sides of the triangle in pixels before calculating the angle
var adjacent = gx*(x2-x1); // convert x-axis units to pixels
var opposing = gy*(y2-y1); // convert y-axis units to pixels
var φ = Math.Atan(addjacent/opposing) * (180/Math.PI);
The last part calculates the angle φ and converts it from radians to degrees.
I need to make a C# simulator for a simple pendulum.
I have been searching the web for 3 days and I am stuck.
The problem is I have found many equations that would give the angle position as a function of time, which is perfect for my needs for making a visual simulation but the problem is those functions only works for angles smaller than 10, but I should be able to simulate from any angle.
Example of a equation that only works for small angles:
Source: http://hyperphysics.phy-astr.gsu.edu/hbase/pend.html#c2
And the equations that should work for any angle (Amplitude) are too complicated as it involves differential equations, and derivatives. I don't know how to implement these in C#.
Example of a equation that I think would work but I don't know how to use:
Source: http://www.sbfisica.org.br/rbef/pdf/070707.pdf
(Equation number 32)
the problem of this last equation is the "sn" that is Jacobi elliptic function sn(u;m) u, and I don't know how to use in C#
Can someone help? maybe with another equation that I could use programmatically, or helping me understand how I could use this last one if it would really works.
If you want to simulate the pendulum, you don't need the exact solution. The only you need is a sufficiently good approximation at every step of your simulation, combined with sufficient steps. This is similar to approximating a circle with a sufficiently large number of segments, each of them, tangent to the ideal circle.
Now, consider your pendulum has a deviation of theta degrees (or radians) from the vertical as depicted below:
The mass m will have a weight of m * g, where g is the gravity acceleration. Now, let's approximate the angle alpha where the pendulum will move in the next dt seconds (dt is the duration of one step, so dt is just a fraction of a second).
Since the acceleration on the tangent direction is g * cos(theta) we can approximate the tangent distance the pendulum would travel in dt seconds as if the acceleration were constant during this lapse:
d = v * dt + g * sin(theta) (dt)^2 / 2
where v is the tangential speed of the pendulum at the angular position theta. Now we can calculate alpha as
alpha = arcsin(d / r)
where r is the radius. Thus, the only that remains is to update the value of v so we can repeat the same in the next step. Here is how
v := v + g * sin(theta) * dt
Of course, when the pendulum starts you can initialize v = 0.
I haven't tried this myself, so please, let me know if this "simulated" approach worked for you. Good luck!
I'm making just a basic application that just writes pixels along a curve in C#.
I came across this website with a formula that looks promising. I believe this website is also talking about the same thing here.
What I don't really understand is how to implement it. I tried looking at the JavaScript code on the first link but I can't really tell what data I need to supply. The things involving the PVC, PVI, or PVT are the things I don't understand.
The example situation I'm going to set up is just both of the grades (vertical incline/decline) is just 5 and -5. Let's say point 1 is at 0, 0 and point 2 is 100, 100.
Can someone explain some of the obscure variables in the formula and how would I use the formula to draw the curve?
Generally, to draw a curve in 2D you vary one parameter, and then collect x,y point pairs, and plot the pairs. In your case it will work to just vary the horizontal distance (x), and then collect the corresponding y-values, and then you can plot these.
As for the formula, it is very unclear. Basically it's just a parabola with a bunch of (poorly defined) jargon around it. To graph this, you want to vary x from 0 to L (this isn't obvious, btw, I had to work out the math, i.e., how to vary x so that the slopes would be as they suggest in the figure, anyway, it's 0 to L, and they should have said so).
I don't have C# running now, but hopefully you can translate this Python code:
from matplotlib.pyplot import plot, show
from numpy import arange
G1 = .1 # an initial slope (grade) of 10% (note that one never uses percentages directly in calculations, it's always %/100)
G2 = -.02 # a final slope (grade) of 2%
c = 0 # elevation (value of curve when x=0, that is, y at PVC
L = 10. # the length of the curve in whatever unit you want to use (ft, m, mi, etc), but this basically sets your unit system
N = 1000 # I'm going to calculate and plot 100 points to illustrate this curve
x = arange(0, L, float(L)/N) # an array of N x values from 0 to (almost) L
# calculate the curve
a = (G2-G1)/(2*L)
b = G1
y = a*x*x + b*x + c # this is shorthand for a loop y[0]=a*x[0]*x[0] + b*...
plot(x, y)
show()
print (y[1]-y[0])/(x[1]-x[0]), (y[-1]-y[-2])/(x[-1]-x[-2])
The final line prints the initial and final slopes as a check (in Python neg indexing counts from the back of the array), and this match what I specified for G1 and G2. The plot looks like:
As for your requests: "The example situation I'm going to set up is just both of the grades (vertical incline/decline) is just 5 and -5. Let's say point 1 is at 0, 0 and point 2 is 100, 100.", in a parabola you basically get three free parameters (corresponding to a, b, and c), and here, I think, you over-specified it.
What are PVC, PVT, and PVI? PVC: the starting point, so Y_PVC is the height of the starting point. PVT: the ending point. PVI: if you draw a line from PVC at the initial slope G1 (ie the tangent to the curve on the left), and similarly from PVT, the point where they intersect is called PVI (though why someone would ever care about this point is beyond me).
I would like to know if is there any way to determine if a cone is intersecting with a (finite) line segment. The cone is actually a circle located at P(x,y) with theta degree field of view and radius r:
I'm trying to do it in C# but I don't have any idea how to that, so for now this is what I'm doing:
Check if the line segment is intersecting with the circle;
If the line segment is intersecting with the circle then I check every single point in the line segment using a function I found here.
But I don't think this is the best way to do it. Does anyone have an idea?
For additional info, I need this function to make some kind of simple vision simulator.
Working with Polar Co-ordinates might help. Here, instead of representing a point as (x,y) you represent it as (r, angle), where r is distance from origin and angle is the angle made with a chosen axis (which corresponds to angle 0).
In your case, if you set P(x,y) to be origin and one of the rays of the cone as angle = 0 and find polar co-ordinates of the end points of the line segment, say (r1, ang1) and (r2, ang2) then you need the following four conditions to be true for the line segment to be completely within (including boundary) of the cone.
r1 <= r
r2 <= r
ang1 <= theta
ang2 <= theta
where r is the radius of the cone and theta is the angle of view and you chose the axis so that rotating counter-clockwise gives a corresponding positive angle.
Switching between polar and (x,y) (called rectangular) coordinates is easy, and you can find it on the wiki link I gave above.
In order to determine if any point of the line segment intersects the curve you can use the polar equation of a line give here: Link
We can use the Polar normal form
R = p sec(ang - omega)
We can figure out p and omega given the two end-points of the line segment as follows:
We have
p = r1 * cos(ang1-omega) = r2*cos(ang2-omega)
Using cos(x-y) = cos(x)*cos(y) + sin(x)*sin(y) we get
[r1*cos(ang1) - r2*cos(ang2)] * cos(omega) = [r2*sin(ang2) - r1*sin(ang1)] * sin(omega)
Thus you can calculate tan(omega) = sin(omega)/cos(omega) and use arctan (the inverse function of tan) to get the value of omega. Once you know what omega is, you can solve for p.
Now we need to know if there is some (R, ang) combination on this line such that
R <= r
0 <= ang <= theta
min{ang1, ang2} <= ang <= max{ang1, ang2}
(Note r was radius of cone, and theta was the angle of view, ang1 was angle of P1 and ang2 was angle of P2).
The equation can be rewritten as
Rcos(ang-omega) = p
Now cos(ang-omega) is a very nicely behaved function in terms of monotonicity and you only need to consider it in the interval [min{ang1, ang2}, max{ang1, ang2}].
You should be able to do some manual manipulations first in order to simplify your code.
I will leave the rest to you.
I'd Google around for line/convex polygon intersection algorithms, your field of view is composed of a triangle and a part of a circle which can be approximated to any degree of accuracy by a convex polygon. Your first step might still be useful to rule out lines which go nowhere near the field of view.
If you keep it 2D like above, intersection can be calculated as follows:
Starting point of line segment is S1, ending is S2.
Left edge of code is a vector along the edge C1, right edge is C2, Origin of code is O.
Take the sign of the Z component of the cross product of the vector formed from (O to S1) and C1.
Take the sign of the Z component of the cross product of the vector fromed from (O to S2) and C1. If the signs differ, your starting and ending points are on opposite sides of C1 and therefore they must intersect. If not, do the same comparisons with C2 instead of C1.
If neither side's signs differ, no edge intersection.
In 3D, it's a bit more complicated. I've googled and found cone sphere intersection any number of times. Doing it for lines, would be very similiar, I just need to think about it for a bit :)
A quick google of 'cone line intersection' got all sorts of hits. The basic idea is to form a plane from the cone's origin and the starting and ending point of the line. Once you have that, you can take the angle between that plane and the cone's direction normal. If that angle is less than the angle of the spread on the cone, you have an intersection.
Bit of a weird one this. I'm rendering datasets on a map and need to split out points that have exactly the same long and lat. I had the idea of grouping my dataset by long and lat and where they are the same adjusting slightly so that they are visible as seperate entities on the map - rather than overlapping.
I'm using linq to group them and then enumerating my grouped items and I'd like to spiral the adjusted points around the orginal point (this is a requirement as I may have a few hundred points that are the same geographically) so that they spread out from the original point.
Does anyone know of a simple calculation i can add to my loop to adjust the items in this manner.
Thanks,
The math behind this is pretty simple. A circle can be represented by the sine function in the x-axis and the cosine function in the y-axis. Here's some pseudo-code:
int num = OverlappingPoints.Length;
for(int i = 0; i < num; ++i)
{
int radius = 50;
// using 2*pi because most math functions use radians... change 2*pi to 360 if your math library uses 360 degrees instead of 2*pi radians to represent a circle.
Map.Plot(OverlappingPoints[i].Latitude + radius*sin(2*pi*i/num),
OverlappingPoints[i].Latitude + radius*cos(2*pi*i/num));
}
That pseudo-code, if properly implemented, will draw the points out in a circle around the original point. Change the radius multiplier to the sine and cosine functions if you want to increase the radius of the circle. If you want the points to spiral out instead of making a circle, choose a number of points per circle revolution and replace num with that number in the sin/cos functions. Also, increase the radius after each loop iteration, probably by using a number and multiplying it by the loop index. (i.e. you could change radius to 50*i).
Hope this helps.