Finding Y value from X value in MSChart Series - mschart

I have created a Line chart using MSChart 2008.I have Dates on the x axis and Double values on y axis.Now I need to find Y value on Todays Date(Which will be my x value)..Can anybody help me to achieve this.
Thanks

I use a similar approach to this with cursors: I wanted to find the closest record to where the vertical cursor was added and show the value for that (as opposed to the value of the cursor coordinates):
If you swap out e.NewPosition with your query value (eg. today's date), the code should do what you want.
// Cursor Position Changing Event
private void chart1_CursorPositionChanged(object sender, CursorEventArgs e)
{
//Get the nearest record and use its X value as the position
double coercedPosition = chart1.Series[0].Points.Aggregate((x, y) => Math.Abs(x.XValue - e.NewPosition) < Math.Abs(y.XValue - e.NewPosition) ? x : y).XValue;
//Set cursor to the coerced position
chart1.ChartAreas[0].CursorX.Position = coercedPosition;
SetPosition(e.Axis, coercedPosition);
}
// Update the labels with the values at the indicated position
private void SetPosition(Axis axis, double position)
{
if (double.IsNaN(position))
return;
if (axis.AxisName == AxisName.X)
{
//Get the value at the position
DateTime dt = DateTime.FromOADate(position);
//set the timestamp label
lbl_CursorTimestampValue.Text = dt.ToString();
//get the point at that timestamp (x value)
var point = chart1.Series[0].Points.FindByValue(position, "X");
//set the y value label
lbl_CursorYValue.Text = point.IsEmpty == true ? "--" : point.YValues[0].ToString();
}
}
Also note that if you will want to convert your DateTime to an OA value:
double yourOADate = yourDateTime.ToOADate();

Related

Performing a cubic fit to a set of four points to extrapolate a "local" path, Or working alternatives?

Problem: Generate a extrapolated local path which provides path points ahead of the max FOV.
Situation: Having a car move round an unknown looped track of varying shape using a field of view which is limited so can only provide reliably 3 points ahead of the car and the car's current position. Note for more information the tack is defined by cone gates and the information provided about the locations of said gates is 2D (x,y).
Background: I have successfully generated a vector of mid points between gates however wish to generate an extrapolated path for the motion control algorithm to use. the format of this path needs to be a sequence of PathPoint (s) which contain (x,y velocity, gravity). note that gravity is just used to cap the maximum acceleration and is not important to the situation nor is velocity as the post is only concerned about generating respective (x,y) co-ordinates.
Attempted Solution Methodology: To fit two cubic functions for X positions and Y positions using the set of four points i.e f(x) and g(y). These functions should then be provided as the desired (f(x),g(y)) positions as we vary the look ahead distance to supply 20 path points.
Question: I do not believe this method to be correct both in theory and in implementation can anyone think of an easy/simple methodology to achieve the out come of having position in x axis and position in y axis to be the functions from the argument of overall distance from the car?
double PathPlanningClass::squared(double arg)
{
return arg*arg;
}
double PathPlanningClass::cubed(double arg)
{
return arg*arg*arg;
}
//https://eigen.tuxfamily.org/dox/group__TutorialLinearAlgebra.html
void PathPlanningClass::Coeffs()
{
Eigen::Matrix4f Aone;
Eigen::Vector4f bone;
Aone << _x, squared(_x), cubed(_x), _midpoints[0].getX(), squared(_midpoints[0].getX()), cubed(_midpoints[0].getX()), _midpoints[1].getX(), squared(_midpoints[1].getX()), cubed(_midpoints[1].getX()), _midpoints[_midpoints.size()-1].getX(), squared(_midpoints[_midpoints.size()-1].getX()), cubed(_midpoints[_midpoints.size()-1].getX());
bone << _y, _midpoints[0].getY(), _midpoints[1].getY(), _midpoints[_midpoints.size()-1].getY();
Eigen::Vector4f x = Aone.colPivHouseholderQr().solve(bone);
_Ax = x(1);
_Bx = x(2);
_Cx = x(3);
_Dx = x(4);
Eigen::Matrix4f Atwo;
Eigen::Vector4f btwo;
Atwo << _y, squared(_y), cubed(_y), _midpoints[0].getY(), squared(_midpoints[0].getY()), cubed(_midpoints[0].getY()), _midpoints[1].getY(), squared(_midpoints[1].getY()), cubed(_midpoints[1].getY()), _midpoints[_midpoints.size()-1].getY(), squared(_midpoints[_midpoints.size()-1].getY()), cubed(_midpoints[_midpoints.size()-1].getY());
btwo << _x, _midpoints[0].getX(), _midpoints[1].getX(), _midpoints[_midpoints.size()-1].getX();
Eigen::Vector4f y = Aone.colPivHouseholderQr().solve(bone);
_Ay = y(1);
_By = y(2);
_Cy = y(3);
_Dx = y(4);
return;
}
void PathPlanningClass::extrapolate()
{
// number of desired points
int numOfpoints = 20;
// distance to be extrapolated from car's location
double distance = 10;
// the argument for g(y) and f(x)
double arg = distance/numOfpoints;
for (int i = 0 ; i < numOfpoints; i++)
{
double farg = _Ax + _Bx*arg*i + _Cx*squared(arg*i) + _Dx*cubed(arg*i);
double garg = _Ay + _By*arg*i + _Cy*squared(arg*i) + _Dy*cubed(arg*i);
PathPoint newPoint(farg, garg, velocity(_x, _y, _yaw), 9.8);
_path.push_back(newPoint);
}
return;
}

c++ with custom 3D graphics library - Writing a while loop with the or operator between conditions

Im trying to write a looping block of code that codes that asks the following following within c++
while object A, or B or C or D == X, Y, Z (coords)
if A meets conditions, move object A East.
If B meets conditions, move object B East.
and so on,
I've pre-established each object coords as a string, so I just need to compare them against a control, Currently, I just have a loop that happens that doesn't recognise which object is triggering it.
The code to read coords and move the object is within a specific library, My tutor suggests using an array and a while loop to achieve this but I'm not sure how to do it even after spending several hours researching it.
I come from a background of unity and unreal engine so something simple like this goes over my head because I want to just use a conditional on the point, rather than react to each of the objects.
I'm very fresh to c# so please try to keep solutions simple thankyou!
EDIT: This is the code I am using at the moment
//Load strings at the start of the game
```string bblocal = (ballblue->GetLocalX, ballblue->GetLocalY, ballblue->GetLocalZ);
string bilocal = (ballindigo->GetLocalX,ballbindigo->GetLocalY, ballindigo->GetLocalZ);
string bvlocal = (ballviolet->GetLocalX,ballviolet->GetLocalY, ballviolet->GetLocalZ);
string bflocal = (ballfawn->GetLocalX,ballfawn->GetLocalY, ballfawn->GetLocalZ);
string bb = bblocal;
string bi = bilocal;
string bv = bvlocal;
string bf = bflocal;```
//For each tick, check the following
```while (bb || bi || bv || vf == (-50, 10, 50)
{
//Turn blue and move it to next point
if blue
{
ballblue->MoveX (0);
ballblue->MoveZ (100);
ballblue->RotateX (-50);
ballblue->RotateZ (50);
}
//Turn Indigo and move it to next point
//Turn Violet and move it to next point
//Turn Fawn and move it to next point
}
With a given class Point like:
public class Point
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
}
You have a brunch of define point:
var A = new Point{X=1, Y=0, Z=0};
var B = new Point{X=0, Y=1, Z=0};
var C = new Point{X=0, Y=0, Z=1};
// Etc
And a refenrece point to compare them with. List all the point you have to check in an array.
var referencePoint = new Point{X=0, Y=0, Z=1};
var pointsToCheck = new []{A, B, C};
An for each element of this array do your validation. You can have access to the point via the variable.
foreach(var p in pointsToCheck){
// Would be nice If Point add IEquatable<Point> with Equals gethashcode
if( p.X == referencePoint.X
&& p.Y == referencePoint.Y
&& p.Z == referencePoint.Z
)
{
//Do something!
p.X ++;
// Break; // if only the first must be moved.
}
}
Query them directly with LinQ
pointsToCheck.Where( p => p.X == referencePoint.X
&& p.Y == referencePoint.Y
&& p.Z == referencePoint.Z) ;
If you have an array of "corner" you point position in it, you will need the IEquatable.
var currentCornerIndex = Array.IndexOf(cornersList, CurrentPoint);
//Will return the next corner:
// if it's the last corner return the first
// if not a corner return the first.
var nextCornerIndex = (currentCornerIndex + 1) % cornersList.Length;
var nextCorner = cornersList[nextCornerIndex];

Find largest X pos value in QGraphicsItems

How can I loop through a set of Qt QGraphicsItems and find the max X value within the graph items selected. I have a function which seems to work but i recall it not being ideal to set the min value to NULL. The only reason im doing that is because otherwise the value returns something insanely far away. I just don't feel like im doing this the most efficient way. Keep in mind im taking into consideration the width of the actual graph item itself.
float max = NULL;
foreach (QGraphicsItem* item, items) {
if (!item) continue;
if (item->type() == NexusBlockItem::Type) {
float x = item->pos().x() + item->sceneBoundingRect().width()*.5;
if (max == NULL) max = x;
if (x > max) {
max = x;
}
}
}
I have a function which seems to work but i recall it not being ideal
to set the min value to NULL.
It's not actually possible to set a floating point value to NULL, since only pointers can be NULL in C++ and float is not a pointer type. What you're likely actually doing there is initializing max to 0.0f (because NULL is typically defined as 0), but conceptually it doesn't make any sense, and of course it will mess up your result if any of your actual x positions are less than zero.
As far as how to do it better, you have two options that I can think of:
1) Add a separate maximum_value_is_set variable to track when your max variable is not initialized yet.
float max; // not initialized here, because...
bool maximum_value_is_set = false; // we'll keep track of it this way instead
[...]
float x = item->pos().x() + item->sceneBoundingRect().width()*.5;
if ((maximum_value_is_set == false)||(x > max)) {
max = x;
maximum_value_is_set = true;
}
2) or, alternatively, you could just set the default value of max to the smallest possible floating point value:
float max = -FLT_MAX;
[...]
... that way any conceivable x value will be greater than the original value of max.
Btw...
float x = item->pos().x() + item->sceneBoundingRect().width()*.5;
Why the *.5 there? It looks like this code computes the center the the rectangle, but according to your graphic, you are more interested in the right side (in which case I think you'd want to get rid of the *.5).
this code is for your items you shared.
float max = 0;
foreach (QGraphicsItem* item, items) {
if (!item) continue;
if (item->type() == NexusBlockItem::Type) {
float x = item->boundingRect().width();
if (x > max) {
max = x;
}
}
but if your second item or others shifted to more right other than
item->boundingRect().windth(); is not give correct value.
what is the max value of "X"? is it biggest item's width or scene Rectangle's width?

How to extract date on X axis from a point on chart [mschart]

X axis type is DateTime. I want to know how to extract original DateTime value from the double value on the x axis corresponding to the point in my series?
I can add point with
point->SetValueXY(xdateTime,yvalue);
chart1->Series[0]-Add(point);
Try this C# code, it should give you a start. I use it to add text to a Label thats shows the x value as date and the yvalue as a number. Hope this helps
public void Cht_Click(object sender, System.Windows.Forms.MouseEventArgs e)
{
//Call HitTest()
HitTestResult result = sender.HitTest(e.X, e.Y);
//If the mouse if over a data point
if (result.ChartElementType == ChartElementType.DataPoint) {
//Reset Data Point Attributes
DataPoint point = default(DataPoint);
//Find selected data point
point = result.Series.Points(result.PointIndex);
//extract x value
System.DateTime _date = System.DateTime.FromOADate(point.XValue);
Label24.Text = "Date: " + Strings.Format(_date, "dd/MM/yy") + " Value: " + point.YValues(0);
}
}

Get a full double value

I add one double value from a file to a variable and push it into a vector, with format "338620.3478" , then after that I get the value from the vector, it just gets "338620", as it could not get all the double value.
So how can I get a full double value like the original format?
The Code:
struct Point {
double x, y;
bool operator <(const Point &p) const {
return x < p.x || (x == p.x && y < p.y);
}
};
ifstream iFile("griddata.dat"); //read a file (grid)
string line;
Point Grid; /
while(getline(iFile,line))
{
unsigned pos = line.find(",");//the symbol is used to separate X and Y
std::string strs = line.substr(0,pos); // get X
std::string strs2 = line.substr(pos+1); // get Y
Grid.x = atof(strs.c_str()); // get the first cooordinate X
Grid.y = atof(strs2.c_str()); // get the second cooordinate Y
// A list of coordinates of grid is stored into the vector gridPoints
gridPoints.push_back(Grid); // adding the points of grid to vector
}
int j;
for(j=0;j<gridPoints.size();j++)
{
//here i cannot get the full double value for gridPoints[j].x;
//....it just gets "338620"
}
The format of file (griddata.dat):
338620.3478,6196150.566
Thank you!
Assuming that your Point class is in the windows framework, I'm pretty sure it's members are int types.
Either way, your values are being cast to a type that isn't floating point and is being truncated.
I think your problem is retrieving the values (maybe with cout?? -->then you can use: cout.precision(15))
see: How do I print a double value with full precision using cout?