def METHOD_NAME(self, other: "DirectionWithSpeed", deviation: float = 0.1) -> bool:
    if not 0.0 <= deviation <= 1.0:
        raise ValueError("Invalid deviation passed")
    def check_matching_directions() -> bool:
        for s, o in [
            (self.direction.x, other.direction.x),
            (self.direction.y, other.direction.y),
            (self.direction.z, other.direction.z),
        ]:
            if s < 0 < o:
                return False
            elif o < 0 < s:
                return False
        return True
    if not check_matching_directions():
        return False
    def get_hypotenuse(d: Direction) -> float:
        # c side of right triangle
        return math.sqrt(d.x**2 + d.y**2 + d.z**2)
    # Scale direction based on x
    self_scale = 1.0
    if self.direction.x != 0.0:
        other_scale = other.direction.x / self.direction.x
    elif self.direction.y != 0.0:
        other_scale = other.direction.y / self.direction.y
    elif self.direction.z != 0.0:
        other_scale = other.direction.z / self.direction.z
    else:
        raise InvalidDirection(f"{self.direction}")
    def get_normalized_direction_by_scale(d: Direction, scale: float) -> Direction:
        return Direction(d.x / scale, d.y / scale, d.z / scale)
    self_n_d = get_normalized_direction_by_scale(self.direction, self_scale)
    other_n_d = get_normalized_direction_by_scale(other.direction, other_scale)
    self_c = get_hypotenuse(self_n_d)
    other_c = get_hypotenuse(other_n_d)
    # check if same direction
    if other_c * (1.0 - deviation) < self_c < other_c / (1.0 - deviation):
        if self.speed > other.speed:
            return True
    return False