~ubuntu-branches/ubuntu/feisty/fonttools/feisty

« back to all changes in this revision

Viewing changes to Lib/fontTools/misc/arrayTools.py

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Fok
  • Date: 2003-11-18 00:53:59 UTC
  • Revision ID: james.westby@ubuntu.com-20031118005359-pqirsxbgdz0f0xmx
Tags: upstream-1.99+2.0b1+cvs20031014
ImportĀ upstreamĀ versionĀ 1.99+2.0b1+cvs20031014

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Various array and rectangle tools, but mostly rectangles, hence the
 
3
# name of this module (not).
 
4
#
 
5
 
 
6
 
 
7
def calcBounds(array):
 
8
        """Return the bounding rectangle of a 2D points array as a tuple:
 
9
        (xMin, yMin, xMax, yMax)
 
10
        """
 
11
        import Numeric
 
12
        if len(array) == 0:
 
13
                return 0, 0, 0, 0
 
14
        xMin, yMin = Numeric.minimum.reduce(array)
 
15
        xMax, yMax = Numeric.maximum.reduce(array)
 
16
        return xMin, yMin, xMax, yMax
 
17
 
 
18
def updateBounds(bounds, (x, y), min=min, max=max):
 
19
        """Return the bounding recangle of rectangle bounds and point (x, y)."""
 
20
        xMin, yMin, xMax, yMax = bounds
 
21
        return min(xMin, x), min(yMin, y), max(xMax, x), max(yMax, y)
 
22
 
 
23
def pointInRect((x, y), rect):
 
24
        """Return True when point (x, y) is inside rect."""
 
25
        xMin, yMin, xMax, yMax = rect
 
26
        return (xMin <= x <= xMax) and (yMin <= y <= yMax)
 
27
 
 
28
def pointsInRect(array, rect):
 
29
        """Find out which points or array are inside rect. 
 
30
        Returns an array with a boolean for each point.
 
31
        """
 
32
        import Numeric
 
33
        if len(array) < 1:
 
34
                return []
 
35
        lefttop = rect[:2]
 
36
        rightbottom = rect[2:]
 
37
        condition = Numeric.logical_and(
 
38
                        Numeric.greater_equal(array, lefttop), 
 
39
                        Numeric.less_equal(array, rightbottom))
 
40
        return Numeric.logical_and.reduce(condition, -1)
 
41
 
 
42
def vectorLength(vector):
 
43
        """Return the length of the given vector."""
 
44
        import Numeric
 
45
        return Numeric.sqrt(vector[0]**2 + vector[1]**2)
 
46
 
 
47
def asInt16(array):
 
48
        """Round and cast to 16 bit integer."""
 
49
        import Numeric
 
50
        return Numeric.floor(array + 0.5).astype(Numeric.Int16)
 
51
        
 
52
 
 
53
def normRect((xMin, yMin, xMax, yMax)):
 
54
        """Normalize the rectangle so that the following holds:
 
55
                xMin <= xMax and yMin <= yMax
 
56
        """
 
57
        return min(xMin, xMax), min(yMin, yMax), max(xMin, xMax), max(yMin, yMax)
 
58
 
 
59
def scaleRect((xMin, yMin, xMax, yMax), x, y):
 
60
        """Scale the rectangle by x, y."""
 
61
        return xMin * x, yMin * y, xMax * x, yMax * y
 
62
 
 
63
def offsetRect((xMin, yMin, xMax, yMax), dx, dy):
 
64
        """Offset the rectangle by dx, dy."""
 
65
        return xMin+dx, yMin+dy, xMax+dx, yMax+dy
 
66
 
 
67
def insetRect((xMin, yMin, xMax, yMax), dx, dy):
 
68
        """Inset the rectangle by dx, dy on all sides."""
 
69
        return xMin+dx, yMin+dy, xMax-dx, yMax-dy
 
70
 
 
71
def sectRect((xMin1, yMin1, xMax1, yMax1), (xMin2, yMin2, xMax2, yMax2)):
 
72
        """Return a boolean and a rectangle. If the input rectangles intersect, return
 
73
        True and the intersecting rectangle. Return False and (0, 0, 0, 0) if the input
 
74
        rectangles don't intersect.
 
75
        """
 
76
        xMin, yMin, xMax, yMax = (max(xMin1, xMin2), max(yMin1, yMin2),
 
77
                                  min(xMax1, xMax2), min(yMax1, yMax2))
 
78
        if xMin >= xMax or yMin >= yMax:
 
79
                return 0, (0, 0, 0, 0)
 
80
        return 1, (xMin, yMin, xMax, yMax)
 
81
 
 
82
def unionRect((xMin1, yMin1, xMax1, yMax1), (xMin2, yMin2, xMax2, yMax2)):
 
83
        """Return the smallest rectangle in which both input rectangles are fully
 
84
        enclosed. In other words, return the total bounding rectangle of both input
 
85
        rectangles.
 
86
        """
 
87
        xMin, yMin, xMax, yMax = (min(xMin1, xMin2), min(yMin1, yMin2),
 
88
                                  max(xMax1, xMax2), max(yMax1, yMax2))
 
89
        return (xMin, yMin, xMax, yMax)
 
90
 
 
91
def rectCenter((xMin, yMin, xMax, yMax)):
 
92
        """Return the center of the rectangle as an (x, y) coordinate."""
 
93
        return (xMin+xMax)/2, (yMin+yMax)/2
 
94
 
 
95
def intRect((xMin, yMin, xMax, yMax)):
 
96
        """Return the rectangle, rounded off to integer values, but guaranteeing that
 
97
        the resulting rectangle is NOT smaller than the original.
 
98
        """
 
99
        import math
 
100
        xMin = int(math.floor(xMin))
 
101
        yMin = int(math.floor(yMin))
 
102
        xMax = int(math.ceil(xMax))
 
103
        yMax = int(math.ceil(yMax))
 
104
        return (xMin, yMin, xMax, yMax)
 
105
 
 
106
 
 
107
if __name__ == "__main__":
 
108
        import Numeric, math
 
109
        assert calcBounds([(0, 40), (0, 100), (50, 50), (80, 10)]) == (0, 10, 80, 100)
 
110
        assert updateBounds((0, 0, 0, 0), (100, 100)) == (0, 0, 100, 100)
 
111
        assert pointInRect((50, 50), (0, 0, 100, 100))
 
112
        assert pointInRect((0, 0), (0, 0, 100, 100))
 
113
        assert pointInRect((100, 100), (0, 0, 100, 100))
 
114
        assert not pointInRect((101, 100), (0, 0, 100, 100))
 
115
        assert list(pointsInRect([(50, 50), (0, 0), (100, 100), (101, 100)],
 
116
                        (0, 0, 100, 100))) == [1, 1, 1, 0]
 
117
        assert vectorLength((3, 4)) == 5
 
118
        assert vectorLength((1, 1)) == math.sqrt(2)
 
119
        assert list(asInt16(Numeric.array([0, 0.1, 0.5, 0.9]))) == [0, 0, 1, 1]
 
120
        assert normRect((0, 10, 100, 200)) == (0, 10, 100, 200)
 
121
        assert normRect((100, 200, 0, 10)) == (0, 10, 100, 200)
 
122
        assert scaleRect((10, 20, 50, 150), 1.5, 2) == (15, 40, 75, 300)
 
123
        assert offsetRect((10, 20, 30, 40), 5, 6) == ((15, 26, 35, 46))
 
124
        assert insetRect((10, 20, 50, 60), 5, 10) == (15, 30, 45, 50)
 
125
        assert insetRect((10, 20, 50, 60), -5, -10) == (5, 10, 55, 70)
 
126
        intersects, rect = sectRect((0, 10, 20, 30), (0, 40, 20, 50))
 
127
        assert not intersects
 
128
        intersects, rect = sectRect((0, 10, 20, 30), (5, 20, 35, 50))
 
129
        assert intersects
 
130
        assert rect == (5, 20, 20, 30)
 
131
        assert unionRect((0, 10, 20, 30), (0, 40, 20, 50)) == (0, 10, 20, 50)
 
132
        assert rectCenter((0, 0, 100, 200)) == (50, 100)
 
133
        assert rectCenter((0, 0, 100, 199.0)) == (50, 99.5)
 
134
        assert intRect((0.9, 2.9, 3.1, 4.1)) == (0, 2, 4, 5)