for (double x=0;x<=7D;x+=.01D)
{
b = 1.771289; c = 2.335719; d = 0.5855771; g = 4.4990302; h = 4.3369349; k = 0.67356705;
y = b * Math.Exp(-(0.5 * (Math.Pow(((x - c) / d), 2)))) +
g * Math.Exp(-(0.5 * (Math.Pow(((x - h) / k), 2))));
qResults.Rows.Add(x, y);
}
the graph is good but it draws a hole in the peek.i am using mschart:
http://imageshack.us/photo/my-images/824/graph1v.png/
i would like to know whether the hole is a problem with my syntax?
It seems that your y-axis range is bounded by the maximum value, but the very point falls exactly outside the plotting range.
One solution is to add a small amount to the axis range such that all points fall clearly inside the plotting space.
Try making the max y range for the graph a little over the max value. If the max value is 4.5 then make the graph y-axis limit equal to 5.0.
There's nothing wrong with your syntax, that really should be a smooth curve. I stuck it into matlab just to be certain.
Related
OxyPlot is a cross-platform plotting library for .NET, very convenient for making plots,
Now there's a situation here, I have to draw a 95% confidence ellipse to an XY scatter plot.
Oxyplot provides with following annotation:-
Given here Ellipse Annotation(OxyPlot.Annotations) gives only following properties to add ellipse-
We don't have any rotation property or method here, IRender provides several draw methods to override but none of the methods have double angled rotation argument or so. Neither the documentation has provides any direct solution to it:-
Then how to draw this:-
*I was facing this issue for one of my assignment, and came up with a solution after going through the following forums discussion to get hints on how to generate such an ellipse.
https://github.com/oxyplot/oxyplot/issues/268
https://oxyplot.userecho.com/en/communities/1/topics/598-ellipse-annotation-rotation
Please add more solutions if anyone else has :-
Based on the link shared (in Quest.) best and easiest solution here was to draw an ellipse using PolygonAnnotation, which takes List of co-ordinate points,
Let's say if you give four co-ordinate points A,B,C,D--- polygonAnnotation will give me a closed 4-gon~quadrilateral sort of structure based on kind of points taken.
Now if you increase the number of points from 4 to 6--- it will give you hexagon, and so on.
Now at pixel level you can give infinite-number/discrete-number of points eclipsing over 360 degree.
So here we need an algorithm/equation of point on an 2D ellipse- given following inputs (based on this case):-
Center of ellipse (h,k)
rotation angle of the ellipse axis
major axis (a)
minor axis (b)
theta angle from the x-axis
private void GeneratePolygonAsEllipse(PolygonAnnotation polygonAnnotation)
{
double step = 2 * Math.PI / 200;
var h = xCenter;
var k = yCenter;
var rotation = AngleOfRotation;
var a = MajorAxisLength;
var b = MinorAxisLength;
for (double theta = 0; theta < 2 * Math.PI; theta += step)
{
var x = a * Math.Cos(rotation) * Math.Cos(theta) + b * Math.Sin(rotation) * Math.Sin(theta) + h;
var y = b * Math.Cos(rotation) * Math.Sin(theta) + a * Math.Sin(rotation) * Math.Cos(theta) + k;
polygonAnnotation.Points.Add(new DataPoint(x, y));
}
}
I hope above stipulated sample method equation can be useful to other folks like me looking for solution. I couldn't find direct solution anywhere else so I have added my solution here, that can be used as reference.
Result:-
if anyone can come-up with other solutions like how to use IRender or anything else, would be great to look at them.
I am trying to draw an arc between two points that represents a projectile's path. The angle that the projectile leaves point A at is known, and the X/Y coordinates of both points are known.
I'm trying to figure out the math behind this, and how to draw it up in c#.
Here is my failed attempt, based on some path examples I found
var g = new StreamGeometry();
var xDistance = Math.Abs(pointA.X - pointB.X);
var yDistance = Math.Abs(pointA.Y - pointB.Y);
var angle = 60;
var radiusX = xDistance / angle;
var radiusY = yDistance / angle;
using (var gc = g.Open())
{
gc.BeginFigure(
startPoint: pointA,
isFilled: false,
isClosed: false);
gc.ArcTo(
point: pointB,
size: new Size(radiusX, radiusY),
rotationAngle: 0d,
isLargeArc: false,
sweepDirection: SweepDirection.Clockwise,
isStroked: true,
isSmoothJoin: false);
}
Any help would be greatly appreciated!
Edit #2 (added clarity): For this problem assume that physics play no role (no gravity, velocity, or any outside forces). The projectile is guaranteed to land at point B and move along a parabolic path. The vertex will be halfway between point A and point B on the horizontal axis. The angle that it launches at is the angle up from the ground (horizontal).
So Point A (Ax, Ay) is known.
Point B (Bx, By) is known.
The angle of departure is known.
The X half of the vertex is known (Vx = Abs(Ax - Bx)).
Does this really boil down to needing to figure out the Y coordinate of the vertex?
Following on from the comments, we need a quadratic Bezier curve. This is defined by 3 points, the start, end, and a control point:
It is defined by the following equation:
We therefore need to find P1 using the given conditions (note that the gravity strength is determined implicitly). For a 2D coordinate we need two constraints / boundary conditions. They are given by:
The tangent vector at P0:
We need to match the angle to the horizontal:
The apex of the curve must be directly below the control point P1:
Therefore the vertical coordinate is given by:
[Please let me know if you would like some example code for the above]
Now for how to add a quadratic Bezier; thankfully, once you have done the above, it is not too difficult
The following method creates the parabolic geometry for the simple symmetric case. The angle is measured in degrees counterclockwise from the horizontal.
public Geometry CreateParabola(double x1, double x2, double y, double angle)
{
var startPoint = new Point(x1, y);
var endPoint = new Point(x2, y);
var controlPoint = new Point(
0.5 * (x1 + x2),
y - 0.5 * (x2 - x1) * Math.Tan(angle * Math.PI / 180));
var geometry = new StreamGeometry();
using (var context = geometry.Open())
{
context.BeginFigure(startPoint, false, false);
context.QuadraticBezierTo(controlPoint, endPoint, true, false);
}
return geometry;
}
A body movement subject only to the force of gravity (air resistance is ignored) can be evaluated with the following equations:
DistanceX(t) = dx0 + Vx0·t
DistanceY(t) = dy0 + Vy0·t - g/2·t^2
Where
g : gravity acceleration (9.8 m/s^2)
dx0 : initial position in the X axis
dy0 : initial position in the Y axis
Vy0 : initial X velocity component (muzzle speed)
Vy0 : initial Y velocity component (muzzle speed)
Well that doesn't seem very helpful, but lets investigate further. Your cannon has a muzzle speed V we can consider constant, so Vx0 and Vy0 can be written as:
Vx0 = V·cos(X)
Vy0 = V·sin(X)
Where X is the angle at which you are shooting. Ok, that seems interesting, we finally have an input that is useful to whoever is shooting the cannon: X. Lets go back to our equations and rewrite them:
DistanceX(t) = dx0 + V·cos(X)·t
DistanceY(t) = dy0 + V·sin(X)·t - g/2·t^2
And now, lets think through what we are trying to do. We want to figure out a way to hit a specific point P. Lets give it coordinates: (A, B). And in order to do that, the projectile has to reach that point in both projections at the same time. We'll call that time T. Ok, lets rewrite our equations again:
A = dx0 + V·cos(X)·T
B = dy0 + V·sin(X)·T - g/2·T^2
Lets get ourselves rid of some unnecessary constants here; if our cannon is located at (0, 0) our equations are now:
A = V·cos(X)·T [1]
B = V·sin(X)·T - g/2·T^2 [2]
From [1] we know that: T = A/(V·cos(X)), so we use that in [2]:
B = V·sin(X)·A/(V·cos(X)) - g/2·A^2/(V^2·cos^2(X))
Or
B = A·tan(X) - g/2·A^2/(V^2*cos^2(X))
And now some trigonometry will tell you that 1/cos^2 = 1 + tan^2 so:
B = A·tan(X) - g/2·A^2/V^2·(1+tan^2(X)) [3]
And now you have quadratic equation in tan(X) you can solve.
DISCLAIMER: typing math is kind of hard, I might have an error in there somewhere, but you should get the idea.
UPDATE The previous approach would allow you to solve the angle X that hits a target P given a muzzle speed V. Based on your comments, the angle X is given, so what you need to figure out is the muzzle speed that will make the projectile hit the target with the specified cannon angle. If it makes you more comfortable, don't think of V as muzzle speed, think of it as a form factor of the parabola you are trying to find.
Solve Vin [3]:
B = A·tan(X) - g/2·A^2/V^2·(1+tan^2(X))
This is a trivial quadratic equation, simply isolate V and take the square root. Obviously the negative root has no physical meaning but it will also do, you can take any of the two solutions. If there is no real number solution for V, it would mean that there is simply no possible shot (or parabola) that reaches P(angle X is too big; imagine you shoot straight up, you'll hit yourself, nothing else).
Now simply eliminate t in the parametrized equations:
x = V·cos(X)·t [4]
y = V·sin(X)·t - g/2·t^2 [5]
From [4] you have t = x/(V·cos(X)). Substitute in [5]:
y = tan(X)·x - g·x^2 /(2·V^2*cos^2(X))
And there is your parabola equation. Draw it and see your shot hit the mark.
I've given it a physical interpretation because I find it easier to follow, but you could change all the names I've written here to purely mathematical terms, it doesn't really matter, at the end of the day its all maths and the parabola is the same, any which way you want to think about it.
I am trying to code for a game I am working on a specific curve with a specific rotation. I am not a great mathematician... At all... Tried searching for solutions for a few hours, but I'm affraid I do not find any solution.
So, a small picture to illustrate first:
This is an eighth of a circle, radius of 9, beggining is (0,0)
The end is now at about 6.364, -2.636. But I need this same curve, with a 45° direction at the end, but ending at aexactly 6.0,-3.0.
Could any of you show me how to do this? I need to be able to calculate precisly any point on this curve & its exact length. I would suppose using some kind of eliptical math could be a solution? I admit my math class are reaaaly far now and have now good clue for now...
Thank for any possible help
I think I found a quadratic curve which sastisfies your requirement:
f(x) = -1/12 x^2 + 9
Copy the following into https://www.desmos.com/calculator to see it:
-\frac{1}{12}x^2+9
f'(x) would be -1/6x, so when x=6, the derivative would be -1, which corresponds to a -45° inclination. There are probably infinite curves that satisfy your requirement but if my calculus isn't too rusty this is one of them.
I tried to fit an ellipse with foci starting at y=6 here and starting at y=9 here to your points but the slope doesn't look like 45°.
Also starting at any height k, here doesn't seem to work.
I don't think you've fully understood the question I asked in the comments about the "inclination" angle. So I will give a general case solution, where you have an explicit tangent vector for the end of the curve. (You can calculate this using the inclination angle; if we clarify what you mean by it then I will be happy to edit with a formula to calculate the tangent vector if necessary)
Let's draw a diagram of how the setup can look:
(Not 100% accurate)
A and B are your fixed points. T is the unit tangent vector. r and C are the radius and center of the arc we need to calculate.
The angle θ is given by the angle between BA and T minus π/2 radians (90 degrees). We can calculate it using the dot product:
The (signed) distance from the center of AB to C is given by:
Note that this is negative for the case on the right, and positive for the left. The radius is given by:
(You can simplify by substituting and using a cosine addition rule, but I prefer to keep things in terms of variables in the diagram). To obtain the point C, we need the perpendicular vector to AB (call it n):
Now that we have the radius and center of the circular arc, we still need to determine which direction we are moving in, i.e. whether we are moving clockwise or anti-clockwise when going from A to B. This is a simple test, using the cross-product:
If this is negative, then T is as in the diagram, and we need to move clockwise, and vice versa. The length of the arc l, and the angular displacement γ when we move by a distance x along the arc:
Nearly there! Just one more step - we need to work out how to rotate the point A by angle γ around point C, to get the point we want (call it D):
(Adapted from this Wikipedia page)
Now for some code, in case the above was confusing (it probably was!):
public Vector2 getPointOnArc(Vector2 A, Vector2 B, Vector2 T, double x)
{
// calculate preliminaries
Vector2 BA = B - A;
double d = BA.Length();
double theta = Math.Acos(Vector2.DotProduct(BA, T) / d) - Math.PI * 0.5;
// calculate radius
double r = d / (2.0 * Math.Cos(theta));
// calculate center
Vector2 n = new Vector2(BA.y, -BA.x);
Vector2 C = 0.5 * (A + B + n * Math.Tan(theta));
// calculate displacement angle from point A
double l = (Math.PI - 2.0 * theta) * r;
double gamma = (2.0 * Math.PI * x) / l;
// sign change as discussed
double cross = T.x * BA.y - T.y * BA.x;
if (cross < 0.0) gamma = -gamma;
// finally return the point we want
Vector2 disp = A - C;
double c_g = Math.Cos(gamma), s_g = Math.Sin(gamma);
return new Vector2(disp.X * c_g + disp.Y * s_g + C.X,
disp.Y * c_g - disp.X * s_g + C.Y);
}
I am updating one of our older apps from vb6 to c# and in the process have to recreate a custom control that the original programmer designed. The control simply took the dimensions of an object, rectangular or conical, and placed an outline sketch of the object in 3D (2.5D technically I think). Of course, the code for the control or the algorithim is nowhere to be had.
Knowing nothing about this before hand I have gotten pretty much everything replicated except the perspective. I am using this code that I found on another answer here.
}
double w = 400;
double h = 250;
double t = 0.6; // tilt angle
double X = w / 2 - x;
double Y = h / 2 - y;
double a = h / (h + Y * Math.Sin(t));
double u = a * X + w / 2;
double v = a * Y * Math.Cos(t) + h / 2;
}
The last piece I need help with though is turning the perspective about 30 degrees left-to-right so I'm not looking at straight on.
Thanks for any help.
As the commenter says: You should use matrices to make your live easy.
Rotation could be easily done by multiplying the 2 matrices, a rotation matrix and a perspective matrix this way:
// We don't have a view matrix here
Matrix4x4 modelProjection = Matrix4x4.Perspective(400, 250, Math.PI / 4) * Matrix4x4.RotationX(degree);
// Get a specifics point position, use x and y to determine the screen position and z for the z-order
Vector3 screenPosition = modelProjection * myPosition; // myPosition is a Vector3
For running the code you have to do some things:
Implement a C# matrix, or get it from anywhere else. Here is a excellent source for implementing matrices.
Lets Say I have a 3d Cartesian grid. Lets also assume that there are one or more log spirals emanating from the origin on the horizontal plane.
If I then have a point in the grid I want to test if that point is in one of the spirals. I acutally want to test if it within a certain range of the spirals but determining if it is on the point is a good start.
So I guess the question has a couple parts.
How to generate the arms from parameters (direction, tightness)
How to tell if a point in the grid is in one of the spiral arms
Any ideas? I have been googling all day and don't feel I am any closer to a solution than when I started.
Here is a bit more information that might help:
I don't actually need to render the spirals. I want to set the pitch and rotation and then pass a point to a method that can tell me if the point I passed is within the spiral (within a given range of any point on the spiral). Based on the value returned (true or false) my program will make a decision on whether or not something exists at the point in space.
How to parametrically define the log spirals (pitch and rotation and ??)
Test if a point (x, y, z) is withing a given range of any point on the spiral.
Note: Both of the above would be just on the horizontal plane
These are two functions defining an anti-clockwise spiral:
PolarPlot[{
Exp[(t + 10)/100],
Exp[t/100]},
{t, 0, 100 Pi}]
Output:
These are two functions defining a clockwise spiral:
PolarPlot[{
- Exp[(t + 10)/100],
- Exp[t/100]},
{t, 0, 100 Pi}]
Output:
Cartesian coordinates
The conversion Cartesian <-> Polar is
(1) Ro = Sqrt[x^2+y^2]
t = ArcTan[y/x]
(2) x = Ro Cos[t]
y = Ro Sin[t]
So, If you have a point in Cartesian Coords (x,y) you transform it to your equivalent polar coordinates using (1). Then you use the forula for the spiral function (any of the four mentinoned above the plots, or similar ones) putting in there the value for t, and obtaining Ro. The last step is to compare this Ro with the one we got from the coordinates converion. If they are equal, the point is on the spiral.
Edit Answering your comment
For a Log spiral is almost the same, but with multiple spirals you need to take care of the logs not going to negative values. That's why I used exponentials ...
Example:
PolarPlot[{
Log[t],
If[t > 3, Log[ t - 2], 0],
If[t > 5, Log[ t - 4], 0]
}, {t, 1, 10}]
Output:
Not sure this is what you want, but you can reverse the log function (or "any" other for that matter).
Say you have ln A = B, to get A from B you do e^B = A.
So you get your point and pass it as B, you'll get A. Then you just need to check if that A (with a certain +- range) is in the values you first passed on to ln to generate the spiral.
I think this might work...
Unfortunately, you will need to know some mathematics notation anyway - this is a good read about the logarithmic sprial.
http://en.wikipedia.org/wiki/Logarithmic_spiral
we will only need the top 4 equations.
For your question 1
- to control the tightness, you tune the parameter 'a' as in the wiki page.
- to control the direction, you offset theta by a certain amount.
For your question 2
In floating point arithmetic, you will never get absolute precision, which mean there will be no point falling exactly on the sprial. On the screen, however, you will know which pixel get rendered, and you can test whether you are hitting a point that is rendered.
To render a curve, you usually render it as a sequence of line segments, short enough so that overall it looks like a curve. If you want to know whether a point lies within certain distance from the spiral, you can render the curve (on a off-screen buffer if you wish) by having thicker lines.
here a C++ code drawing any spiral passing where the mouse here
(sorry for my English)
int cx = pWin->vue.right / 2;
int cy = pWin->vue.bottom / 2;
double theta_mouse = atan2((double)(pWin->y_mouse - cy),(double)(pWin->x_mouse - cx));
double square_d_mouse = (double)(pWin->y_mouse - cy)*(double)(pWin->y_mouse - cy)+
(double)(pWin->x_mouse - cx)*(double)(pWin->x_mouse - cx);
double d_mouse = sqrt(square_d_mouse);
double theta_t = log( d_mouse / 3.0 ) / log( 1.19 );
int x = cx + (3 * cos(theta_mouse));
int y = cy + (3 * sin(theta_mouse));
MoveToEx(hdc,x,y,NULL);
for(double theta=0.0;theta < PI2*5.0;theta+=0.1)
{
double d = pow( 1.19 , theta ) * 3.0;
x = cx + (d * cos(theta-theta_t+theta_mouse));
y = cy + (d * sin(theta-theta_t+theta_mouse));
LineTo(hdc,x,y);
}
Ok now the parameter of spiral is 1.19 (slope) and 3.0 (radius at center)
Just compare the points where theta is a mutiple of 2 PI = PI2 = 6,283185307179586476925286766559
if any points is near of a non rotated spiral like
x = cx + (d * cos(theta));
y = cy + (d * sin(theta));
then your mouse is ON the spiral... I searched this tonight and i googled your past question