Geometric errors

W.Pasman, november 1999
Revised 14.11.2001

Model of distortion

All distortions are screen-space error in rad (by the 2Atn[r/d] term).
If you omit this term you have the geometric distortion.
No corrections for lifetime here.

Sometimes one or more variables have no effect.
They are nevertheless passed as vars, to get consistent calls and avoid confusion
n=number of polygons
r=radius of virtual object
d=distance to object
k=complexity (see report)
θ=distance between optimal and actual viewpoint

Polygon simplification

See text.

PolygonSimpErr[n_, r_, d_, θ_, k_] := 
        k/n 2  ArcTan[r/d];

Viewpoint deptdt polygon simplification

For VptDepSimpErr formula see text.
    We derived that, considering the contour, half the number of polygons is required as compared to PolygonSimpErr.
    However for the internal faces, the distortion is 20 times as large as on the contour, thus 10 times PolygonSimpErr.
    We assume smooth transition and use Cos-shaped blending

Plot[21/4 - 19/4 Cos[2  θ], {θ, 0, π/2}]

VptDepSimpErr[n_, r_, d_, θ_, 
          k_] := 
(21/4 - 
              19/4 Cos[2  θ]) PolygonSimpErr[ n, r, d, θ, 
            k];

Simple Imposter

See "imp dist.nb" for full derivation

SimpleImposterErrExact1[n_, r_, dobj_, θ_, k_] := 
        Module[{sq, 
            frontfacedistortion}, 
sq = (Sqrt[(((dobj + r))^2) - 4 (r^2) Cos[θ] + 4 (r^2) Cos[θ]^2]); 
frontfacedistortion = 
            Abs[ArcSin[(Cos[(θ/2)] (-dobj + r + sq - 
                          2 r Cos[θ]) )/((Sqrt[2]) √((dobj^2) + dobj r + 
                            r (r + sq) - (dobj (r + sq) + 
                                  2 r (2 r + sq)) Cos[θ] + 
                            2 r (dobj + 
                                  2 r) Cos[θ]^2))]] ; 
(1 + Cos[2  θ]) 
              frontfacedistortion +  (1 - Cos[2  θ]) 2 ArcTan[
                r/dobj]
];

Separate check whether θ=0 because that will cause div0 error

SimpleImposterErr[n_, r_, dobj_, θ_, k_] := 
        Module[{sq, 
            frontfacedistortion}, 
If[θ == 0, 
            0, 
SimpleImposterErrExact1[n, r, 
              dobj, θ, 
              k]
]
];

Imposter-plot

r = 0.4; 
    Plot3D[SimpleImposterErr[0, r, dobj, θ, 0], {dobj, 3, 
        10}, {θ, 0, π/2}, 
      AxesLabel -> {dobj, θ, error}, 
      PlotRange -> {0, 1}]

Meshed Imposter

Using k-term and ignoring back faces (effectively, n->2n) the formula becomes
dfront=k/n Sin[θ]
and the entire formula will be
[(1-cos2θ) + (1+cos2θ)k/(2n) sinθ] 2Atn[r/d]

MeshedImposterErr[n_, r_, d_, θ_, k_] := 
        2 ArcTan[
            r/d] ((1 - 
                  Cos[2  θ]) + (1 + 
                    Cos[2  θ]) (k/(2  
                          n) Sin[θ]));

This approximation may fail with low number of polygons
and furthermore it is not the way meshed imposters are generated so 
improvement is possible.

Image with depth

Frontface perfect, backface missing

IwDErr[n_,r_,d_,θ_,k_]:= (1-Cos[2θ]) 2 ArcTan[r/d];

(*LDI equals IwD: no backside. This is not completely fair because LDI can handle complex transparent objects better, but that's not
in our model...*)

LDIErr[n_,r_,d_,θ_,k_]:=IwDErr[n,r,d,θ,k]; (* LDI can also not be viewed from the side, mentioned values of 1.26 suggest no back face at all *)

Help functions to simplify plotting

MakeMesh[m_, {{xmin_, xmax_}, {ymin_, ymax_}}] := 
        Module[{w, h, xs, ys}, 
          w = Dimensions[m][[2]]; 
h = Dimensions[
                m][[1]]; 
xs = xmax - xmin;  
          ys = ymax - ymin; 
Table[
            Polygon[{{x xs/w + xmin, y ys/h + ymin, 
                  m[[y + 1, x + 1]]}, {x xs/w + 
                    xmin, (y + 1) ys/h + ymin, 
                  m[[y + 2, x + 1]]}, {(x + 1) xs/w + 
                    xmin, (y + 1) ys/h + ymin, 
                  m[[y + 2, x + 2]]}, {(x + 1) xs/w + xmin, 
                  y ys/h + ymin, m[[y + 1, x + 2]]}}], {x, 0, 
              w - 2}, {y, 0, h - 2}]];

ConvertToMesh[SurfaceGraphics[points_,opts_]]:=
	MakeMesh[points,opts[[39,2]]]; (*MeshRange*)

Color definitions

PolygonColor = RGBColor[1, 0, 0];
VptDepColor = RGBColor[1, 1, 0];
IncrementalColor = 
        RGBColor[ .4,  .4,  .4];
SimpleImposterColor = RGBColor[0, 1, 0];
MeshedImposterColor = RGBColor[0, 1, 1];
IwDColor = RGBColor[ .8, 0.4, 1];
LDIColor = RGBColor[0, 0, 1];

Show[
          Graphics[{#, 
              Rectangle[{0, 0}, {1, 
                  1}]}]] &  /@  
{PolygonColor, 
        VptDepColor, IncrementalColor, SimpleImposterColor, 
        MeshedImposterColor, 
IwDColor, 
        LDIColor}

Some nice plots

Plot 1. error as function of θ and distance

SetOptions[Plot3D, ViewPoint -> {-2.251, -2.003, 1.540}, 
        AxesLabel -> {"θ", "dtce", "dtrtion"}];

r=.1; n=100; k=5; Clear[d];
pa=Plot3D[-180/Pi PolygonSimpErr[n,r,d,θ,k],{θ,0,Pi/2},{d,.5,8}];
pb=Plot3D[-180/Pi VptDepSimpErr[n,r,d,θ,k],{θ,0,Pi/2},{d,.5,8}
];
pc=Plot3D[-180/Pi SimpleImposterErr[n,r,d,θ,k],{θ,0,Pi/2},{d,.5,8}
];
pd=Plot3D[-180/Pi MeshedImposterErr[n,r,d,θ,k],{θ,0,Pi/2},{d,.5,8}
];
pe=Plot3D[-180/Pi IwDErr[n,r,d,θ,k],{θ,0,Pi/2},{d,.5,8}
];

\(Show[
      Graphics3D[
{PolygonColor, 
          ConvertToMesh[pa], 
VptDepColor, 
          ConvertToMesh[pb], 
SimpleImposterColor, 
          ConvertToMesh[pc], 
MeshedImposterColor, 
          ConvertToMesh[pd], 
IwDColor, ConvertToMesh[pe]}, 
        Lighting -> False, AspectRatio -> Automatic, 
        AxesLabel -> {"θ (rad)", "distance", "dstion(deg)"}, ViewPoint -> {1.480, \(-2.754\), 1.294}, 
        Axes -> True], 
PlotRange -> {0, \(-1\)}, 
      BoxRatios -> {1, 1,  .5}
]\)

.Export["Apps:Desktop Folder:bla.eps", %];

Plot 2. Error as function of θ and #polygons

\(\(SetOptions[Plot3D, ViewPoint -> {\(-2.251\), \(-2.003\), 1.540}, 
        AxesLabel -> {"θ", "#polys", "dtrtion"}];\)\)
nmin = 4;  nmax = 500;
θm = 20 Degree;

d=1.5;k=5; d=4;r=1;
pa=Plot3D[-180/Pi PolygonSimpErr[n,r,d,θ,k],{θ,0,θm},{n,nmin,nmax}
];
pb=Plot3D[-180/Pi VptDepSimpErr[n,r,d,θ,k],{θ,0,θm},{n,nmin,nmax}
];
pc=Plot3D[-180/Pi SimpleImposterErr[n,r,d,θ,k],{θ,0,θm},{n,nmin,nmax}
];
pd=Plot3D[-180/Pi MeshedImposterErr[n,r,d,θ,k],{θ,0,θm},{n,nmin,nmax}
];
pe=Plot3D[-180/Pi IwDErr[n,r,d,θ,k],{θ,0,θm},{n,nmin,nmax}
];

Collected plot

Show[
      Graphics3D[
{PolygonColor, 
          ConvertToMesh[pa], 
VptDepColor, 
          ConvertToMesh[pb], 
SimpleImposterColor, 
          ConvertToMesh[pc], 
MeshedImposterColor, 
          ConvertToMesh[pd]
, IwDColor, 
          ConvertToMesh[
            pe]
}, 
Lighting -> 
          False, AspectRatio -> Automatic, 
        AxesLabel -> {"θ (rad)", "#polys", "distortion \
(deg)"}, 
        ViewPoint -> {1.480, -2.754, 
            1.294}, 
Axes -> 
          True], 
PlotRange -> {{0, θm}, 
          Automatic, {0, -4}}, 
BoxRatios -> {1, 
          1,  .5}]

Note that all imposters have 0 distortion at θ=0, while polygon models dont reach 0.
This is purely theoretical, assuming infinity resolution bitmaps on the imposters and
their images generated with perfect virtual models (infinite number of triangles?).
Later we will deal with subsampling issues. 
Furthermore, all practical polygon models never reach 0 distortion because it can always be improved by adding more - properly sampled- points to the mesh.

Old and new SimpleImposter functions are very similar

Show[
      Graphics3D[
{
SimpleImposterColor, 
          ConvertToMesh[pc], 
MeshedImposterColor, 
          ConvertToMesh[
            pc2]
}, 
Lighting -> 
          False, AspectRatio -> Automatic, 
        AxesLabel -> {"θ (rad)", "#polys", "distortion \
(deg)"}, 
        ViewPoint -> {1.480, -2.754, 
            1.294}, 
Axes -> 
          True], 
BoxRatios -> {1, 1,  .5}, 
      PlotRange -> All]

.Export["Apps:Desktop Folder:bla.eps", %];

A 2-D plot

r=.1; d=1.5; n=50;
pa=Plot[-180/Pi PolygonSimpErr[n,r,d,θ,k],{θ,0,Pi/2}];
pb=Plot[-180/Pi VptDepSimpErr[n,r,d,θ,k],{θ,0,Pi/2}];
pc=Plot[-180/Pi SimpleImposterErr[n,r,d,θ,k],{θ,0,Pi/2}];
pd=Plot[-180/Pi MeshedImposterErr[n,r,d,θ,k],{θ,0,Pi/2}];
pe=Plot[-180/Pi IwDErr[n,r,d,θ,k],{θ,0,Pi/2}];

Show[
      Graphics[
{Thickness[ .02], PolygonColor, 
          pa[[1]], 
VptDepColor, 
          pb[[1]], 
SimpleImposterColor, 
          pc[[1]], 
MeshedImposterColor, 
          pd[[1]], 
IwDColor, 
          pe[[1]]
}], Frame -> True, 
      FrameLabel -> {"θ", "distortion"}, 
      PlotRange -> {Automatic, Automatic}]