.. _Algebra:

Operator Algebra for Geometry Objects
======================================
Instances of classes :ref:`Point`, :ref:`IRect`, :ref:`Rect` and :ref:`Matrix` are collectively also called "geometry" objects.

They all are special cases of Python sequences, see :ref:`SequenceTypes` for more background.

We have defined operators for these classes that allow dealing with them (almost) like ordinary numbers in terms of addition, subtraction, multiplication, division, and some others.

This chapter is a synopsis of what is possible.

General Remarks
-----------------
1. Operators can be either **binary** (i.e. involving two objects) or **unary**.

2. The resulting type of **binary** operations is either a **new object** of the **left operand's class** or a bool.

3. The result of **unary** operations is either a **new object** of the same class, a bool or a float.

4. ``+, -, *, /`` are defined for all classes. They do what you would expect from them.

5. Rectangles have two additional binary operators: ``&`` (intersection) and ``|`` (union).

6. Binary operators fully support in-place operations: if ``"°"`` denotes any binary operator, then ``a °= b`` is the same as ``a = a ° b``.

7. For binary operations, the **second** operand may always be a number sequence of the same size as the left one. We allude to this fact by e.g. saying "x-like object" if a number sequence of same length as x is allowed.

Unary Operations
------------------

+---------+---------------------------------------------------------------+
|         | **Result**                                                    |
+=========+===============================================================+
| bool(O) | is false exactly if all components of "O" are zero.           |
+---------+---------------------------------------------------------------+
| abs(O)  | Euclidean norm (square root of the sum of component           |
|         | squares), if "O" is a :ref:`Point` or a :ref:`Matrix`.        |
|         | For rectangles, the area is returned.                         |
+---------+---------------------------------------------------------------+
| +O      | copy of "O".                                                  |
+---------+---------------------------------------------------------------+
| -O      | copy of "O" with negated components.                          |
+---------+---------------------------------------------------------------+
| ~m      | inverse of :ref:`Matrix` "m".                                 |
+---------+---------------------------------------------------------------+



Binary Operations
------------------
For every geometry object "a" and every number "b", the operations "a ° b" and "a °= b" are always defined if "°" is any of the operators ``+, -, *, /``. The respective operation is simply executed for each component of "a". If the second operand is **not a number**, then the following is defined:

+--------+---------------------------------------------------------------+
|        | **Result**                                                    |
+========+===============================================================+
| a+b,   | component-wise execution, "b" must be "a"-like.               |
| a-b    |                                                               |
+--------+---------------------------------------------------------------+
| a*m,   | "a" can be any geometry object and "m" must be matrix-like.   |
| a/m    | ``"a/m"`` is always treated as ``"a*~m"``.                    |
|        | If "a" is a **point** or a **rectangle**, then                |
|        | ``"a.transform(m)"`` is executed. If "a" is a matrix, then    |
|        | matrix concatenation takes place.                             |
+--------+---------------------------------------------------------------+
| a&b    | **intersection rectangle:** "a" must be a rectangle and       |
|        | "b" rect-like. Delivers the **largest rectangle**             |
|        | contained in both operands.                                   |
+--------+---------------------------------------------------------------+
| a|b    | **union rectangle:** "a" must be a rectangle, and "b"         |
|        | may be point-like or rect-like.                               |
|        | Delivers the **smallest rectangle** containing both operands. |
+--------+---------------------------------------------------------------+
| b in a | if "b" is a number, then ``"b in tuple(a)"`` is returned.     |
|        | If "b" is point-like or rect-like, then "a" must be a         |
|        | rectangle, and ``"a.contains(b)"`` is returned.               |
+--------+---------------------------------------------------------------+
| a==b   | ``True`` if ``bool(a-b)`` is ``False`` ("b" may be "a"-like). |
+--------+---------------------------------------------------------------+
