Page 1 of 1

How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Mon Feb 11, 2019 8:05 pm
by 16585377
Hello,

How can I draw nice 3D arrows like in the attached picture?
By using the code below I only get "flat" arrows
and can't draw an arrow in Z direction:

Code: Select all

var
  tmpX,tmpY,tmpZ: Integer;
  FromPoint,ToPoint: TPoint;
begin
  tmpY := Chart.ChartYCenter + Round(Chart.Canvas.RotationCenter.Y);
  tmpX := Chart.ChartXCenter + Round(Chart.Canvas.RotationCenter.X);
  tmpZ := (Chart.Width3D div 2) + Round(Chart.Canvas.RotationCenter.Z);
  StrainChart.Canvas.Pen.Color := clRed;
  StrainChart.Canvas.Pen.Width := 4;
  StrainChart.Canvas.Pen.Style := psSolid;

  FromPoint.X := Chart.ChartRect.Left;
  FromPoint.Y := tmpY;
  ToPoint.X := Chart.ChartRect.Right;
  ToPoint.Y := tmpY;
  Chart.Canvas.Arrow(True, FromPoint, ToPoint, 50, 50, tmpZ);

  FromPoint.X := tmpX;
  FromPoint.Y := Chart.ChartRect.Bottom;
  ToPoint.X := tmpX;
  ToPoint.Y := StrainChart.ChartRect.Top;
  Chart.Canvas.Arrow(True, FromPoint, ToPoint, 50, 50, tmpZ);
Nice3DArrowsCapture.PNG
Nice3DArrowsCapture.PNG (62.85 KiB) Viewed 28732 times
Flat2DArrowsCapture.PNG
Flat2DArrowsCapture.PNG (108.13 KiB) Viewed 28732 times

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Mon Feb 18, 2019 9:11 am
by yeray
Hello,

You can give it a try at the Vector series. Ie:

Code: Select all

uses TeeSurfa;

procedure TForm1.FormCreate(Sender: TObject);
begin
  with Chart1 do
  begin
    Chart3DPercent:=100;
    Aspect.Orthogonal:=False;
    Aspect.Zoom:=70;
    Legend.Hide;

    Axes.Left.SetMinMax(0,10);
    Axes.Bottom.SetMinMax(0,10);
    Axes.Depth.SetMinMax(0,10);
    Axes.Depth.Visible:=True;

    Axes.Left.Increment:=1;
    Axes.Bottom.Increment:=1;
    Axes.Depth.Increment:=1;
  end;

  with Chart1.AddSeries(TVector3DSeries) as TVector3DSeries do
  begin
    Color:=clRed;
    Pen.Width:=2;
    ArrowHeight:=10;
    ArrowWidth:=10;
    AddVector(5,5,5,0,5,5,'', clRed);
    AddVector(5,5,5,10,5,5,'', clRed);
    AddVector(5,5,5,5,0,5,'', clRed);
    AddVector(5,5,5,5,10,5,'', clRed);
    AddVector(5,5,5,5,5,0,'', clRed);
    AddVector(5,5,5,5,5,10,'', clRed);
  end;
end;
Project1_2019-02-18_10-09-28.png
Project1_2019-02-18_10-09-28.png (51.61 KiB) Viewed 28699 times

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Mon Feb 18, 2019 11:36 am
by 16585377
Hello Yeray,

that's a nice solution, interesting is that I can't get the Labels to work in call "AddVector", like:

AddVector(5,5,5,0,5,5,'Vector A', clRed);

Do you have a solution for that?
Also it would be nice to have real 3D Arrows on top of the Vector lines.

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Tue Feb 19, 2019 11:17 am
by yeray
Hello,
axrDegen wrote:
Mon Feb 18, 2019 11:36 am
interesting is that I can't get the Labels to work in call "AddVector", like:

AddVector(5,5,5,0,5,5,'Vector A', clRed);

Do you have a solution for that?
Try turning the Marks visible:

Code: Select all

    Marks.Visible:=True;
    Marks.Style:=smsLabel;
axrDegen wrote:
Mon Feb 18, 2019 11:36 am
Also it would be nice to have real 3D Arrows on top of the Vector lines.
How would you like them to look exactly?

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Tue Feb 19, 2019 12:39 pm
by 16585377
Ok, that makes them appear, but all the Labels are displayed together at the center point, please see the screenshot:
LabelsCapture.PNG
LabelsCapture.PNG (74.15 KiB) Viewed 28675 times
How Can I display the labels at the end of the Arrows?
The Arrowheads I would expect to be shown as a (3D) Cone, see below:
3DArrowdownload.jpg
3DArrowdownload.jpg (6.63 KiB) Viewed 28675 times

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Wed Feb 20, 2019 11:18 am
by yeray
Hello,

I'm afraid this is not possible right now.
I've created a new ticket in the public tracker:
http://bugs.teechart.net/show_bug.cgi?id=2161

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Wed Feb 20, 2019 12:42 pm
by 16585377
Ok, that is about making it nice, but what about the markers/labels, how can I get these displayed correctly?

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Thu Feb 21, 2019 3:55 pm
by yeray
Hello,
axrDegen wrote:
Wed Feb 20, 2019 12:42 pm
but what about the markers/labels, how can I get these displayed correctly?
Sorry, I missed that point.
You could use marks custom positioning at OnGetMarkText event. Ie:

Code: Select all

procedure TForm1.VectorGetMarkText(Sender:TChartSeries; ValueIndex:Integer; var MarkText:String);
begin
  if Assigned(Sender) and (ValueIndex>-1) and (ValueIndex<Sender.count) and
     Assigned(Sender.Marks.Positions) and Assigned(Sender.Marks.Positions[ValueIndex]) then
  begin
    with TVector3DSeries(Sender), Marks.Positions[ValueIndex] do
    begin
      Custom:=True;
      LeftTop:=ParentChart.Canvas.Calculate3DPosition(CalcXPosValue(EndXValues[ValueIndex]),
                                                      CalcYPosValue(EndYValues[ValueIndex]),
                                                      ParentChart.Axes.Depth.CalcPosValue(EndZValues[ValueIndex]));
    end;
  end;
end;

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Fri Feb 22, 2019 7:50 am
by 16585377
Thank you Yeray, that works for X and Y but not for Z, please see screenshot:
ZLabelProblemCapture.PNG
ZLabelProblemCapture.PNG (204.48 KiB) Viewed 28640 times
Note that I use the Min/Max of another series to calculate the Max values for the Vectors, like that:

Code: Select all

    MaxX := Max(FPoint3DSeries.MaxXValue, Abs(FPoint3DSeries.MinXValue));
    MaxY := Max(FPoint3DSeries.MaxYValue, Abs(FPoint3DSeries.MinYValue));
    MaxZ := Max(FPoint3DSeries.MaxZValue, Abs(FPoint3DSeries.MinZValue));
    FAxesSeries.AddVector(0,0,0, MaxX,0,0, 'a', clRed);
    FAxesSeries.AddVector(0,0,0, 0,MaxY,0, 'b', clGreen);
    FAxesSeries.AddVector(0,0,0, 0,0,MaxZ, 'c', clBlue);
How to solve that ?

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Fri Feb 22, 2019 10:29 am
by 16585377
I don't really understand that source code anyway, LeftTop (a TPoint value) is set per series Mark via call "Chart.Canvas.Calculate3DPosition"
How is the 3D position (X, Y, Z) coded into a TPoint, which only has X and Y ?
So where do you finally set the Z position of each Mark?

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Mon Feb 25, 2019 10:44 am
by yeray
Hello,

It seems to work fine for me here:
Project1_2019-02-25_11-38-47.png
Project1_2019-02-25_11-38-47.png (87.19 KiB) Viewed 28580 times
testVectorArrow2.zip
(2.17 KiB) Downloaded 1349 times
axrDegen wrote:
Fri Feb 22, 2019 10:29 am
I don't really understand that source code anyway, LeftTop (a TPoint value) is set per series Mark via call "Chart.Canvas.Calculate3DPosition"
How is the 3D position (X, Y, Z) coded into a TPoint, which only has X and Y ?
So where do you finally set the Z position of each Mark?
The Calculate3DPosition function converts 3D coordinates to 2D coordinates to be used when custom drawing (ref here)
Calculates and returns the XY position in pixels of the XYZ 3D coordinate.

Can be used when custom drawing using 3D XYZ coordinates, either returned from the axes or not.

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Mon Feb 25, 2019 11:17 am
by 16585377
Thank you, but this doesn't work. I am finally painting the axes labels in the OnAfterDraw event like that:

Code: Select all

    XCent := FAxesSeries.CalcXPosValue(0);
    YCent := FAxesSeries.CalcYPosValue(0);
    ZCent := aChart.Axes.Depth.CalcPosValue(0);
    XPosi := FAxesSeries.CalcXPosValue(FXAxisMax);
    YPosi := FAxesSeries.CalcYPosValue(FYAxisMax) - aChart.Canvas.TextHeight('b');
    ZPosi := aChart.Axes.Depth.CalcPosValue(FZAxisMax);
    aChart.Canvas.TextOut3D(XPosi, YCent, ZCent, 'a');
    aChart.Canvas.TextOut3D(XCent, YPosi, ZCent, 'b');
    aChart.Canvas.TextOut3D(XCent, YCent, ZPosi, 'c');

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Mon Feb 25, 2019 11:39 am
by yeray
Hello,
axrDegen wrote:
Mon Feb 25, 2019 11:17 am
I am finally painting the axes labels in the OnAfterDraw event
That's another possibility. Does it work as you want?

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Mon Feb 25, 2019 12:34 pm
by 16585377
Yes, that works very well

Re: How can I draw nice 3D Arrows to depict axes (a,b,c)

Posted: Tue Feb 26, 2019 7:22 am
by yeray
axrDegen wrote:
Mon Feb 25, 2019 12:34 pm
Yes, that works very well
Great!