/// <summary>Calculate Field-of-View from a detailed prescription.</summary>
        /// <param name="coordsObserver">Cordinates of observer;s hex.</param>
        /// <param name="radius">Maximum radius for Field-of-View.</param>
        /// <param name="heightObserver">Height (ASL) of the observer's eyes.</param>
        /// <param name="isOnboard">Returns whether this hex on the baoard.</param>
        /// <param name="heightTarget">Returns ground level (ASL) of supplied hex.</param>
        /// <param name="heightTerrain">Returns height (ASL) of terrain in supplied hex.</param>
        /// <param name="setFieldOfView">Sets a hex as visible in the Field-of-View.</param>
        private static void ComputeFieldOfView(
            HexCoords coordsObserver,
            int radius,
            int heightObserver,
            Func <HexCoords, bool> isOnboard,
            Func <HexCoords, int> heightTarget,
            Func <HexCoords, Hexside, int> heightTerrain,
            Action <HexCoords> setFieldOfView
            )
        {
            if (setFieldOfView == null)
            {
                throw new ArgumentNullException("setFieldOfView");
            }
            FieldOfViewTrace(true, " - Coords = " + coordsObserver.User.ToString());
            var matrixOrigin = new IntMatrix2D(coordsObserver.Canon);

            if (radius >= 0)
            {
                setFieldOfView(coordsObserver);           // Always visible to self!
            }
            Action <Dodecant> dodecantFov = d => {
                var dodecant = new Dodecant(d, matrixOrigin);
                _mapCoordsDodecant = hex => dodecant.TranslateDodecant <HexCoords>(v => v)(hex);

                ComputeFieldOfViewInDodecantZero(
                    radius,
                    heightObserver,
                    dodecant.TranslateDodecant(isOnboard),
                    dodecant.TranslateDodecant(heightTarget),
                    dodecant.TranslateDodecant(heightTerrain),
                    dodecant.TranslateDodecant(setFieldOfView)
                    );
            };

      #if DEBUG
            InSerial = true;
      #endif
            if (InSerial)
            {
                Dodecant.Dodecants.ForEach(dodecantFov);
            }
            else
            {
                Parallel.ForEach(Dodecant.Dodecants, dodecantFov);
            }
        }
 public Dodecant(Dodecant dodecant, IntMatrix2D matrixOrigin)
 {
     HexsideMap = dodecant.HexsideMap;
     Matrix     = dodecant.Matrix * matrixOrigin;
 }