A WinForms application that visualizes, as a heatmap, the received-power distribution from multiple indoor Wi-Fi access points (APs) across an office made up of a corridor and several rooms.
The propagation models and building-material transmission losses are based on ITU-R recommendations:
- Distance loss: ITU-R P.1238-13 (09/2025), eq. (2)
L = 20log10(f) − 28 + N·log10(d) - Wall transmission / reflection loss: ITU-R P.2040-4 (09/2025) — material electrical constants and single-layer slab transmission/reflection coefficients
- Diffraction loss: ITU-R P.526 single knife-edge approximation
J(ν) - Antenna pattern: ITU-R F.1336-5 empirical patterns (omni / directional), or an
.antfile
In addition to the direct wave, it combines first-order reflections off walls and diffraction at the edges of apertures (windows/doors).
Requirements
- .NET 8 SDK or later
- Windows (the UI is WinForms; the
WiFiArea.Corecalculation layer is OS-independent, and its tests run on non-Windows too)
dotnet build WiFiArea.slndotnet run --project WiFiArea.Desktop -- config/office-sample.jsonIf you omit the argument, the app walks up from the working directory and opens config/office-sample.json automatically.
| Action | Effect |
|---|---|
| Wheel | Zoom (anchored at the cursor) |
| Drag | Pan |
Double-click / Home |
Fit to view |
F5 |
Reload the config and recalculate |
Ctrl+O |
Open a config |
Ctrl+S |
Save the current view as PNG |
The status bar shows the value under the cursor (received power, loss, and number of paths).
Buildings and antennas are not edited in the GUI. Edit the config file in a text editor and press F5 to reload.
config/office-sample.json is a practical example (one corridor + six rooms + four APs). It is JSON but tolerates line comments // and trailing commas.
| Key | Meaning |
|---|---|
name |
Building name (shown in the title bar and the right pane) |
environment |
office / corridor / industrial / conferenceRoom; used for the coefficient lookup when a site-general model is selected |
extent |
Calculation/drawing range { "x0":0, "y0":0, "x1":24, "y1":14 } [m] |
ceilingHeightM |
Ceiling height [m]; used for input validation |
Specifying ituMaterial + thicknessMm computes the transmission loss from the material constants in ITU-R P.2040-4 Table 3. Specifying lossOverrideDb uses that fixed value instead (e.g. to substitute a measured value).
{ "id": "concrete", "displayName": "Concrete wall 180mm",
"ituMaterial": "Concrete", "thicknessMm": 180, "color": "#555555" }Available ituMaterial values (the P.2040-4 Table 3 material classes):
Vacuum / Concrete / Brick / Plasterboard / Wood / Glass / Clear Acrylic / Ceiling board / Chipboard / Plywood / Marble / Floorboard / Vinyl tile / Carpet tile / Asphalt concrete / Metal
Each material has a valid frequency range; using a frequency outside it is an error (coefficients are not extrapolated). For example, Floorboard is only defined at 50 GHz and above, so it cannot be used in the Wi-Fi bands.
A wall is a line segment + material; apertures (windows, doors, openings) are given as intervals measured from the wall's start point.
{ "id": "W-C-S1", "from": [0, 6], "to": [18, 6], "material": "partition",
"apertures": [
{ "type": "door", "start": 2.6, "length": 0.9, "material": "wood-door" }
] }Rooms are for display only and are not used in the calculation.
{ "id": "AP1", "name": "AP-01 (corridor west)", "position": [6.0, 7.0], "heightM": 2.6,
"frequencyMHz": 2412, "txPowerDbm": 17.0, "cableLossDb": 0.0,
"azimuthDeg": 0, "tiltDeg": 0,
"antenna": { "mode": "omni", "gainDbi": 3.0 } }antenna.mode |
Required fields | Pattern |
|---|---|---|
omni |
gainDbi |
F.1336-5 omni pattern (uniform in azimuth, dipole-like in elevation) |
directional |
gainDbi, hpbwHDeg |
F.1336-5 Recommends 3; hpbwVDeg is auto-derived from the empirical formula if omitted |
file |
patternFile |
.ant file (path relative to the config) |
Do not use
omnifor a ceiling-mounted AP. The F.1336 omni pattern is dipole-like, so the antenna-axis direction (straight down) is a null: directly under the AP is −8 dBi while the horizontal direction is +3 dBi, which cancels the distance falloff and flattens the distribution. Real ceiling APs radiate into the lower hemisphere, so specify a pattern such as the bundledconfig/patterns/ceiling-ap.ant(maximum straight down, −6 dB at the horizon, −20 dB straight up) infilemode.omniis appropriate for a pole-mounted vertical rod antenna whose axis is vertical and which radiates in the horizontal plane.
azimuthDegis measured clockwise with +y as 0° (the same convention as a true-north bearing).tiltDegis positive for downtilt. A ceiling-mounted omni AP has a vertical antenna axis, so it is 0 (set it only when aiming a directional antenna downward).
{ ...,
"colormap": "RdYlGn", // Turbo (blue→red) / RdYlGn (green→red) / Grayscale
"thresholdsDbm": [-65.0, -75.0] // legend threshold lines; the first is the basis for the coverage ratio
}For each grid point, the received power is the sum of the powers of every path arriving from each AP. When there are multiple APs, the maximum (best server) among them is taken.
| Path | Description |
|---|---|
| Direct wave | The straight line joining Tx and Rx; the transmission loss of each penetrated wall is added |
| First-order reflection | The reflection point is found by the image method on the wall face; reflection coefficients come from the P.2040 slab coefficients. Metal walls reflect almost losslessly (|R|≈1) |
| Diffracted wave | The aperture edge is treated as a vertical knife edge; from the path difference Δ, ν = √(2Δ/λ) and J(ν) are applied |
The received power of each path is:
Prx = Pt − feed loss + Gtx(3D) + Grx − L_distance − Σ L_wall − L_extra [dBm]
L_extra is the reflection or diffraction loss. Paths are combined by a simple power sum (incoherent combination); phase is not modeled. Fine interference fringes do not appear, but this is more practical for viewing the average distribution.
The bottom-right of the sample is a server room enclosed by metal-panel walls (with one wooden door). Toggling "Reflection" and "Diffraction" in the toolbar lets you compare against the direct-wave-only result.
| Project | Description |
|---|---|
WiFiArea.Core |
OS-independent geometry, materials, and propagation engine |
WiFiArea.Desktop |
Windows WinForms UI |
WiFiArea.Desktop.Tests |
Tests for the drawing transforms and color scales |
tools/FormPreview |
A verification harness that captures the screen to PNG |
dotnet test WiFiArea.slnAfter changing the UI, capture and visually check it:
dotnet run --project tools/FormPreview -- --config config/office-sample.json --out shots/main.png --size 1440x900This software is under the MIT License.
The propagation models and building-material electrical constants are based on the following ITU-R recommendations. The implementation uses only the coefficients needed in the indoor Wi-Fi bands (1–100 GHz) this app targets; obtain the full text and complete tables from the ITU website.
| Recommendation | What is used |
|---|---|
| ITU-R P.1238-13 (09/2025) | Indoor basic transmission-loss eqs. (1)(2), site-general coefficients, the guideline for the distance power coefficient N, floor penetration loss |
| ITU-R P.2040-4 (09/2025) | Building-material electrical-constant models, single-layer slab reflection/transmission coefficients (ABCD-matrix method) |
| ITU-R P.526 | Single knife-edge diffraction approximation J(ν) |
| ITU-R F.1336-5 | Empirical antenna radiation patterns |
This software has not been approved or endorsed by the ITU. The results are simplified predictions and do not guarantee the actual radio environment. Verify with field measurements when designing or operating radio equipment.



{ "schema": "wifiarea-site-1", // fixed; used for the compatibility check "site": { ... }, // building extent and environment "materials": [ ... ], // material definitions (referenced by id from walls/apertures) "walls": [ ... ], // walls (line segments + apertures) "rooms": [ ... ], // rooms (for display only; not used in the calculation) "antennas": [ ... ], // APs "calc": { ... }, // calculation settings "display": { ... } // display settings }