/// <summary>Calculate Field-of-View from a specified TargetMode, assuming a spherical earth /// and height measured in feet if <code>hexesPerMile</code> is not equal 0.</summary> /// <param name="board">A reference to an IFovBoard {IHex} instance.</param> /// <param name="coordsObserver">Cordinates of observer;s hex.</param> /// <param name="fovRadius">Radius of Field-of-view desired.</param> /// <param name="targetMode">TargetMode value for determining target visibility.</param> /// <param name="setFieldOfView">Sets a hex as visible in the Field-of-View.</param> /// <param name="defaultHeight">Height used for observer and target when targetMode = EqualHeights/</param> /// <param name="hexesPerMile">Number of hexes per mile (ie 1/4000 of planet radius).</param> /// <remarks>Adjusts visibility for curvature of the Earth. This is the only version of /// ComputeFieldOfView that is <b>not</b> scale invariant for height, and assumes that height /// is measured in feet. /// </remarks> /// <a href="http://mathcentral.uregina.ca/qq/database/QQ.09.02/shirley3.html">Hidden by the Curvature of the Earth</a> public static void ComputeFieldOfView( IFovBoard board, HexCoords coordsObserver, int fovRadius, FovTargetMode targetMode, Action <HexCoords> setFieldOfView, int defaultHeight, int hexesPerMile ) { if (fovRadius > int.MinValue) { fovRadius = fovRadius - 1; } int CalculationHeightUnits = UseMetric ? 5 // convert metres to cm for greater precision : 12; // convert feet to inches for greater precision Func <HexCoords, int> elevationTarget; int elevationObserver; switch (targetMode) { case FovTargetMode.TargetHeightEqualZero: elevationTarget = coords => board.ElevationGroundASL(coords); elevationObserver = board.ElevationObserverASL(coordsObserver); break; default: case FovTargetMode.TargetHeightEqualActual: elevationTarget = coords => board.ElevationTargetASL(coords); elevationObserver = board.ElevationObserverASL(coordsObserver); break; case FovTargetMode.EqualHeights: elevationTarget = coords => board.ElevationGroundASL(coords) + defaultHeight; elevationObserver = elevationTarget(coordsObserver); break; } var deltaHeight = GetDeltaHeight(coordsObserver, hexesPerMile, CalculationHeightUnits); ComputeFieldOfView( coordsObserver, fovRadius, elevationObserver * CalculationHeightUnits, hc => board.MapSizeHexes.IsOnboard(hc), coords => elevationTarget(coords) * CalculationHeightUnits - deltaHeight(coords), (coords, hexside) => board.ElevationHexsideASL(coords, hexside) * CalculationHeightUnits - deltaHeight(coords), setFieldOfView ); }
/// <summary>Calculate Field-of-View from a specified TargetMode, assuming a spherical earth /// and height measured in feet if <code>hexesPerMile</code> is not equal 0.</summary> /// <param name="coordsObserver">Cordinates of observer;s hex.</param> /// <param name="board">A reference to an IFovBoard {IHex} instance.</param> /// <param name="targetMode">TargetMode value for determining target visibility.</param> /// <param name="setFieldOfView">Sets a hex as visible in the Field-of-View.</param> /// <param name="defaultHeight">Height used for observer and target when targetMode = EqualHeights/</param> /// <param name="hexesPerMile">Number of hexes per mile (ie 1/4000 of planet radius).</param> /// <remarks>Adjusts visibility for curvature of the Earth. This is the only version of /// ComputeFieldOfView that is <b>not</b> scale invariant for height, and assumes that height /// is measured in feet. /// </remarks> /// <a href="http://mathcentral.uregina.ca/qq/database/QQ.09.02/shirley3.html">Hidden by the Curvature of the Earth</a> public static void ComputeFieldOfView( HexCoords coordsObserver, IFovBoard <IHex> board, FovTargetMode targetMode, Action <HexCoords> setFieldOfView, int defaultHeight, int hexesPerMile ) { int CalculationHeightUnits = UseMetric ? 5 // convert metres to cm for greater precision : 12; // convert feet to inches for greater precision Func <HexCoords, int> elevationTarget; int elevationObserver; switch (targetMode) { case FovTargetMode.TargetHeightEqualZero: elevationTarget = coords => board.ElevationGroundASL(coords); elevationObserver = board.ElevationObserverASL(coordsObserver); break; default: case FovTargetMode.TargetHeightEqualActual: elevationTarget = coords => board.ElevationTargetASL(coords); elevationObserver = board.ElevationObserverASL(coordsObserver); break; case FovTargetMode.EqualHeights: elevationTarget = coords => board.ElevationGroundASL(coords) + defaultHeight; elevationObserver = elevationTarget(coordsObserver); break; } Func <HexCoords, int> deltaHeight = GetDeltaHeight(coordsObserver, hexesPerMile, CalculationHeightUnits); ShadowCasting.ComputeFieldOfView( coordsObserver, board.FovRadius - 1, elevationObserver * CalculationHeightUnits, board.IsOnboard, coords => elevationTarget(coords) * CalculationHeightUnits - deltaHeight(coords), (coords, hexside) => board.ElevationHexsideASL(coords, hexside) * CalculationHeightUnits - deltaHeight(coords), setFieldOfView ); }