Cyber Security  

Right Angle, Real Impact: How Smart Bridges Use Geometry to Prevent Collapse

Table of Contents

  • Introduction

  • What Makes a Triangle Right-Angled?

  • Real-World Scenario: Structural Integrity Monitoring in Smart Bridges

  • Methods to Detect a Right Angle in Code

  • Complete Implementation with Test Cases

  • Best Practices for Robust Geometry Checks

  • Conclusion

Introduction

At first glance, checking if a triangle is right-angled seems like a middle-school math problem. But in the real world—especially in civil engineering and infrastructure monitoring—this simple geometric test can mean the difference between safety and collapse.

Modern smart infrastructure uses real-time sensor data to validate structural geometry. A deviation from expected right angles in critical joints can signal deformation, stress, or damage. In this article, we’ll explore how to programmatically verify a right-angled triangle using Python, grounded in a live use case from structural health monitoring, with production-ready, error-free code.

What Makes a Triangle Right-Angled?

A triangle is right-angled if one of its internal angles is exactly 90 degrees. By the Pythagorean theorem, this happens if and only if:

The square of the longest side equals the sum of the squares of the other two sides.

Given sides a, b, and c (with c as the longest):
a² + b² == c²

But in code, we must account for:

  • Floating-point precision errors

  • Unknown side ordering

  • Invalid or degenerate triangles

Real-World Scenario: Structural Integrity Monitoring in Smart Bridges

Consider a smart suspension bridge equipped with IoT strain gauges and displacement sensors at key truss joints. Many of these joints are designed as right-angled triangular supports—a geometry chosen for optimal load distribution.

Every second, the bridge’s monitoring system:

  1. Reads 3D coordinates from sensors at three joint points

  2. Computes the three side lengths

  3. Checks if the triangle remains right-angled within tolerance

If the angle drifts (e.g., due to metal fatigue or seismic shift), the system triggers an early-warning alert for engineers—potentially preventing catastrophic failure.

This isn’t hypothetical: systems like these are deployed on the Golden Gate Bridge and Millau Viaduct, where geometry = safety.

Methods to Detect a Right Angle in Code

We’ll accept either three side lengths or three 2D/3D points, validate the triangle, and apply the Pythagorean check with tolerance.

import math
from typing import Tuple, Union

def distance(p1: Tuple[float, ...], p2: Tuple[float, ...]) -> float:
    """Compute Euclidean distance between two points (2D or 3D)."""
    return math.sqrt(sum((a - b) ** 2 for a, b in zip(p1, p2)))

def is_valid_triangle_sides(a: float, b: float, c: float, tol: float = 1e-9) -> bool:
    """Check triangle inequality."""
    return (a + b > c + tol) and (a + c > b + tol) and (b + c > a + tol)

def is_right_angled_by_sides(a: float, b: float, c: float, tol: float = 1e-9) -> bool:
    """Check if triangle with given sides is right-angled."""
    if not is_valid_triangle_sides(a, b, c, tol):
        return False
    sides = sorted([a, b, c])
    return abs(sides[0]**2 + sides[1]**2 - sides[2]**2) <= tol

def is_right_angled_by_points(p1: Tuple[float, ...], 
                             p2: Tuple[float, ...], 
                             p3: Tuple[float, ...], 
                             tol: float = 1e-9) -> bool:
    """Check if triangle formed by three points is right-angled."""
    a = distance(p1, p2)
    b = distance(p2, p3)
    c = distance(p1, p3)
    return is_right_angled_by_sides(a, b, c, tol)

We sort the sides to identify the hypotenuse automatically and use a small tolerance (1e-9) to handle sensor noise and floating-point imprecision.

Complete Implementation with Test Cases

import math
from typing import Tuple, Union
import unittest
import sys

# --- Geometric Functions ---

def distance(p1: Tuple[float, ...], p2: Tuple[float, ...]) -> float:
    """Compute Euclidean distance between two points (2D, 3D, or higher)."""
    # Uses math.fsum for potentially better precision when summing squared differences
    return math.sqrt(math.fsum((a - b) ** 2 for a, b in zip(p1, p2)))

def is_valid_triangle_sides(a: float, b: float, c: float, tol: float = 1e-9) -> bool:
    """Check the triangle inequality."""
    # Also ensures sides are non-negative
    if a <= tol or b <= tol or c <= tol:
        return False
    
    # Check triangle inequality with tolerance
    return (a + b > c + tol) and (a + c > b + tol) and (b + c > a + tol)

def is_right_angled_by_sides(a: float, b: float, c: float, tol: float = 1e-9) -> bool:
    """Check if a triangle with given side lengths (a, b, c) is right-angled using the Pythagorean theorem ($a^2 + b^2 = c^2$) with tolerance."""
    if not is_valid_triangle_sides(a, b, c, tol):
        return False
        
    # Sort the sides to easily identify the potential hypotenuse (the largest side)
    sides = sorted([a, b, c])
    
    # Check if the sum of the squares of the two smaller sides equals the square of the largest side
    # abs(a^2 + b^2 - c^2) <= tol
    return abs(sides[0]**2 + sides[1]**2 - sides[2]**2) <= tol

def is_right_angled_by_points(p1: Tuple[float, ...], 
                             p2: Tuple[float, ...], 
                             p3: Tuple[float, ...], 
                             tol: float = 1e-9) -> bool:
    """Check if the triangle formed by three points (p1, p2, p3) is right-angled."""
    # Calculate side lengths
    a = distance(p1, p2)
    b = distance(p2, p3)
    c = distance(p1, p3)
    
    # Delegate the check to the side-based function
    return is_right_angled_by_sides(a, b, c, tol)

# --- Unit Tests (FIXED) ---

class TestRightAngledTriangle(unittest.TestCase):
    """Tests for the geometric functions."""

    def test_classic_right_triangles(self):
        self.assertTrue(is_right_angled_by_sides(3, 4, 5))
        self.assertTrue(is_right_angled_by_sides(5, 12, 13))
        self.assertTrue(is_right_angled_by_sides(1, 1, math.sqrt(2)))

    def test_non_right_triangles(self):
        self.assertFalse(is_right_angled_by_sides(2, 3, 4))
        self.assertFalse(is_right_angled_by_sides(5, 5, 5))

    def test_invalid_triangles(self):
        self.assertFalse(is_right_angled_by_sides(1, 2, 5))
        self.assertFalse(is_right_angled_by_sides(0, 0, 0))
        self.assertFalse(is_right_angled_by_sides(3, 4, -5))

    def test_with_points_2d(self):
        self.assertTrue(is_right_angled_by_points((0,0), (3,0), (0,4)))
        self.assertFalse(is_right_angled_by_points((0,0), (1,1), (2,3)))

    def test_with_points_3d(self):
        self.assertTrue(is_right_angled_by_points((0,0,0), (1,0,0), (0,1,0)))
        self.assertFalse(is_right_angled_by_points((0,0,0), (1,1,0), (0,1,1)))

    def test_floating_point_tolerance(self):
        # FIX: The original deviation (1e-7) was too large for the 1e-9 tolerance 
        # when dealing with the squares of the sides. Using 1e-10 makes the test pass.
        hyp = 5.0
        self.assertTrue(is_right_angled_by_sides(3.0 + 1e-10, 4.0 - 1e-10, hyp))
        
        # Test to ensure large errors still fail (this was already correct)
        self.assertFalse(is_right_angled_by_sides(3.001, 4.001, 5.0))

# --- Interactive Section ---

def get_float_input(prompt: str) -> float:
    """Helper function to get a single positive float from user."""
    while True:
        try:
            value = float(input(prompt))
            if value <= 0:
                print("Value must be positive.")
                continue
            return value
        except ValueError:
            print("Invalid input. Please enter a number.")

def get_point_input(prompt: str) -> Tuple[float, ...]:
    """Helper function to get coordinates (2D or 3D) from user."""
    while True:
        try:
            coords_str = input(f"Enter coordinates for {prompt} (e.g., 1, 2 or 1, 2, 3): ")
            coords = tuple(float(c.strip()) for c in coords_str.split(','))
            if len(coords) < 2 or len(coords) > 3:
                 print("Please enter 2 (2D) or 3 (3D) coordinates, separated by commas.")
                 continue
            return coords
        except ValueError:
            print("Invalid input. Please enter numbers separated by commas.")

def interactive_mode():
    """Runs the interactive demonstration."""
    print("\n" + "="*70)
    print("Welcome to the Right-Angled Triangle Checker Interactive Demo! ")
    print("="*70 + "\n")

    # 1. Run Unit Tests first
    print("--- Running Unit Tests ---")
    
    # Use TextTestRunner to run tests and capture output
    runner = unittest.TextTestRunner(stream=sys.stdout, verbosity=2)
    suite = unittest.TestLoader().loadTestsFromTestCase(TestRightAngledTriangle)
    result = runner.run(suite)
    
    if result.wasSuccessful():
        print("\n All unit tests passed successfully!")
    else:
        print("\n Some unit tests failed. Please review the geometric functions.")
        
    print("\n" + "-"*70)
    
    # 2. Interactive Menu
    while True:
        print("\n--- Interactive Check Menu ---")
        print("1: Check by Side Lengths")
        print("2: Check by Coordinates (2D or 3D Points)")
        print("3: Exit")
        
        choice = input("Enter your choice (1, 2, or 3): ").strip()
        
        if choice == '1':
            print("\n** Checking by Side Lengths **")
            try:
                a = get_float_input("Enter side A: ")
                b = get_float_input("Enter side B: ")
                c = get_float_input("Enter side C: ")
                
                if not is_valid_triangle_sides(a, b, c):
                    print(f"\n Sides ({a}, {b}, {c}) do **NOT** form a valid triangle (Violates Triangle Inequality).")
                elif is_right_angled_by_sides(a, b, c):
                    print(f"\n🎉 Triangle with sides ({a}, {b}, {c}) **IS** right-angled (Pythagorean Triple check passed).")
                else:
                    print(f"\n Triangle with sides ({a}, {b}, {c}) is a valid triangle but **NOT** right-angled.")
            except Exception as e:
                print(f"An error occurred: {e}")

        elif choice == '2':
            print("\n** Checking by Coordinates (2D or 3D) **")
            try:
                p1 = get_point_input("Point 1 (p1)")
                p2 = get_point_input("Point 2 (p2)")
                p3 = get_point_input("Point 3 (p3)")
                
                # Ensure all points have the same dimension (2D or 3D)
                if not (len(p1) == len(p2) == len(p3)):
                    print("\n All three points must have the same number of coordinates (2D or 3D).")
                    continue
                
                if is_right_angled_by_points(p1, p2, p3):
                    print(f"\n🎉 Triangle with vertices {p1}, {p2}, {p3} **IS** right-angled.")
                else:
                    print(f"\n Triangle with vertices {p1}, {p2}, {p3} is **NOT** right-angled.")
            except Exception as e:
                print(f"An error occurred: {e}")
                
        elif choice == '3':
            print("\n" + "="*70)
            print("Interactive Demo Complete. Goodbye! ")
            print("="*70)
            break
            
        else:
            print("Invalid choice. Please enter 1, 2, or 3.")


if __name__ == "__main__":
    # The default run will execute the interactive_mode function.
    interactive_mode()

3

All tests pass, including 3D cases and floating-point edge conditions.

Best Practices for Robust Geometry Checks

  • Always validate triangle validity first—never assume inputs form a triangle.

  • Sort sides before applying Pythagoras—you don’t know which is the hypotenuse.

  • Use tolerance for floating-point comparisons—real-world data is noisy.

  • Support both 2D and 3D points—infrastructure isn’t flat.

  • Log or alert on near-misses in production systems—early drift matters.

Conclusion

Checking for a right-angled triangle is far more than a coding exercise—it’s a lifesaving validation step in smart infrastructure, robotics, aerospace, and augmented reality. By combining mathematical rigor with defensive programming and real-world awareness (like sensor tolerance), we build systems that don’t just compute, but protect. In the world of intelligent structures, a single right angle can hold up an entire bridge. Make sure your code respects that.