collide 0.4.0

Simple extensible collision management
Documentation
# Collide

[![crates.io](https://img.shields.io/crates/v/collide)](https://crates.io/crates/collide) 
[![docs.rs](https://img.shields.io/docsrs/collide)](https://docs.rs/collide)

A generic trait system for collision detection in Rust. Implement collision checks between arbitrary shapes while maintaining flexibility for the vector type.

## Features

- 🧩 Generic `Collider` trait for cross-library interoperability
- 📐 Compatible with any vector types
- 🚀 Supports 2D/3D/N-D collisions
- 🔄 Bidirectional collision data with automatic perspective flipping

## Example

```rust
use std::ops::{Add, Mul, Neg, Sub};

use collide::{Collider, CollisionInfo};

#[derive(Copy, Clone, Debug, PartialEq)]
struct Vec2(f32, f32);

impl Add for Vec2 {
    type Output = Self;
    fn add(self, rhs: Self) -> Self {
        Vec2(self.0 + rhs.0, self.1 + rhs.1)
    }
}
impl Sub for Vec2 {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self {
        Vec2(self.0 - rhs.0, self.1 - rhs.1)
    }
}
impl Mul<f32> for Vec2 {
    type Output = Self;
    fn mul(self, rhs: f32) -> Self {
        Vec2(self.0 * rhs, self.1 * rhs)
    }
}
impl Neg for Vec2 {
    type Output = Self;
    fn neg(self) -> Self {
        Vec2(-self.0, -self.1)
    }
}
impl Vec2 {
    fn magnitude(self) -> f32 {
        f32::sqrt(self.0 * self.0 + self.1 * self.1)
    }
    fn normalize(self) -> Self {
        let mag = self.magnitude();
        if mag == 0.0 { self } else { self * (1.0 / mag) }
    }
}

struct Sphere {
    center: Vec2,
    radius: f32,
}

impl Collider for Sphere {
    type Vector = Vec2;

    fn collision_info(&self, other: &Self) -> Option<CollisionInfo<Vec2>> {
        let delta = other.center - self.center;
        let distance = delta.magnitude();
        if distance > self.radius + other.radius || distance == 0.0 {
            return None;
        }
        let direction = delta.normalize();
        let min_distance = self.radius + other.radius;
        Some(CollisionInfo {
            self_contact: self.center + direction * self.radius,
            other_contact: other.center - direction * other.radius,
            vector: direction * (min_distance - distance),
        })
    }
}

let s1 = Sphere {
    center: Vec2(0.0, 0.0),
    radius: 1.0,
};
let s2 = Sphere {
    center: Vec2(1.5, 0.0),
    radius: 1.0,
};
assert!(s1.check_collision(&s2));
```

## Design Goals

1. **Interoperability**: Share colliders across physics engines
2. **Flexibility**: Arbitrary dimensions (2D, 3D, etc.) and number types (f32, f64, etc.)
3. **Extensibility**: New collider types without breaking existing implementations