Getting pixel values from axis label values
Posted: Thu Aug 28, 2008 10:14 pm
I am trying to save the coordinates of a polygon that I marked on an image
displayed on a TColorGrid so that I can redraw the polygon at a later time.
My users save the polygon vertex values, and at a later date, draw a new image
using a different target and want to redraw the saved polygon.
Below is some example code that I use...
//
// This is the way I put data into the TColorGridSeries. My image data is
// stored in a 2D array of doubles called DblImageData. Note that IrrGrid is
// NOT defined because this code is still VERY slow.
//
for i := 0 to High(DblImageData) do
for j := 0 to High(DblImageData[0]) do
begin
{$ifndef IrrGrid}
// NOTE:
// We are adding 1 to the "X" and "Z" parameters as a work around for a bug
// steema has in their code that is suppose to be fixed in the next release.
// Setting IrregularGrid := True cause images to update REALLY slowly!
(Chart1.Series[SIndex] as TColorGridSeries).AddXYZ(i+1, DblImageData[i,j], j+1);
{$else}
// The axis here is much nicer, but redrawing the image is very slow when
// resizing.
(Chart1.Series[SIndex] as TColorGridSeries).AddXYZ(xScaleOff+i*xScaleMul,
DblImageData[i,j], zScaleOff+j*zScaleMul);
{$endif}
end;
//
// This is the way I fill in the Axis labels when IrregulatGrid is set to false
// which it is in my application.
//
{$ifndef IrrGrid}
// Fill in labels for the X axis.
for i := 0 to High(DblImageData) do
begin
x := i * xScaleMul + xScaleOff;
if (i mod (Length(DblImageData) Div 10) = 0) then
Chart1.Axes.Bottom.Items.add(i,Format('%-.2f',[x]));
end;
// Fill in labels for the Y axis.
for j := 0 to High(DblImageData[0]) do
begin
x := j * zScaleMul + zScaleOff;
if (j mod (Length(DblImageData) Div 10) = 0) then
Chart1.Axes.Left.Items.add(j,Format('%-.2f',[x]));
end;
{$Endif}
//
// I then draw a polygon on the image by getting mouse clicks and saving the
// axis values.
//
// So in procedure TPlotForm.Chart1MouseDown, I get the axis values of points
// clicked on the screen to draw a polygon. I save these points so that later I
// can redraw the polygon on another image with a different zoom and different
// screen size.
//
// NOTE: This is only a code snippet, it is not complete. Unessary application
// specific code and initialization was removed to simplify this example.
//
procedure TPlotForm.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
fIER_Array[High(fIER_Array)].X := X;
fIER_Array[High(fIER_Array)].Y := Y;
// Add the first vertex to the end of the list so we can close the polygon
// when we draw it
SetLength(fIER_Array, Length(fIER_Array)+1);
fIER_Array[High(fIER_Array)].X := fIER_Array[0].X;
fIER_Array[High(fIER_Array)].Y := fIER_Array[0].Y;
// Save polygon if there is more than 2 points in it.
if Length(fIER_Array) > 2 then
begin
// Draw the polygon.
Chart1.Canvas.Pen.Width := 1;
Chart1.Canvas.Polyline(fIER_Array);
// Save the current polygon in the IER shape list.
SetLength(fIERRecList, Length(fIERRecList)+1);
j := High(fIERRecList);
i := Length(fIER_Array);
// Pixel locations of each vertex
SetLength(fIERRecList[j].Point_List, i);
SetLength(fIERRecList[j].X_Values, i); // X axis values
SetLength(fIERRecList[j].Y_Values, i); // Y axis values
for i := 0 to High(fIER_Array) do
begin
// Save the X and Y pixel positions or the vertex points. This is
// really useless because the images sizez will be different!!
fIERRecList[j].Point_List := fIER_Array;
// Get the index of the point clicked.
k := Chart1.Series[0].Clicked(fIER_Array.X,fIER_Array.Y);
// Save the value of the axis label of the point clicked.
fIERRecList[j].X_Values := (k div (Chart1.Series[0] as TColorGridSeries).NumZValues) *
xScaleMul + xScaleOff;
fIERRecList[j].Y_Values := (k mod (Chart1.Series[0] as TColorGridSeries).NumZValues) *
zScaleMul + zScaleOff ;
end;
end;
end;
Now that I have the axis label values of the points in the polygon, how can I
go backwards to the pixel locations on a new image made sometime inthe future?
For example, if I collect data on a different target and display the image, I
want to redraw the polygon on the new target at the same x/y positions.
How do I get the pixel locations from the fIERRecList[j].X_Value and
fIERRecList[j].Y_Value arrays that I saved earlier?
Is there a better way to do this with Irregular grid set to False?
displayed on a TColorGrid so that I can redraw the polygon at a later time.
My users save the polygon vertex values, and at a later date, draw a new image
using a different target and want to redraw the saved polygon.
Below is some example code that I use...
//
// This is the way I put data into the TColorGridSeries. My image data is
// stored in a 2D array of doubles called DblImageData. Note that IrrGrid is
// NOT defined because this code is still VERY slow.
//
for i := 0 to High(DblImageData) do
for j := 0 to High(DblImageData[0]) do
begin
{$ifndef IrrGrid}
// NOTE:
// We are adding 1 to the "X" and "Z" parameters as a work around for a bug
// steema has in their code that is suppose to be fixed in the next release.
// Setting IrregularGrid := True cause images to update REALLY slowly!
(Chart1.Series[SIndex] as TColorGridSeries).AddXYZ(i+1, DblImageData[i,j], j+1);
{$else}
// The axis here is much nicer, but redrawing the image is very slow when
// resizing.
(Chart1.Series[SIndex] as TColorGridSeries).AddXYZ(xScaleOff+i*xScaleMul,
DblImageData[i,j], zScaleOff+j*zScaleMul);
{$endif}
end;
//
// This is the way I fill in the Axis labels when IrregulatGrid is set to false
// which it is in my application.
//
{$ifndef IrrGrid}
// Fill in labels for the X axis.
for i := 0 to High(DblImageData) do
begin
x := i * xScaleMul + xScaleOff;
if (i mod (Length(DblImageData) Div 10) = 0) then
Chart1.Axes.Bottom.Items.add(i,Format('%-.2f',[x]));
end;
// Fill in labels for the Y axis.
for j := 0 to High(DblImageData[0]) do
begin
x := j * zScaleMul + zScaleOff;
if (j mod (Length(DblImageData) Div 10) = 0) then
Chart1.Axes.Left.Items.add(j,Format('%-.2f',[x]));
end;
{$Endif}
//
// I then draw a polygon on the image by getting mouse clicks and saving the
// axis values.
//
// So in procedure TPlotForm.Chart1MouseDown, I get the axis values of points
// clicked on the screen to draw a polygon. I save these points so that later I
// can redraw the polygon on another image with a different zoom and different
// screen size.
//
// NOTE: This is only a code snippet, it is not complete. Unessary application
// specific code and initialization was removed to simplify this example.
//
procedure TPlotForm.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
fIER_Array[High(fIER_Array)].X := X;
fIER_Array[High(fIER_Array)].Y := Y;
// Add the first vertex to the end of the list so we can close the polygon
// when we draw it
SetLength(fIER_Array, Length(fIER_Array)+1);
fIER_Array[High(fIER_Array)].X := fIER_Array[0].X;
fIER_Array[High(fIER_Array)].Y := fIER_Array[0].Y;
// Save polygon if there is more than 2 points in it.
if Length(fIER_Array) > 2 then
begin
// Draw the polygon.
Chart1.Canvas.Pen.Width := 1;
Chart1.Canvas.Polyline(fIER_Array);
// Save the current polygon in the IER shape list.
SetLength(fIERRecList, Length(fIERRecList)+1);
j := High(fIERRecList);
i := Length(fIER_Array);
// Pixel locations of each vertex
SetLength(fIERRecList[j].Point_List, i);
SetLength(fIERRecList[j].X_Values, i); // X axis values
SetLength(fIERRecList[j].Y_Values, i); // Y axis values
for i := 0 to High(fIER_Array) do
begin
// Save the X and Y pixel positions or the vertex points. This is
// really useless because the images sizez will be different!!
fIERRecList[j].Point_List := fIER_Array;
// Get the index of the point clicked.
k := Chart1.Series[0].Clicked(fIER_Array.X,fIER_Array.Y);
// Save the value of the axis label of the point clicked.
fIERRecList[j].X_Values := (k div (Chart1.Series[0] as TColorGridSeries).NumZValues) *
xScaleMul + xScaleOff;
fIERRecList[j].Y_Values := (k mod (Chart1.Series[0] as TColorGridSeries).NumZValues) *
zScaleMul + zScaleOff ;
end;
end;
end;
Now that I have the axis label values of the points in the polygon, how can I
go backwards to the pixel locations on a new image made sometime inthe future?
For example, if I collect data on a different target and display the image, I
want to redraw the polygon on the new target at the same x/y positions.
How do I get the pixel locations from the fIERRecList[j].X_Value and
fIERRecList[j].Y_Value arrays that I saved earlier?
Is there a better way to do this with Irregular grid set to False?