Getting pixel values from axis label values
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi dpatch,
Yes, we received the files, built your project and could reproduce the problem here but we need some time to investigate what's wrong here. We will get back to you when we have further news.
Yes, we received the files, built your project and could reproduce the problem here but we need some time to investigate what's wrong here. We will get back to you when we have further news.
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Hello,
The Polygon values returned in your demo project by CalcPosPoint are correct and coincide with the Axes' scales and Chart values.
If you were to disable the lines that populate the Custom Axis Labels you will see that the polygon data correctly reflect Axis data:
You need to obtain values according to the scale you have used for the Custom Labels. An option would be to create a lookup routine back to your data to translate the Chart values to your custom scale.
Regards,
Marc Meumann
The Polygon values returned in your demo project by CalcPosPoint are correct and coincide with the Axes' scales and Chart values.
If you were to disable the lines that populate the Custom Axis Labels you will see that the polygon data correctly reflect Axis data:
Code: Select all
To test comment the lines and run the project:
//Chart1.Axes.Bottom.Items.add ...
and
//Chart1.Axes.Left.Items.add ...
Regards,
Marc Meumann
Steema Support
I want to be sure that I understand exactly what you are saying.
I agree that CalcPosPoint is returning the axis values I put in using the Chart1.Series[index].AddXYZ method. Using that method because I have IrregularGrid set to false, I just increment a counter for the X and Z values. So, CalcPosPoint returns a floating point number between 1 and the number of points in the plot..in this case 128. Is this correct?
So, I think what you are saying, is that there is no direct way to get the a corresponding point on my custom label. I need to write a routine to do this myself. Is this also correct?
It is ok if I have to, actually, I already do this when I generate the custom axis labels. I was just hoping that your routines would return the custom axis value for me. I am afraid that I may run into problems when I start to rotate the polygons in 2D space.
Thanks in advance for your time...
I agree that CalcPosPoint is returning the axis values I put in using the Chart1.Series[index].AddXYZ method. Using that method because I have IrregularGrid set to false, I just increment a counter for the X and Z values. So, CalcPosPoint returns a floating point number between 1 and the number of points in the plot..in this case 128. Is this correct?
So, I think what you are saying, is that there is no direct way to get the a corresponding point on my custom label. I need to write a routine to do this myself. Is this also correct?
It is ok if I have to, actually, I already do this when I generate the custom axis labels. I was just hoping that your routines would return the custom axis value for me. I am afraid that I may run into problems when I start to rotate the polygons in 2D space.
Thanks in advance for your time...
Hello,
Regards,
Marc
Not quite correct (I think - if I've followed your text correctly). I see it as follows:CalcPosPoint returns the actual on-Chart value at the x,y pixel location passed to it. In your example that will be anywhere between 0 and 500 on either the Left or Bottom Axes. Comment the label population lines in your example and build a polygon and you will see the values coincide exactly with the default Axis scales.CalcPosPoint returns a floating point number between 1 and the number of points in the plot..in this case 128. Is this correct?
Correct. You would need to follow/backstep the steps you use to create the Labels. We couldn't think of a better way when we looked at it though it does the raise a feature request that we've now noted ... for an in-Chart technique to extract the nearest Label index from an x,y location. We'll look to do that for a future version.no direct way to get the a corresponding point on my custom label. I need to write a routine to do this myself. Is this also correct?
Regards,
Marc
Steema Support
Your last answer is what I suspected.
And, I agree that an "in-chart" solution to calculate the nearest axis Label index (or value) from an x,y point is a necessary function due to the inefficiencies of the chart when IrregularGrid is true. Also, given an axis label value, calculating the nearest x,y point would be the other half of the new feature.
Thanks Marc (and everyone), I appreciate your time.
And, I agree that an "in-chart" solution to calculate the nearest axis Label index (or value) from an x,y point is a necessary function due to the inefficiencies of the chart when IrregularGrid is true. Also, given an axis label value, calculating the nearest x,y point would be the other half of the new feature.
Thanks Marc (and everyone), I appreciate your time.
Hello, it has bee a while.
I am still unable to translate point values from the axis labels I created to pixel values on the screen so I can re-draw my polygons.
I have posted a simplified example on the upload page link you supplied earlied in this thread. It is called "Image Test 2.zip". There are coments in this example describing exactly what aI am trying to do. Can you please review this file and get back to me? I am really in a jam!
Thanks in advance.
I am still unable to translate point values from the axis labels I created to pixel values on the screen so I can re-draw my polygons.
I have posted a simplified example on the upload page link you supplied earlied in this thread. It is called "Image Test 2.zip". There are coments in this example describing exactly what aI am trying to do. Can you please review this file and get back to me? I am really in a jam!
Thanks in advance.
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi dpatch,
I think the problem here is that you are using axis scales values with screen coordinates.
In the Chart1MouseDown method you save polygon points like this:
Here X and Y are screen coordinates.
Later on the method you perform a transformation on them to be according to your custom axis labels:
I think the error here as you are mixing series/axis values with screen coordinates doing this transformation. Then, at RedrawPolygonsClick method it's quite tricky "undoing" the transformation to get screen coordinates again for plotting the polygons. Those custom labels may be good for your chart visualisation but are a problem for internal calculations.
Having said that, my suggestion is that you try to save polygon points relative to axis values in a floating point structure, something like this:
If possible, don't do any transformation on those values so that in RedrawPolygonsClick method you will just need to retrieve fVertex_List's axes values and convert them back to screen coordinates for plotting the polygons, for example:
Hope my explanation was clear and helpful for you. Otherwise don't hesitate to let us know.
I think the problem here is that you are using axis scales values with screen coordinates.
In the Chart1MouseDown method you save polygon points like this:
Code: Select all
// Save the new vertex
fVertex_List[High(fVertex_List)].X := X;
fVertex_List[High(fVertex_List)].Y := Y;
Later on the method you perform a transformation on them to be according to your custom axis labels:
Code: Select all
fPolygon_List[j].X_Values[i] := Chart1.Axes.Bottom.CalcPosPoint(fVertex_List[i].X) * fxScaleMul + fxScaleOff;
fPolygon_List[j].Y_Values[i] := Chart1.Axes.Left.CalcPosPoint(fVertex_List[i].Y) * fzScaleMul + fzScaleOff;
Having said that, my suggestion is that you try to save polygon points relative to axis values in a floating point structure, something like this:
Code: Select all
fVertex_List[High(fVertex_List)].X := Chart1.Axes.Bottom.CalcPosPoint(X);
fVertex_List[High(fVertex_List)].Y := Chart1.Axes.Left.CalcPosPoint(Y);
Code: Select all
Vertex_List[j].X := Chart1.Axes.Bottom.CalcXPosValue(Saved_Polygon_List[i].X_Values[j]);
Vertex_List[j].Y := Chart1.Axes.Left.CalcYPosValue(Saved_Polygon_List[i].Y_Values[j]);
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi dpatch,
I'd also like to comment that for running your project here I removed RTInumbers objects and related code. My impression was they don't have any effect on the problem discussed here, do they?
Thanks in advance.
I'd also like to comment that for running your project here I removed RTInumbers objects and related code. My impression was they don't have any effect on the problem discussed here, do they?
Thanks in advance.
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Thank you for your quick response.
You are correct, RTInumbers do NOT have an impact on this issue. I tried to remove unnecessary code when I cut and pasted from a larger project. I just missed that one.
Your explaination is very clear. I will give it a try and let you know how it goes.
Thanks again!
You are correct, RTInumbers do NOT have an impact on this issue. I tried to remove unnecessary code when I cut and pasted from a larger project. I just missed that one.
Your explaination is very clear. I will give it a try and let you know how it goes.
Thanks again!
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi dpatch,
I've made a quick test implementing what I explained in your project and it works even it needs to be improved.
I just sent you an e-mail with the modified project. RedrawPolygonsClick now draws the polygons but first one is always linked to the left-bottom corner of the chart and in case of mulitple polygons they are also linked.
Hope this helps!
I've made a quick test implementing what I explained in your project and it works even it needs to be improved.
I just sent you an e-mail with the modified project. RedrawPolygonsClick now draws the polygons but first one is always linked to the left-bottom corner of the chart and in case of mulitple polygons they are also linked.
Hope this helps!
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi dpatch,
BTW: The project with my modifications also gives a Range check error.
BTW: The project with my modifications also gives a Range check error.
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi dpatch,
Which can be solved using this code:BTW: The project with my modifications also gives a Range check error.
Code: Select all
//
// Convert and the points collected for the polygon to my axis values.
//
// NOTE: These are the points that I need to use when re-drawing the
// polygons on a new image.
//
for i := 0 to High(fAxesVertices_List) do
begin
fPolygon_List[j].X_Values[i] := fAxesVertices_List[i].X;
fPolygon_List[j].Y_Values[i] := fAxesVertices_List[i].Y;
// These are the points used in procedure RedrawPolygonsClick to
// re-draw the polygons.
Saved_Polygon_List[j] := fPolygon_List[j];
end;
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
I have recieved your code changes and looked at them. I think maybe I have not made my problem understood.
What I am doing is generating an image of a target and measuring the distance of its features in feet from the center. That is why I need to change the axis values to make zero at the center. Once I have the image, I draw the polygon around the features. I then generate a new image of a different target and take the polygons from the previous image and redraw then on the new image to see if the features have moved.
Since the scale can change, it is important that I save the distance in feet of each vertex, not it's axis position. That is why I applied the transform to the X/Y values. When I redraw the polygons on a new image, it is important that I place each vertex at the same "distance" in feet from the center. They may not be in the same X/Y position on the chart if my axis labels change. In your example, you removed the transform so you did not save the distance, only the axis position.
If you look at my original code, you will see that I performed the transform and saved the distance (or my axis values). My problem is that how do I get a new X/Y for a given an axis value, i.e. 2.5 feet?
In other words, if you look at my image, can you place a polygon on that image if I gave you only values from my axis labels that are in feet?
For example,
point1: x= -4.26, y= -2.66 feet
point2: x= -3.20, y= -2.50 feet
point3: x= -3.25, y= -2.00 feet
See here you do not have the axis positions that you saved in you example, only the distance from the center of the target. How can I get the new axis positions given only values from the axis labels I created using my transform?
If this is not clear, please let me know. I really need to solve this problem. If you want, I can also send you my original example if you did not save it. Also, I can create another one if you are still not clear on my problem.
Thanks so much.
What I am doing is generating an image of a target and measuring the distance of its features in feet from the center. That is why I need to change the axis values to make zero at the center. Once I have the image, I draw the polygon around the features. I then generate a new image of a different target and take the polygons from the previous image and redraw then on the new image to see if the features have moved.
Since the scale can change, it is important that I save the distance in feet of each vertex, not it's axis position. That is why I applied the transform to the X/Y values. When I redraw the polygons on a new image, it is important that I place each vertex at the same "distance" in feet from the center. They may not be in the same X/Y position on the chart if my axis labels change. In your example, you removed the transform so you did not save the distance, only the axis position.
If you look at my original code, you will see that I performed the transform and saved the distance (or my axis values). My problem is that how do I get a new X/Y for a given an axis value, i.e. 2.5 feet?
In other words, if you look at my image, can you place a polygon on that image if I gave you only values from my axis labels that are in feet?
For example,
point1: x= -4.26, y= -2.66 feet
point2: x= -3.20, y= -2.50 feet
point3: x= -3.25, y= -2.00 feet
See here you do not have the axis positions that you saved in you example, only the distance from the center of the target. How can I get the new axis positions given only values from the axis labels I created using my transform?
If this is not clear, please let me know. I really need to solve this problem. If you want, I can also send you my original example if you did not save it. Also, I can create another one if you are still not clear on my problem.
Thanks so much.
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi dpatch,
Thanks for the information. Now I understand which is the exact problem here.
In that case I think that a solution might be this:
1. Associating 4 default axes (left, top, right and bottom) to your series.
2. Use left and bottom axes as you already do for plotting the chart.
3. Manually set top and right axes scales. The point here would be being able to calculate each axis minimum and maximum value according to your transformation and assign such values to top and right axes using SetMinMax method. This calculation may be obtained from Series’s MinXValue, MaxXValue, MinYValue and MaxYValue with the transformation factors. For example:
4. Use right and top axes values for definning the polygons. This way you wouldn't need the transformation here. It would be just necessary in previous step for calculating top and right axes scales. For example:
5. Now you should be able to draw polygons again using the right and top axes values you have calculated as I suggested in my previous reply For example:
The key with this approach is the transformation calculation in point 3 and doing so every time a new chart is plotted.
I think I implemented this successfully to your project. I'm going to send it now by e-mail.
Is that what you were looking for?
Thanks for the information. Now I understand which is the exact problem here.
In that case I think that a solution might be this:
1. Associating 4 default axes (left, top, right and bottom) to your series.
2. Use left and bottom axes as you already do for plotting the chart.
3. Manually set top and right axes scales. The point here would be being able to calculate each axis minimum and maximum value according to your transformation and assign such values to top and right axes using SetMinMax method. This calculation may be obtained from Series’s MinXValue, MaxXValue, MinYValue and MaxYValue with the transformation factors. For example:
Code: Select all
Chart1[0].VertAxis:=aBothVertAxis;
Chart1[0].HorizAxis:=aBothHorizAxis;
Chart1.Axes.Top.SetMinMax(Chart1[0].MinXValue * fxScaleMul + fxScaleOff,
Chart1[0].MaxXValue * fxScaleMul + fxScaleOff );
Chart1.Axes.Right.SetMinMax(Chart1[0].MinYValue * fzScaleMul + fzScaleOff,
Chart1[0].MaxYValue * fzScaleMul + fzScaleOff );
Code: Select all
fAxesVertex_List[High(fAxesVertex_List)].X := Chart1.Axes.Top.CalcPosPoint(X);
fAxesVertex_List[High(fAxesVertex_List)].Y := Chart1.Axes.Right.CalcPosPoint(Y);
Code: Select all
Vertex_List[j].X := Chart1.Axes.Top.CalcXPosValue(Saved_Polygon_List[i].X_Values[j]);
Vertex_List[j].Y := Chart1.Axes.Right.CalcYPosValue(Saved_Polygon_List[i].Y_Values[j]);
I think I implemented this successfully to your project. I'm going to send it now by e-mail.
Is that what you were looking for?
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |