Skip to main content

A Python toolkit for angular range operations supporting intersection, union, and difference operations on angular intervals

Project description

Angular Range Operations (角度区间操作工具)

简体中文 | English

简体中文

一个用于处理角度区间运算的Python工具库,支持角度区间(0-360度)的交集、并集、差集等操作。

功能特性

  • ✅ 支持多个区间的交集、并集、差集运算
  • ✅ 自动处理跨越0/360度边界的区间
  • ✅ 基于扫描线算法,高效处理任意数量的区间
  • ✅ 提供覆盖矩阵分析功能
  • ✅ 支持区间排列组合和效率评估

模块说明

ops.py - 核心区间操作模块(推荐使用)

提供了改进的区间操作算法,支持多个区间的运算。 核心算法思想

  1. 收集所有区间的起止点作为分界点
  2. 将分界点归一化到[0, 360)范围
  3. 用分界点将[0, 360)分割成多个子区间
  4. 构建覆盖矩阵:子区间中点 × 原始区间 → 0/1矩阵
  5. 根据矩阵模式计算交集、并集、差集 主要函数
  • intersection() - 多区间交集
  • union() - 多区间并集
  • difference() - 区间差集
  • build_coverage_matrix() - 构建覆盖矩阵

安装

从 PyPI 安装(推荐)

pip install angular_range_ops

从源码安装

# 克隆或下载项目
git clone <repository-url>
cd angular_range_ops
# 安装
pip install .
# 或者以开发模式安装
pip install -e .

要求:Python 3.9+,无需额外依赖

快速开始

基本用法

from angular_range_ops import intersection, union, difference
# 示例1: 计算多个区间的交集
ranges = [[10, 100], [50, 120], [80, 150]]
result = intersection(ranges)
print(f"交集: {result}")
# 输出: 交集: [[80, 100]]
# 示例2: 计算多个区间的并集
ranges = [[10, 50], [100, 150], [30, 120]]
result = union(ranges)
print(f"并集: {result}")
# 输出: 并集: [[10, 150]]
# 示例3: 计算区间差集
base = [0, 360]
subtract = [[10, 50], [100, 150], [200, 250]]
result = difference(base, subtract)
print(f"差集: {result}")
# 输出: 差集: [[0, 10], [50, 100], [150, 200], [250, 360]]

处理跨越0/360度边界的区间

# 示例4: 跨界区间的交集
# [350, 370] 表示从350度到10度(跨越0度)
ranges = [[350, 370], [340, 380]]
result = intersection(ranges)
print(f"交集: {result}")
# 输出: 交集: [[0, 10], [350, 360]]
# 示例5: 跨界区间的并集
ranges = [[350, 370], [10, 30]]
result = union(ranges)
print(f"并集: {result}")
# 输出: 并集: [[0, 30], [350, 360]]
# 示例6: 从完整圆中减去跨界区间
base = [0, 360]
subtract = [[350, 370], [100, 150]]
result = difference(base, subtract)
print(f"差集: {result}")
# 输出: 差集: [[10, 100], [150, 350]]

使用覆盖矩阵分析区间关系

from angular_range_ops import build_coverage_matrix
# 构建覆盖矩阵
ranges = [[10, 100], [50, 150], [200, 250]]
sub_ranges, matrix = build_coverage_matrix(ranges)
print("覆盖矩阵分析:")
for i, (sr, row) in enumerate(zip(sub_ranges, matrix)):
    print(f"子区间 {sr}: {row}")
# 输出:
# 子区间 [0, 10]: [0, 0, 0]      # 盲区
# 子区间 [10, 50]: [1, 0, 0]     # 只被区间1覆盖
# 子区间 [50, 100]: [1, 1, 0]    # 被区间1和2覆盖
# 子区间 [100, 150]: [0, 1, 0]   # 只被区间2覆盖
# 子区间 [150, 200]: [0, 0, 0]   # 盲区
# 子区间 [200, 250]: [0, 0, 1]   # 只被区间3覆盖
# 子区间 [250, 360]: [0, 0, 0]   # 盲区

API 文档

intersection(ranges: List[List[float]]) -> List[List[float]]

计算多个区间的交集。 参数

  • ranges: 区间列表,每个区间格式为 [start, end],单位为度 返回
  • 交集区间列表 示例
ranges = [[10, 100], [50, 120], [80, 150]]
result = intersection(ranges)
# 返回: [[80, 100]]

union(ranges: List[List[float]]) -> List[List[float]]

计算多个区间的并集。 参数

  • ranges: 区间列表,每个区间格式为 [start, end],单位为度 返回
  • 并集区间列表 示例
ranges = [[10, 50], [100, 150], [30, 120]]
result = union(ranges)
# 返回: [[10, 150]]

difference(base_range: List[float], subtract_ranges: List[List[float]]) -> List[List[float]]

计算区间差集:base_range - union(subtract_ranges)。 参数

  • base_range: 基础区间 [start, end]
  • subtract_ranges: 要减去的区间列表 返回
  • 差集区间列表 示例
base = [0, 360]
subtract = [[10, 50], [100, 150]]
result = difference(base, subtract)
# 返回: [[0, 10], [50, 100], [150, 360]]

build_coverage_matrix(ranges: List[List[float]]) -> Tuple[List[List[float]], List[List[int]]]

构建覆盖矩阵,用于分析区间覆盖关系。 参数

  • ranges: 输入区间列表 返回
  • (sub_ranges, matrix) 元组
    • sub_ranges: 分割后的子区间列表
    • matrix: 覆盖矩阵,matrix[i][j] = 1 表示子区间i的中点在原始区间j内 示例
ranges = [[10, 100], [50, 150]]
sub_ranges, matrix = build_coverage_matrix(ranges)
# sub_ranges: [[0, 10], [10, 50], [50, 100], [100, 150], [150, 360]]
# matrix: [[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]

注意事项

  1. 角度范围:所有角度单位为度(0-360),内部会自动处理归一化
  2. 跨界区间:区间 [350, 370] 表示从350度到10度,会自动分割为 [350, 360][0, 10]
  3. 空区间:长度为0的区间(如 [10, 10])会被自动过滤
  4. 完整覆盖:长度 >= 360度的区间会被视为完整圆 [0, 360]
  5. 浮点精度:内部使用 EPSILON = 1e-9 处理浮点数比较

作者

wangheng

许可证

MIT License - 详见 LICENSE 文件

English

A Python toolkit for angular range operations, supporting intersection, union, and difference operations on angular intervals (0-360 degrees).

Features

  • ✅ Support intersection, union, and difference operations on multiple ranges
  • ✅ Automatic handling of ranges crossing 0/360 degree boundaries
  • ✅ Efficient processing of arbitrary number of ranges using sweep line algorithm
  • ✅ Coverage matrix analysis functionality
  • ✅ Support for range permutation and efficiency evaluation

Module Description

ops.py - Core Range Operation Module (Recommended)

Provides improved range operation algorithms supporting operations on multiple ranges. Core Algorithm Concept:

  1. Collect start and end points of all ranges as boundary points
  2. Normalize boundary points to [0, 360) range
  3. Partition [0, 360) into multiple sub-ranges using boundary points
  4. Build coverage matrix: sub-range midpoints × original ranges → 0/1 matrix
  5. Calculate intersection, union, and difference based on matrix patterns Main Functions:
  • intersection() - Multiple range intersection
  • union() - Multiple range union
  • difference() - Range difference
  • build_coverage_matrix() - Build coverage matrix

Installation

Install from PyPI (Recommended)

pip install angular_range_ops

Install from Source

# Clone or download the project
git clone <repository-url>
cd angular_range_ops
# Install
pip install .
# Or install in development mode
pip install -e .

Requirements: Python 3.9+, no additional dependencies

Quick Start

Basic Usage

from angular_range_ops import intersection, union, difference
# Example 1: Calculate intersection of multiple ranges
ranges = [[10, 100], [50, 120], [80, 150]]
result = intersection(ranges)
print(f"Intersection: {result}")
# Output: Intersection: [[80, 100]]
# Example 2: Calculate union of multiple ranges
ranges = [[10, 50], [100, 150], [30, 120]]
result = union(ranges)
print(f"Union: {result}")
# Output: Union: [[10, 150]]
# Example 3: Calculate range difference
base = [0, 360]
subtract = [[10, 50], [100, 150], [200, 250]]
result = difference(base, subtract)
print(f"Difference: {result}")
# Output: Difference: [[0, 10], [50, 100], [150, 200], [250, 360]]

Handling Ranges Crossing 0/360 Degree Boundaries

# Example 4: Intersection of boundary-crossing ranges
# [350, 370] represents a range from 350 degrees to 10 degrees (crossing 0)
ranges = [[350, 370], [340, 380]]
result = intersection(ranges)
print(f"Intersection: {result}")
# Output: Intersection: [[0, 10], [350, 360]]
# Example 5: Union of boundary-crossing ranges
ranges = [[350, 370], [10, 30]]
result = union(ranges)
print(f"Union: {result}")
# Output: Union: [[0, 30], [350, 360]]
# Example 6: Subtract boundary-crossing range from complete circle
base = [0, 360]
subtract = [[350, 370], [100, 150]]
result = difference(base, subtract)
print(f"Difference: {result}")
# Output: Difference: [[10, 100], [150, 350]]

Using Coverage Matrix for Range Relationship Analysis

from angular_range_ops import build_coverage_matrix
# Build coverage matrix
ranges = [[10, 100], [50, 150], [200, 250]]
sub_ranges, matrix = build_coverage_matrix(ranges)
print("Coverage matrix analysis:")
for i, (sr, row) in enumerate(zip(sub_ranges, matrix)):
    print(f"Sub-range {sr}: {row}")
# Output:
# Sub-range [0, 10]: [0, 0, 0]      # Blind spot
# Sub-range [10, 50]: [1, 0, 0]     # Covered only by range 1
# Sub-range [50, 100]: [1, 1, 0]    # Covered by ranges 1 and 2
# Sub-range [100, 150]: [0, 1, 0]   # Covered only by range 2
# Sub-range [150, 200]: [0, 0, 0]   # Blind spot
# Sub-range [200, 250]: [0, 0, 1]   # Covered only by range 3
# Sub-range [250, 360]: [0, 0, 0]   # Blind spot

API Documentation

intersection(ranges: List[List[float]]) -> List[List[float]]

Calculate the intersection of multiple ranges. Parameters:

  • ranges: List of ranges, each range in format [start, end], unit in degrees Returns:
  • List of intersection ranges Example:
ranges = [[10, 100], [50, 120], [80, 150]]
result = intersection(ranges)
# Returns: [[80, 100]]

union(ranges: List[List[float]]) -> List[List[float]]

Calculate the union of multiple ranges. Parameters:

  • ranges: List of ranges, each range in format [start, end], unit in degrees Returns:
  • List of union ranges Example:
ranges = [[10, 50], [100, 150], [30, 120]]
result = union(ranges)
# Returns: [[10, 150]]

difference(base_range: List[float], subtract_ranges: List[List[float]]) -> List[List[float]]

Calculate range difference: base_range - union(subtract_ranges). Parameters:

  • base_range: Base range [start, end]
  • subtract_ranges: List of ranges to subtract Returns:
  • List of difference ranges Example:
base = [0, 360]
subtract = [[10, 50], [100, 150]]
result = difference(base, subtract)
# Returns: [[0, 10], [50, 100], [150, 360]]

build_coverage_matrix(ranges: List[List[float]]) -> Tuple[List[List[float]], List[List[int]]]

Build coverage matrix for analyzing range coverage relationships. Parameters:

  • ranges: List of input ranges Returns:
  • Tuple (sub_ranges, matrix)
    • sub_ranges: List of partitioned sub-ranges
    • matrix: Coverage matrix, matrix[i][j] = 1 means sub-range i's midpoint is in original range j Example:
ranges = [[10, 100], [50, 150]]
sub_ranges, matrix = build_coverage_matrix(ranges)
# sub_ranges: [[0, 10], [10, 50], [50, 100], [100, 150], [150, 360]]
# matrix: [[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]

Notes

  1. Angular Range: All angles are in degrees (0-360), internally normalized automatically
  2. Boundary-Crossing Ranges: Range [350, 370] represents from 350 to 10 degrees, auto-partitioned to [350, 360] and [0, 10]
  3. Empty Ranges: Zero-length ranges (e.g., [10, 10]) are automatically filtered
  4. Complete Coverage: Ranges with length >= 360 degrees are treated as complete circle [0, 360]
  5. Floating-Point Precision: Internal use of EPSILON = 1e-9 for floating-point comparison

Author

wangheng

License

MIT License - see LICENSE file for details

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

angular_range_ops-0.1.0.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

angular_range_ops-0.1.0-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

File details

Details for the file angular_range_ops-0.1.0.tar.gz.

File metadata

  • Download URL: angular_range_ops-0.1.0.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for angular_range_ops-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e83824982ddb33e5d0aa2970224f9b8e2a22ba20355b2848bfb1b370118e2c0b
MD5 c4619a8a3bd754ae84e8ebecbceb3514
BLAKE2b-256 08ddcb9971c1c8812cbbd90d1e29217a6ecc998cd26b906685fc78d4d140baf6

See more details on using hashes here.

File details

Details for the file angular_range_ops-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for angular_range_ops-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bbf94daab6d1a7d1b081ed7b66e67e29509c5cc45bb798dc1069cd26a9962d74
MD5 c3c3dd5b4075a3ba126f1eae074b8273
BLAKE2b-256 29eb3c3cf7640f427b1d2b7523a2a4f33914ad787e6931eee423a480ca05bb78

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page