Scenegraph - Geometry Structures Tutorial

scenegraph tutorial On this page we will create and draw a scenegraph with various plots and a grid in the background.

Installing the code

Scenegraph graphics has been in FriCAS since FriCAS 1.1.1 but I sometimes update this code so if you need the latest version you can install it as described on this page.

Using the code

Before we can use the scenegraph we need to make the domains available.

This is very tedious, it would be better if this was done by default.

(1) -> )expose SCartesian

   SCartesian is now explicitly exposed in frame frame1
(1) -> )expose SArgand

   SArgand is now explicitly exposed in frame frame1
(1) -> )expose SConformal

   SConformal is now explicitly exposed in frame frame1 
(1) -> )expose SceneIFS

   SceneIFS is now explicitly exposed in frame frame1 
(1) -> )expose SceneNamedPoints

   SceneNamedPoints is now explicitly exposed in frame frame1 
(1) -> )expose STransform

   STransform is now explicitly exposed in frame frame1 
(1) -> )expose SBoundary

   SBoundary is now explicitly exposed in frame frame1 
(1) -> )expose ExportXml

   ExportXml is now explicitly exposed in frame frame1 
  

Example 1 - Two dimensional plots with scale.

First we will create a couple of functions to plot:

(1) -> DF ==> DoubleFloat
                                                             Type: Void
(2) -> fnsin(x:DF):DF == sin(x)
   Function declaration fnsin : DoubleFloat -> DoubleFloat has been 
      added to workspace.
                                                             Type: Void
(3) -> fntan(x:DF):DF == tan(x)
   Function declaration fntan : DoubleFloat -> DoubleFloat has been 
      added to workspace.
                                                             Type: Void

We then need to define what type of algebra to use to define our points, in this case we will use two dimentional Cartesian coordinates:

(4) -> PT ==> SCartesian(2)
                                                             Type: Void

Then we create a bounding box, this is the box within which we do the drawing. For further information about how to use boundaries see page here. This boundary contains two points representing the maximum and minimum extent of the drawing area or volume. That is mins contains the minimum values of x,y… and maxs contains the maximum values of x,y…

(5) -> view := boxBoundary(sipnt(-1,-1)$PT,sipnt(3,1)$PT)$SBoundary(PT)
   (5)  bound box:pt(- 1.0,- 1.0)->pt(3.0,1.0)
                                         Type: SBoundary(SCartesian(2))

(6) -> sc := createSceneRoot(view)$Scene(PT)
   (6)  scene root bound box:pt(- 1.0,- 1.0)->pt(3.0,1.0) #ch=0
                                             Type: Scene(SCartesian(2))

(7) -> gd := addSceneGrid(sc,view)$Scene(PT)
   (7)  scene group #ch=3
                                             Type: Scene(SCartesian(2))
svg plot

We can now export this to a SVG file so that we can confirm that the scene contains a grid:

writeSvg(sc,"test1.svg")

When we open this file using Inkscape or any other suitable SVG editor then we get the grid on the left.

We can add axis lines:

(8) -> addSceneRuler_
	   (sc,"HORIZONTAL"::Symbol,spnt(0::DF,-0.1::DF)$PT,view)$Scene(PT)
   (8)  scene group #ch=21
                                             Type: Scene(SCartesian(2))

(9) -> addSceneRuler_
         (sc,"VERTICAL"::Symbol,spnt(-0.1::DF,0::DF)$PT,view)$Scene(PT)
   (9)  scene group #ch=21
                                             Type: Scene(SCartesian(2))

Now lets add a plot to this. First we add a 'material' node to the root to define the colour and thickness of the plot. Then we add the plot to the material node using the sine function that we defined earlier.

(10) -> mt1 := addSceneMaterial(sc,3::DF,"blue","green")$Scene(PT)
   (10)  scene material lw=3.0 lc="blue" fc="green" mo=1.0 #ch=0
                                             Type: Scene(SCartesian(2))

(11) -> ln1 := addPlot1Din2D(mt1,fnsin,0..3::DF,49)$Scene(PT)
   Compiling function fnsin with type DoubleFloat -> DoubleFloat
   (11)  scene line [[pt(0.0,0.0),pt(0.0625,0.0624593178423802),....]] #ch=0
                                            Type: Scene(SCartesian(2))
svg plot

We can now export this to a SVG file again to see that the plot has been added to the grid:

writeSvg(sc,"test2.svg")

Again we can open this file using Inkscape to see the results.

Lets now add second plot to the scene so that we can see how to modify it using material and clip. If we did not clip the tangent function it would extend outside of our drawing area and we would also get a vertical line at the singularity at pi where the value jumps from plus infinity to minus infinity. We therfore create a boundary bb at line 13 and clip to that boundary at line 14. This clip node affects all nodes under it.

(12) -> mt2 := addSceneMaterial(sc,3::DF,"green","green")$Scene(PT)
   (12)  scene material lw=3.0 lc="green" fc="green" mo=1.0 #ch=0
                                             Type: Scene(SCartesian(2))

(13) -> bb := boxBoundary(sipnt(0,-1)$PT,sipnt(3,1)$PT)$SBoundary(PT)
   (13)  bound box:pt(0.0,- 1.0)->pt(3.0,1.0)
                                         Type: SBoundary(SCartesian(2))

(14) -> bb2 := addSceneClip(mt2,bb)$Scene(PT)
   (14)  scene clip bound box:pt(0.0,- 1.0)->pt(3.0,1.0) #ch=0
                                             Type: Scene(SCartesian(2))

(15) -> ln2 := addPlot1Din2D(bb2,fntan,0..3::DF,49)$Scene(PT)
   Compiling function fntan with type DoubleFloat -> DoubleFloat
   (15)  scene line [[pt(0.0,0.0),_
                           pt(0.0625,0.06258150756627502),....]] #ch=0
                                             Type: Scene(SCartesian(2))

(16) -> addSceneText(sc,"sin(theta)",32::NNI,_
                   spnt(0.5::DF,0.4::DF)$PT)$Scene(PT)
   (16)  scene text="sin(theta)" sz=32 p=pt(0.5,0.4) npt=[] #ch=0
                                             Type: Scene(SCartesian(2))

(17) -> addSceneText(sc,"tan(theta)",32::NNI,_
                   spnt(0.1::DF,0.6::DF)$PT)$Scene(PT)
   (17)  scene text="tan(theta)" sz=32 p=pt(0.1,0.6) npt=[] #ch=0
                                             Type: Scene(SCartesian(2))
svg plot

We can now export this to a SVG file to see the combined result:

writeSvg(sc,"test3.svg")

Again we can open this file using Inkscape to see the results.

Next Stage

For a tutorial about how to transform these shapes see this page.

Further Information

Other aspects of the graphics framework on these pages:


metadata block
see also:
  • A tutorial about how to transform these shapes is on this page.
Correspondence about this page

This site may have errors. Don't use for critical systems.

Copyright (c) 1998-2023 Martin John Baker - All rights reserved - privacy policy.