This is an old revision of the document!
Table of Contents
Virtual Laser Scanner
Introduction
The ”Scanner” is a module implementing a virtual laser scanning device. To use it, first import the module :
import de.grogra.rgg.Scanner ;
and create a new instance :
Scanner ls = new Scanner() ;
Then, the process of points acquisition can be seen as follow :
- set a ray ”length” ;
- set an origin, and directions for the rays ;
- shoot the rays, store the returned data ;
- repeat until enough points are acquired. This process can be done step-by-step, or a method implementing a scanning according to some predefined schedule can be used.
Shooting of the rays
The rays are always shot according to two angular parameters ($\theta_{range}$ , $\phi_{range}$) defining the solid angle that will be scanned, two parameters ($\theta_{step}$ , $\phi_{step}$) defining the resolution with which it will be scanned, and a direct orthonormal basis ($\vec{x}, \vec{y}, \vec{z}$) serving as reference (see below).
In the spherical coordinate system i based on the reference basis ($\vec{x}, \vec{y}, \vec{z}$), rays are shot for $\theta \in \left[\frac{-\theta_{range}}{2}, \frac{-\theta_{range}}{2}\right]$ with an angular resolution $\theta_{step}$ and for $\phi \in \left[\frac{\pi}{2}-\frac{-\phi_{range}}{2}, \frac{\pi}{2}+\frac{-\phi_{range}}{2}\right]$ with an angular resolution $\phi_{step}$ (see illustration Fig.1 p.2). Thus, the mean direction of the rays shot is $\vec{x}$.
Details concerning the spherical and cylindrical coordinate system used in this module can be found at the end of this document (resp. 4.1 p.6 and 4.2 p.6).

Figure 1: Directions of rays shot for the parameters $\theta_{range} = \frac{\pi}{2}, \phi_{range} = \frac{\pi}{4}, \theta_{step} = \frac{\pi}{20}, \phi_{step} = \frac{\pi}{8}$.
## Methods available
Remark : if calling multiple scan methods (e.g. _scan_, _scanCylinder_, _scanSphere_ ; see below) in a row, be sure to save the returned data after each call, as they will not be kept.
Notations : _Seg(Point3d point, Vector3d vector, Double l) _ designates the segment which has the point _point_ at one end, the direction vector _direction_, and of length _l_. _Cir(Point3d center, Vector3d normal, Double r)_ designates the circle of _center_ center, of radius _r_ and contained in a plane orthogonal to the vector _normal_.
setRayLength   Sets the range of the rays. <div align=“center”> void setRayLength(double desiredLength) ; </div>
_desiredLenght_ must be strictly positive.
setBasis   Sets the 3-dimensional basis to be used as reference for shooting the rays. <div align=“center”> void setBasis(Vector3d x, Vector3d y, Vector3d y) ; </div>
The 3 vectors must form a direct orthogonal basis.
setRange   Sets the angular opening in _θ_ and _φ_. <div align=“center”> void setRange(double thetaRange,double phiRange) ; </div>
If $thetaRange \ge 2 · \pi$ (resp. $phiRange \ge \pi$) , then $thetaRange = 2 · \pi$ (resp. $phiRange = \pi$) will be used instead. $thetaRange \le 0$ (resp. $phiRange \le 0$) sets an angular opening in _theta_ (resp. _phi_ ) of 0 (Note : _thetaRange = 0_ and _phiRange = 0_ corresponds at the shooting of only one ray, along the x-axis).
setSteps   Sets the resolution in _theta_ and _phi_. <div align=“center”> void setSteps(double thetaStep,double phiStep) ; </div>
If $thetaStep \ge thetaRange$ (resp. $phiStep \ge phiRange$) , then _thetaStep = thetaRange_ (resp. _phiStep = phiRange_) will be used instead. $thetaStep \le 0$ (resp. $phiRange \le 0$) sets an angular opening in theta (resp. _phi_ ) of 0.
setpDrawRay   Set the probability of drawing one ray. <div align=“center”> void setpDrawRay(double p) ; </div>
Each ray will be drawn with a probability _p_ (if $p \le 0$ no rays will be drawn, if $p \ge 1$ all the rays will be drawn), thus $n · p$ will be drawn in average (with _n_ the total number of rays shot).
scan   Triggers the scanning with the specified options. <div align=“center”> ArrayList<Point3d> scan(Point3d center) ; </div>
Rays will be shot from the point center, according to the angular parameters specified. Scanned points are returned in an ArrayList.
writeDataToFile   Writes the ArrayList _data_ in a file named _fileName_. The data are written according to a ”x y z” format. <div align=“center”> void writeDataToFile(ArrayList<Point3d> data, String fileName) ; </div>
scanSegment   Moves the origin of the rays along the segment _Seg(startingPoint, direction, (nbSteps − 1) · stepLength)_. Rays are shot at each step according to the specified parameters. Scanned points are returned in an ArrayList. <div align=“center”> ArrayList<Point3d> scanSegment (Point3d startingPoint, Vector3d direction, double stepLength, int nbSteps) ; </div>
The vector _direction_ must not be null, _stepLenght_ and _nbSteps_ must be strictly positive.
Please note that for all the following methods, the angular pa- rameters used are those fixed by the methods _setRange_ and _setSteps_. However, the basis defining the directions of the rays are defined within the methods.
scanCircle   Moves the origin of the rays along the circle _Cir(center, normal, r)_. Rays are shot for each angular step _angleStep_ until a complete circle has been covered. Directions of the rays shot are defined by the local cylindrical basis $(-u, -u_{\theta}, normal)$ formed at each step, with respect to the reference basis $(zeroAngleVector, normal \land zeroAngleVector, normal)$. Scanned points are returned in an ArrayList. <div align=“center”> ArrayList<Point3d> scanCircle(Point3d center, double r, Vector3d normal,Vector3d zeroAngleVector, double angleStep) ; </div> <div align=“center”> ArrayList<Point3d> scanCircle(Point3d center, double r, Vector3d normal, double angleStep) ; </div>
The vector _zeroAngleVector_ specifies the angle reference for the circle. It must be orthogonal to normal. If none is specified, an arbitrary vector is used.
scanCylinder   Moves the origin of the rays on the surface of the cylinder of axis the segment _Seg(startingPoint, axis, (nbSteps-1) · lengthAxisStep)_ and of radius _r_. For each step _i_ along the cylinder’s axis, the origin of the rays revolves around the cylinder with an angular step _angularStep_. Rays are shot at each angular step until a complete circle has been covered. Directions of the rays shot are defined by the local cylindrical basis $(-u, -u_{\theta}, axis)$ formed at each angular step, with respect to the reference basis $(zeroAngleVector, axis \land zeroAngleVector, axis)$. Scanned points are returned in an ArrayList. <div align=“center”> ArrayList<Point3d> scanCylinder ( Point3d startingPoint, Vector3d axis, double radius, double angularStep, double lengthAxisStep, int nbSteps) ; </div> <div align=“center”> ArrayList<Point3d> scanCylinder ( Point3d startingPoint, Vector3d axis, double radius, double angularStep, double lengthAxisStep, int nbSteps, Vector3d zeroAngleVector) ; </div>
The vector _zeroAngleVector_ specifies the angle reference for each circle. It must be orthogonal to _axis_. If none is specified, an arbitrary vector is used.
scanSphere   Moves the origin of the rays on a sphere of center center and radius _r_. With respect to the spherical coordinate system based on the basis _(x,y,z)_, the origin of the rays moves from _φ = 0_ to _φ = π_ with a step _phiStep_, and, for each angle _φ_, from _θ = 0_ to _θ = 2π_ with a step _thetaStep_. Rays are shot for each couple _(θ, φ)_, their directions being defined by the local spherical basis $(−u_{r}$, $−u_{\phi}$, $u_{\theta})$. Scanned points are returned in an ArrayList. <div align=“center”> ArrayList<Point3d> scanSphere (Point3d center, double r, double phiStep, double thetaStep, Vector3d x, Vector3d y, Vector3d z) ; </div>
_(x, y, z)_ must be a direct orthogonal basis, _r_ and _phiStep_ must be strictly positive. If $thetaStep \le 0$, then _θ = 0_ will be used at each step (thus the origin of the rays describes an half circle).
Noise simulation   A set of methods enables noise simulation. The introduction of a noise factor is triggered for the parameters _θ_, _φ_ and the hit distance by the following methods: <div align=“center”> void setThetaNoise(boolean value) ; </div> <div align=“center”> void setPhiNoise(boolean value) ; </div> <div align=“center”> void setDistanceNoise(boolean value) ; </div>
Each time a point is acquired, a noise factor is added to the angle _θ_ and or _φ_ and or the hit distance when computing the point’s position. Noise on _θ_ and _φ_ modifies the direction in which the point is thought to be ; noise on the hit distance the distance (in this direction) from the scanner.
The type of noise can be set through the following methods : <div align=“center”> void setThetaNoiseType(int type, boolean adapt, double param1, double param2) ; </div> <div align=“center”> void setPhiNoiseType(int type, boolean adapt, double param1, double param2) ; </div> <div align=“center”> void setDistanceNoiseType(int type, boolean adapt, double param1, double param2) ; </div>
_type = 0_ sets the noise to an uniform perturbation, _type = 1_ to a gaussian one (any other value inducing no noise at all). _adapt = false_ produces a noise with fixed parameters, whereas _adapt = true_ produces a noise which parameters depends on the real value (see below).
Given the real value $\alpha_{r}$ of one parameter (_θ_, _φ_ or the hit distance), the value used to compute the point’s position is $`\alpha_{r} = \alpha_{r} + \epsilon`$, where _ϵ_ is the noise. With _U(a, b)_ denoting the uniform density on [_a_, _b_] (a < b), and _N(μ, σ)_ the gaussian density of mean _μ_ and standard deviation _σ_, the perturbation _ϵ_ has the corresponding density :

## Annexes
### Spherical coordinate system
The spherical coordinate system is a 3d-coordinate system in which the position of a point is specified by two angular parameters θ and φ and the radial distance _r_. Given a direct orthonormal basis $B_{0} = (\vec{x}, \vec{y}, \vec{z})$, and a fixed origin point _O_, these parameters, for some point _M(r, θ, φ)_, are defined as follow (see Fig.2 p.7) :
$\theta = \widehat{\vec{x}, \vec{OP}}, \theta \in \left[0; 2\pi\right]$
$\phi = \widehat{\vec{z}, \vec{OM}}, \phi \in \left[0; \pi\right]$
_r = OM_
with _P_ the orthogonal projection of _M_ on the plane $(O, \vec{y}, \vec{z})$. Note that only the two angular parameters _θ_ and _φ_ are needed to define a direction (see Fig.2 p.7).
For each direction (_θ_, _φ_) a local direct orthonormal basis $B_{\theta, \phi} = (\vec{u_{r}}, \vec{u_{\phi}}, \vec{u_{\theta}})$ can be de defined, with :

## Cylindrical coordinate system
The cylindrical coordinate system is a 3d-coordinate system in which the position of a point is specified by one angular parameter θ, one distance _r_ and one height _z_. Given a direct orthonormal basis $B_{0} = (\vec{x}, \vec{y}, \vec{z})$, and a fixed origin point _O_, these parameters, for some point _M (r, θ, z)_, are defined as follow (see Fig.2 p.7)
$\theta = \widehat{\vec{x}, \vec{OP}}, \theta \in \left[0; 2\pi\right]$
_r = OM_
$z = \vec{OM} · \vec{z}$

<div align=“center”> Figure 2: Spherical and Cylindrical coordinate system </div>
with _P_ the orthogonal projection of _M_ on the plane $(O, \vec{x}, \vec{y})$ (see Fig.2 p.7).
For each angle _θ_ a local direct orthonormal basis $B_{\theta} = (\vec{u}, \vec{u_{\theta}}, \vec{z})$ can be de defined, with :

Original report: [etard_ls.pdf](uploads/ab75562dc87022a169f1e3ab929a78fa/etard_ls.pdf)