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

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
axrDegen
Newbie
Newbie
Posts: 12
Joined: Mon Jan 14, 2019 12:00 am

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

Post by axrDegen » Mon Feb 11, 2019 8:05 pm

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 992 times
Flat2DArrowsCapture.PNG
Flat2DArrowsCapture.PNG (108.13 KiB) Viewed 992 times

Yeray
Site Admin
Site Admin
Posts: 8669
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

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

Post by Yeray » Mon Feb 18, 2019 9:11 am

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 959 times
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

axrDegen
Newbie
Newbie
Posts: 12
Joined: Mon Jan 14, 2019 12:00 am

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

Post by axrDegen » Mon Feb 18, 2019 11:36 am

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.

Yeray
Site Admin
Site Admin
Posts: 8669
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

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

Post by Yeray » Tue Feb 19, 2019 11:17 am

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?
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

axrDegen
Newbie
Newbie
Posts: 12
Joined: Mon Jan 14, 2019 12:00 am

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

Post by axrDegen » Tue Feb 19, 2019 12:39 pm

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 935 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 935 times

Yeray
Site Admin
Site Admin
Posts: 8669
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

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

Post by Yeray » Wed Feb 20, 2019 11:18 am

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
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

axrDegen
Newbie
Newbie
Posts: 12
Joined: Mon Jan 14, 2019 12:00 am

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

Post by axrDegen » Wed Feb 20, 2019 12:42 pm

Ok, that is about making it nice, but what about the markers/labels, how can I get these displayed correctly?

Yeray
Site Admin
Site Admin
Posts: 8669
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

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

Post by Yeray » Thu Feb 21, 2019 3:55 pm

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;
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

axrDegen
Newbie
Newbie
Posts: 12
Joined: Mon Jan 14, 2019 12:00 am

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

Post by axrDegen » Fri Feb 22, 2019 7:50 am

Thank you Yeray, that works for X and Y but not for Z, please see screenshot:
ZLabelProblemCapture.PNG
ZLabelProblemCapture.PNG (204.48 KiB) Viewed 900 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 ?

axrDegen
Newbie
Newbie
Posts: 12
Joined: Mon Jan 14, 2019 12:00 am

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

Post by axrDegen » 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?

Yeray
Site Admin
Site Admin
Posts: 8669
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

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

Post by Yeray » Mon Feb 25, 2019 10:44 am

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 840 times
testVectorArrow2.zip
(2.17 KiB) Downloaded 22 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.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

axrDegen
Newbie
Newbie
Posts: 12
Joined: Mon Jan 14, 2019 12:00 am

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

Post by axrDegen » Mon Feb 25, 2019 11:17 am

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');

Yeray
Site Admin
Site Admin
Posts: 8669
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

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

Post by Yeray » Mon Feb 25, 2019 11:39 am

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?
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

axrDegen
Newbie
Newbie
Posts: 12
Joined: Mon Jan 14, 2019 12:00 am

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

Post by axrDegen » Mon Feb 25, 2019 12:34 pm

Yes, that works very well

Yeray
Site Admin
Site Admin
Posts: 8669
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

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

Post by Yeray » Tue Feb 26, 2019 7:22 am

axrDegen wrote:
Mon Feb 25, 2019 12:34 pm
Yes, that works very well
Great!
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Post Reply