bmibody-compositionalgorithmanthropometrydeveloper-guide

Mass Index: An Alternative Body Composition Metric That Accounts for Leg Length

· 5 min read · Martin Hejda

BMI divides weight by height squared. The formula’s simplicity is also its main weakness: it assumes that body weight scales with height² consistently across all people. It doesn’t. Two people with identical height and weight but different trunk-to-leg length ratios have meaningfully different body compositions — and BMI treats them identically.

Mass Index (MI) attempts to correct this by adjusting the height component of BMI for sitting height, which captures how much of a person’s stature comes from their trunk versus their legs.


Why trunk-to-leg ratio matters

Consider two individuals:

  • Person A: 175cm tall, 70kg. Sitting height 90cm (trunk-heavy proportions).
  • Person B: 175cm tall, 70kg. Sitting height 84cm (longer legs relative to trunk).

Both have the same BMI: 70 / 1.75² = 22.9. But their bodies distribute mass differently. Person A’s larger trunk-to-leg ratio means more of their volume is in the abdomen and thorax — body regions with higher metabolic relevance. Person B’s mass is distributed more across leg length.

Research shows that individuals with higher trunk-to-leg ratios (higher sitting height proportion) tend to have higher visceral fat and metabolic risk at the same BMI. This pattern partly explains why East Asian populations — who have higher trunk-to-leg ratios than European populations on average — show elevated metabolic risk at lower BMIs.


The Mass Index formula

Mass Index, as proposed by Nevill et al. and subsequently explored in the literature, adjusts the height exponent based on the sitting height ratio:

Cormic Index = sitting_height / standing_height  (range: approximately 0.49–0.54)

Adjusted height exponent = 2 + k × (CI - CI_mean)

MI = weight / height^(adjusted_exponent)

Where k is a scaling factor derived from population data, and CI_mean is the mean Cormic Index for the reference population.

A simpler formulation that’s more practical for implementation:

def mass_index(
    weight_kg: float,
    standing_height_cm: float,
    sitting_height_cm: float
) -> dict:
    """
    Compute Mass Index adjusted for trunk-to-leg proportion.
    
    sitting_height_cm: height measured while seated, from seat to crown of head.
    
    Returns MI alongside BMI for comparison.
    """
    height_m = standing_height_cm / 100
    
    # Standard BMI
    bmi = weight_kg / (height_m ** 2)
    
    # Cormic Index: fraction of stature that is trunk
    cormic_index = sitting_height_cm / standing_height_cm
    
    # Reference Cormic Index (European adult population mean)
    # East Asian populations typically have CI ~ 0.535–0.545
    # European populations typically have CI ~ 0.520–0.530
    ci_reference = 0.526
    
    # Adjust height exponent
    # k derived from population studies; 4.0 is a commonly used value
    k = 4.0
    adjusted_exponent = 2.0 + k * (cormic_index - ci_reference)
    
    # Mass Index
    mi = weight_kg / (height_m ** adjusted_exponent)
    
    # Classification using MI thresholds
    # Note: MI thresholds are not as widely standardized as BMI thresholds
    if mi < 18.0:
        mi_category = "underweight"
    elif mi < 23.0:
        mi_category = "normal"
    elif mi < 27.5:
        mi_category = "overweight"
    else:
        mi_category = "obese"
    
    # For BMI, use standard thresholds for comparison
    if bmi < 18.5:
        bmi_category = "underweight"
    elif bmi < 25.0:
        bmi_category = "normal"
    elif bmi < 30.0:
        bmi_category = "overweight"
    else:
        bmi_category = "obese"
    
    return {
        "bmi": round(bmi, 1),
        "bmi_category": bmi_category,
        "mass_index": round(mi, 1),
        "mi_category": mi_category,
        "cormic_index": round(cormic_index, 3),
        "adjusted_height_exponent": round(adjusted_exponent, 3),
        "categories_agree": bmi_category == mi_category
    }

When categories disagree

The most interesting cases are where BMI and MI classify differently:

# Example: East Asian woman, higher Cormic Index
result_ea = mass_index(65, 160, 87)  # CI = 87/160 = 0.544
# BMI ≈ 25.4 → overweight
# MI adjusts for trunk-heavy: exponent ≈ 2.07 → MI ≈ 25.0 → borderline

# Example: European woman, lower Cormic Index
result_eu = mass_index(65, 160, 82)  # CI = 82/160 = 0.513
# BMI ≈ 25.4 → overweight (identical BMI)
# MI adjusts for more leg-length: exponent ≈ 1.95 → MI ≈ 25.9 → overweight

This illustrates why MI matters for global applications: the same BMI value represents different body compositions in individuals with different trunk-to-leg ratios, and MI attempts to surface that difference.


Getting sitting height from a prediction API

If users don’t know their sitting height — most people don’t — a body measurement prediction API can estimate it from standing height and weight.

Sitting height is a BONE dimension in ISO 7250-1 (dimension code 4.2.10, “sitting height”). It’s predicted with relatively high confidence from standing height, since trunk-to-leg ratio has a moderate correlation with total height (taller people tend to have slightly longer legs proportionally, though this varies by population).

import requests

def get_sitting_height_prediction(
    gender: str,
    standing_height_cm: float,
    weight_kg: float,
    region: str = "GLOBAL"
) -> dict:
    """
    Predict sitting height from standing height and weight.
    Sitting height allows computation of Mass Index.
    """
    response = requests.post(
        "https://dimensionspot-bodysize-engine.p.rapidapi.com/v1/predict",
        json={
            "input_data": {
                "input_unit_system": "metric",
                "subject": {
                    "gender": gender,
                    "input_origin_region": region
                },
                "anchors": {
                    "body_height": int(standing_height_cm * 10),  # cm → mm
                    "body_mass": weight_kg
                }
            },
            "output_settings": {
                "calculation": {"target_region": region, "body_build_type": "CIVILIAN"},
                "requested_dimensions": {
                    "specific_dimensions": ["sitting_height"]
                },
                "output_format": {
                    "include_range_95": True,
                    "confidence_score_threshold": 60,
                    "include_iso_codes": True
                }
            }
        },
        headers={
            "X-RapidAPI-Key": "YOUR_API_KEY",
            "X-RapidAPI-Host": "dimensionspot-bodysize-engine.p.rapidapi.com"
        }
    )
    data = response.json()
    
    dim = data.get("body_dimensions", {}).get("sitting_height")
    if dim:
            sitting_height_mm = dim["value"]
            sitting_height_cm = sitting_height_mm / 10
            range_95 = dim.get("range_95") or []
            
            return {
                "sitting_height_cm": round(sitting_height_cm, 1),
                "range_95_low_cm": round((range_95[0] if range_95 else sitting_height_mm - 25) / 10, 1),
                "range_95_high_cm": round((range_95[1] if range_95 else sitting_height_mm + 25) / 10, 1),
                "confidence_score": dim.get("confidence_score")
            }
    
    return None

def full_mass_index_from_height_weight(
    gender: str,
    standing_height_cm: float,
    weight_kg: float,
    region: str = "GLOBAL"
) -> dict:
    """
    Compute Mass Index using predicted sitting height.
    Includes uncertainty propagation from the sitting height prediction.
    """
    sitting = get_sitting_height_prediction(gender, standing_height_cm, weight_kg, region)
    
    if not sitting:
        # Fallback: use population-average Cormic Index for the region
        regional_ci = {
            "ASIA_PACIFIC": 0.540,
            "EUROPE": 0.526,
            "GLOBAL": 0.528
        }
        ci = regional_ci.get(region, 0.528)
        sitting_height_cm = standing_height_cm * ci
        mi_result = mass_index(weight_kg, standing_height_cm, sitting_height_cm)
        mi_result["sitting_height_source"] = "population_average"
        return mi_result
    
    # Compute MI with predicted sitting height
    mi_result = mass_index(weight_kg, standing_height_cm, sitting["sitting_height_cm"])
    
    # Also compute at bounds to show sensitivity
    mi_low = mass_index(weight_kg, standing_height_cm, sitting["range_95_low_cm"])
    mi_high = mass_index(weight_kg, standing_height_cm, sitting["range_95_high_cm"])
    
    mi_result["sitting_height_source"] = "predicted"
    mi_result["sitting_height_cm"] = sitting["sitting_height_cm"]
    mi_result["mi_sensitivity"] = {
        "at_p5_sitting_height": mi_low["mass_index"],
        "at_p95_sitting_height": mi_high["mass_index"],
        "note": "MI varies by ±{:.1f} across the 95% sitting height prediction interval".format(
            (mi_high["mass_index"] - mi_low["mass_index"]) / 2
        )
    }
    
    return mi_result

Limitations and appropriate use

Mass Index is not a clinical standard. BMI thresholds are embedded in clinical guidelines, electronic health records, and population databases accumulated over decades. Mass Index has no equivalent infrastructure.

Appropriate uses for MI in applications:

  • Research or analytics tools where you want to correct for proportional body differences across populations
  • Supplementary metric alongside BMI for users who have their sitting height measured
  • Educational context — explaining why BMI is imperfect and what alternatives look like

Inappropriate uses:

  • Replacing BMI in clinical decision contexts (no validated clinical thresholds)
  • Presenting MI as a clinical metric to users without a clear explanation that it’s not a standard measure
  • Using population-average Cormic Indices as if they were individual measurements (the correction is only meaningful when actual sitting height is measured)

Mass Index illustrates a broader principle in anthropometric computing: the best body composition metrics account for body proportions, not just weight-to-height ratios. For population-level analysis and research applications, incorporating trunk-to-leg ratio produces more biologically meaningful classifications than BMI alone — particularly for globally diverse populations.

Try DimensionsPot

Free tier — 100 requests/month, no credit card required.

Get API on RapidAPI