agt 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.md +7 -0
- data/README.md +5 -0
- data/app/assets/javascripts/agt/config.coffee +9 -0
- data/app/assets/javascripts/agt/dom.coffee +12 -0
- data/app/assets/javascripts/agt/function.coffee +317 -0
- data/app/assets/javascripts/agt/geom/circle.coffee +338 -0
- data/app/assets/javascripts/agt/geom/cubic_bezier.coffee +37 -0
- data/app/assets/javascripts/agt/geom/diamond.coffee +241 -0
- data/app/assets/javascripts/agt/geom/ellipsis.coffee +141 -0
- data/app/assets/javascripts/agt/geom/linear_spline.coffee +56 -0
- data/app/assets/javascripts/agt/geom/matrix.coffee +240 -0
- data/app/assets/javascripts/agt/geom/mixins/geometry.coffee +171 -0
- data/app/assets/javascripts/agt/geom/mixins/intersections.coffee +150 -0
- data/app/assets/javascripts/agt/geom/mixins/path.coffee +145 -0
- data/app/assets/javascripts/agt/geom/mixins/proxyable.coffee +9 -0
- data/app/assets/javascripts/agt/geom/mixins/spline.coffee +329 -0
- data/app/assets/javascripts/agt/geom/mixins/surface.coffee +55 -0
- data/app/assets/javascripts/agt/geom/mixins/triangulable.coffee +112 -0
- data/app/assets/javascripts/agt/geom/point.coffee +454 -0
- data/app/assets/javascripts/agt/geom/polygon.coffee +119 -0
- data/app/assets/javascripts/agt/geom/quad_bezier.coffee +43 -0
- data/app/assets/javascripts/agt/geom/quint_bezier.coffee +42 -0
- data/app/assets/javascripts/agt/geom/rectangle.coffee +599 -0
- data/app/assets/javascripts/agt/geom/spiral.coffee +90 -0
- data/app/assets/javascripts/agt/geom/transformation_proxy.coffee +43 -0
- data/app/assets/javascripts/agt/geom/triangle.coffee +442 -0
- data/app/assets/javascripts/agt/impulse.coffee +105 -0
- data/app/assets/javascripts/agt/index.coffee +56 -0
- data/app/assets/javascripts/agt/inflector/inflection.coffee +21 -0
- data/app/assets/javascripts/agt/inflector/inflections.coffee +75 -0
- data/app/assets/javascripts/agt/inflector/inflector.coffee +235 -0
- data/app/assets/javascripts/agt/inheritance.coffee +132 -0
- data/app/assets/javascripts/agt/math.coffee +45 -0
- data/app/assets/javascripts/agt/mixins/activable.coffee +31 -0
- data/app/assets/javascripts/agt/mixins/aliasable.coffee +25 -0
- data/app/assets/javascripts/agt/mixins/alternate_case.coffee +72 -0
- data/app/assets/javascripts/agt/mixins/cloneable.coffee +71 -0
- data/app/assets/javascripts/agt/mixins/delegation.coffee +90 -0
- data/app/assets/javascripts/agt/mixins/disposable.coffee +7 -0
- data/app/assets/javascripts/agt/mixins/equatable.coffee +37 -0
- data/app/assets/javascripts/agt/mixins/formattable.coffee +52 -0
- data/app/assets/javascripts/agt/mixins/globalizable.coffee +175 -0
- data/app/assets/javascripts/agt/mixins/has_ancestors.coffee +47 -0
- data/app/assets/javascripts/agt/mixins/has_collection.coffee +107 -0
- data/app/assets/javascripts/agt/mixins/has_nested_collection.coffee +51 -0
- data/app/assets/javascripts/agt/mixins/memoizable.coffee +64 -0
- data/app/assets/javascripts/agt/mixins/parameterizable.coffee +101 -0
- data/app/assets/javascripts/agt/mixins/poolable.coffee +62 -0
- data/app/assets/javascripts/agt/mixins/sourcable.coffee +45 -0
- data/app/assets/javascripts/agt/mixins/state_machine.coffee +47 -0
- data/app/assets/javascripts/agt/net/router.coffee +165 -0
- data/app/assets/javascripts/agt/object.coffee +9 -0
- data/app/assets/javascripts/agt/particles/actions/base_action.coffee +7 -0
- data/app/assets/javascripts/agt/particles/actions/die_on_surface.coffee +14 -0
- data/app/assets/javascripts/agt/particles/actions/force.coffee +11 -0
- data/app/assets/javascripts/agt/particles/actions/friction.coffee +14 -0
- data/app/assets/javascripts/agt/particles/actions/live.coffee +9 -0
- data/app/assets/javascripts/agt/particles/actions/macro_action.coffee +13 -0
- data/app/assets/javascripts/agt/particles/actions/move.coffee +11 -0
- data/app/assets/javascripts/agt/particles/actions/null_action.coffee +9 -0
- data/app/assets/javascripts/agt/particles/counters/by_rate.coffee +17 -0
- data/app/assets/javascripts/agt/particles/counters/fixed.coffee +9 -0
- data/app/assets/javascripts/agt/particles/counters/null_counter.coffee +9 -0
- data/app/assets/javascripts/agt/particles/emission.coffee +35 -0
- data/app/assets/javascripts/agt/particles/emitters/null_emitter.coffee +7 -0
- data/app/assets/javascripts/agt/particles/emitters/path.coffee +10 -0
- data/app/assets/javascripts/agt/particles/emitters/ponctual.coffee +9 -0
- data/app/assets/javascripts/agt/particles/emitters/surface.coffee +10 -0
- data/app/assets/javascripts/agt/particles/initializers/explosion.coffee +19 -0
- data/app/assets/javascripts/agt/particles/initializers/life.coffee +16 -0
- data/app/assets/javascripts/agt/particles/initializers/macro_initializer.coffee +10 -0
- data/app/assets/javascripts/agt/particles/initializers/null_initializer.coffee +7 -0
- data/app/assets/javascripts/agt/particles/initializers/particle_sub_system.coffee +12 -0
- data/app/assets/javascripts/agt/particles/initializers/stream.coffee +20 -0
- data/app/assets/javascripts/agt/particles/mixins/randomizable.coffee +10 -0
- data/app/assets/javascripts/agt/particles/particle.coffee +32 -0
- data/app/assets/javascripts/agt/particles/sub_system.coffee +11 -0
- data/app/assets/javascripts/agt/particles/system.coffee +103 -0
- data/app/assets/javascripts/agt/particles/timers/instant.coffee +11 -0
- data/app/assets/javascripts/agt/particles/timers/limited.coffee +19 -0
- data/app/assets/javascripts/agt/particles/timers/null_timer.coffee +11 -0
- data/app/assets/javascripts/agt/particles/timers/unlimited.coffee +9 -0
- data/app/assets/javascripts/agt/particles/timers/until_death.coffee +11 -0
- data/app/assets/javascripts/agt/promise.coffee +214 -0
- data/app/assets/javascripts/agt/random/random.coffee +100 -0
- data/app/assets/javascripts/agt/random/seeds/lagged_fibonnacci.coffee +53 -0
- data/app/assets/javascripts/agt/random/seeds/linear.coffee +16 -0
- data/app/assets/javascripts/agt/random/seeds/linear_congruential.coffee +23 -0
- data/app/assets/javascripts/agt/random/seeds/math_random.coffee +9 -0
- data/app/assets/javascripts/agt/random/seeds/mersenne_twister.coffee +42 -0
- data/app/assets/javascripts/agt/random/seeds/no_random.coffee +12 -0
- data/app/assets/javascripts/agt/random/seeds/paul_houle.coffee +19 -0
- data/app/assets/javascripts/agt/signal.coffee +272 -0
- data/app/assets/javascripts/agt/sprites/animation.coffee +13 -0
- data/app/assets/javascripts/agt/sprites/sprite.coffee +30 -0
- data/app/assets/javascripts/agt/widgets/hash.coffee +36 -0
- data/app/assets/javascripts/agt/widgets/widgets.coffee +194 -0
- data/app/assets/javascripts/agt/widgets/widgets/checked_input.coffee +7 -0
- data/app/assets/javascripts/agt/widgets/widgets/focus_bubbling.coffee +15 -0
- data/lib/agt.rb +8 -0
- data/lib/agt/version.rb +5 -0
- metadata +173 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
namespace('agt.geom')
|
|
2
|
+
|
|
3
|
+
# Public:
|
|
4
|
+
class agt.geom.Polygon
|
|
5
|
+
@extend agt.mixins.Aliasable
|
|
6
|
+
|
|
7
|
+
@include agt.mixins.Formattable('Polygon', 'vertices')
|
|
8
|
+
@include agt.mixins.Sourcable('agt.geom.Polygon', 'vertices')
|
|
9
|
+
@include agt.mixins.Cloneable()
|
|
10
|
+
@include agt.geom.Geometry
|
|
11
|
+
@include agt.geom.Intersections
|
|
12
|
+
@include agt.geom.Triangulable
|
|
13
|
+
@include agt.geom.Surface
|
|
14
|
+
@include agt.geom.Path
|
|
15
|
+
|
|
16
|
+
### Public ###
|
|
17
|
+
|
|
18
|
+
@polygonFrom: (vertices) ->
|
|
19
|
+
if vertices? and typeof vertices is 'object'
|
|
20
|
+
isArray = Object::toString.call(vertices).indexOf('Array') isnt -1
|
|
21
|
+
return vertices unless isArray
|
|
22
|
+
{vertices}
|
|
23
|
+
else
|
|
24
|
+
vertices: null
|
|
25
|
+
|
|
26
|
+
constructor: (vertices) ->
|
|
27
|
+
{vertices} = @polygonFrom vertices
|
|
28
|
+
|
|
29
|
+
@noVertices() unless vertices?
|
|
30
|
+
@notEnougthVertices vertices if vertices.length < 3
|
|
31
|
+
@vertices = vertices
|
|
32
|
+
|
|
33
|
+
center: ->
|
|
34
|
+
x = y = 0
|
|
35
|
+
|
|
36
|
+
for vertex in @vertices
|
|
37
|
+
x += vertex.x
|
|
38
|
+
y += vertex.y
|
|
39
|
+
|
|
40
|
+
x = x / @vertices.length
|
|
41
|
+
y = y / @vertices.length
|
|
42
|
+
|
|
43
|
+
new agt.geom.Point x, y
|
|
44
|
+
|
|
45
|
+
translate: (x,y) ->
|
|
46
|
+
{x,y} = agt.geom.Point.pointFrom x,y
|
|
47
|
+
for vertex in @vertices
|
|
48
|
+
vertex.x += x
|
|
49
|
+
vertex.y += y
|
|
50
|
+
this
|
|
51
|
+
|
|
52
|
+
rotate: (rotation) ->
|
|
53
|
+
center = @center()
|
|
54
|
+
for vertex,i in @vertices
|
|
55
|
+
@vertices[i] = vertex.rotateAround center, rotation
|
|
56
|
+
this
|
|
57
|
+
|
|
58
|
+
@alias 'rotate', 'rotateAroundCenter'
|
|
59
|
+
|
|
60
|
+
scale: (scale) ->
|
|
61
|
+
center = @center()
|
|
62
|
+
for vertex,i in @vertices
|
|
63
|
+
@vertices[i] = center.add vertex.subtract(center).scale(scale)
|
|
64
|
+
this
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@alias 'scale', 'scaleAroundCenter'
|
|
68
|
+
|
|
69
|
+
points: ->
|
|
70
|
+
(vertex.clone() for vertex in @vertices).concat(@vertices[0].clone())
|
|
71
|
+
|
|
72
|
+
closedGeometry: -> true
|
|
73
|
+
|
|
74
|
+
pointAtAngle: (angle) ->
|
|
75
|
+
center = @center()
|
|
76
|
+
distance = (a,b) -> a.distance(center) - b.distance(center)
|
|
77
|
+
vec = center.add Math.cos(angle)*10000,
|
|
78
|
+
Math.sin(angle)*10000
|
|
79
|
+
@intersections(points: -> [center, vec])?.sort(distance)[0]
|
|
80
|
+
|
|
81
|
+
acreage: ->
|
|
82
|
+
acreage = 0
|
|
83
|
+
acreage += tri.acreage() for tri in @triangles()
|
|
84
|
+
acreage
|
|
85
|
+
|
|
86
|
+
contains: (x,y) ->
|
|
87
|
+
return true for tri in @triangles() when tri.contains x,y
|
|
88
|
+
false
|
|
89
|
+
|
|
90
|
+
randomPointInSurface: (random) ->
|
|
91
|
+
unless random?
|
|
92
|
+
random = new agt.random.Random new agt.random.MathRandom
|
|
93
|
+
|
|
94
|
+
acreage = @acreage()
|
|
95
|
+
triangles = @triangles()
|
|
96
|
+
ratios = triangles.map (t, i) -> t.acreage() / acreage
|
|
97
|
+
ratios[i] += ratios[i-1] for n,i in ratios when i > 0
|
|
98
|
+
|
|
99
|
+
random.inArray(triangles, ratios, true).randomPointInSurface random
|
|
100
|
+
|
|
101
|
+
length: ->
|
|
102
|
+
length = 0
|
|
103
|
+
points = @points()
|
|
104
|
+
for i in [1..points.length-1]
|
|
105
|
+
length += points[i-1].distance(points[i])
|
|
106
|
+
length
|
|
107
|
+
|
|
108
|
+
memoizationKey: -> @vertices.map((pt) -> "#{pt.x},#{pt.y}").join ";"
|
|
109
|
+
|
|
110
|
+
### Internal ###
|
|
111
|
+
|
|
112
|
+
polygonFrom: Polygon.polygonFrom
|
|
113
|
+
|
|
114
|
+
noVertices: ->
|
|
115
|
+
throw new Error 'No vertices provided to Polygon'
|
|
116
|
+
|
|
117
|
+
notEnougthVertices: (vertices) ->
|
|
118
|
+
length = vertices.length
|
|
119
|
+
throw new Error "Polygon must have at least 3 vertices, was #{length}"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
namespace('agt.geom')
|
|
2
|
+
|
|
3
|
+
# Public:
|
|
4
|
+
#
|
|
5
|
+
# ### Included Mixins
|
|
6
|
+
#
|
|
7
|
+
# - {agt.geom.Geometry}
|
|
8
|
+
# - {agt.geom.Intersections}
|
|
9
|
+
# - {agt.geom.Path}
|
|
10
|
+
# - [agt.mixins.Spline](../../../files/geom/mixins/spline.coffee.html)
|
|
11
|
+
# - [agt.mixins.Formattable](../../../files/mixins/formattable.coffee.html)
|
|
12
|
+
# - [agt.mixins.Memoizable](../../../files/mixins/memoizable.coffee.html)
|
|
13
|
+
# - [agt.mixins.Sourcable](../../../files/mixins/sourcable.coffee.html)
|
|
14
|
+
class agt.geom.QuadBezier
|
|
15
|
+
@include agt.mixins.Formattable('QuadBezier')
|
|
16
|
+
@include agt.mixins.Sourcable('agt.geom.QuadBezier', 'vertices', 'bias')
|
|
17
|
+
@include agt.geom.Geometry
|
|
18
|
+
@include agt.geom.Path
|
|
19
|
+
@include agt.geom.Intersections
|
|
20
|
+
@include agt.geom.Spline(2)
|
|
21
|
+
|
|
22
|
+
### Public ###
|
|
23
|
+
|
|
24
|
+
constructor: (vertices, bias=20) ->
|
|
25
|
+
@initSpline vertices, bias
|
|
26
|
+
|
|
27
|
+
pointInSegment: (t, seg) ->
|
|
28
|
+
pt = new agt.geom.Point()
|
|
29
|
+
pt.x = (seg[0].x * @b1 (t)) +
|
|
30
|
+
(seg[1].x * @b2 (t)) +
|
|
31
|
+
(seg[2].x * @b3 (t))
|
|
32
|
+
pt.y = (seg[0].y * @b1 (t)) +
|
|
33
|
+
(seg[1].y * @b2 (t)) +
|
|
34
|
+
(seg[2].y * @b3 (t))
|
|
35
|
+
pt
|
|
36
|
+
|
|
37
|
+
### Internal ###
|
|
38
|
+
|
|
39
|
+
b1: (t) -> ((1 - t) * (1 - t) )
|
|
40
|
+
|
|
41
|
+
b2: (t) -> (2 * t * (1 - t))
|
|
42
|
+
|
|
43
|
+
b3: (t) -> (t * t)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
namespace('agt.geom')
|
|
3
|
+
|
|
4
|
+
# Public:
|
|
5
|
+
class agt.geom.QuintBezier
|
|
6
|
+
@include agt.mixins.Formattable('QuintBezier')
|
|
7
|
+
@include agt.mixins.Sourcable('agt.geom.QuintBezier', 'vertices', 'bias')
|
|
8
|
+
@include agt.geom.Geometry
|
|
9
|
+
@include agt.geom.Path
|
|
10
|
+
@include agt.geom.Intersections
|
|
11
|
+
@include agt.geom.Spline(4)
|
|
12
|
+
|
|
13
|
+
### Public ###
|
|
14
|
+
|
|
15
|
+
constructor: (vertices, bias=20) ->
|
|
16
|
+
@initSpline vertices, bias
|
|
17
|
+
|
|
18
|
+
pointInSegment: (t, seg) ->
|
|
19
|
+
pt = new agt.geom.Point()
|
|
20
|
+
pt.x = (seg[0].x * @b1 (t)) +
|
|
21
|
+
(seg[1].x * @b2 (t)) +
|
|
22
|
+
(seg[2].x * @b3 (t)) +
|
|
23
|
+
(seg[3].x * @b4 (t)) +
|
|
24
|
+
(seg[4].x * @b5 (t))
|
|
25
|
+
pt.y = (seg[0].y * @b1 (t)) +
|
|
26
|
+
(seg[1].y * @b2 (t)) +
|
|
27
|
+
(seg[2].y * @b3 (t)) +
|
|
28
|
+
(seg[3].y * @b4 (t)) +
|
|
29
|
+
(seg[4].y * @b5 (t))
|
|
30
|
+
pt
|
|
31
|
+
|
|
32
|
+
### Internal ###
|
|
33
|
+
|
|
34
|
+
b1: (t) -> ((1 - t) * (1 - t) * (1 - t) * (1 - t))
|
|
35
|
+
|
|
36
|
+
b2: (t) -> (4 * t * (1 - t) * (1 - t) * (1 - t))
|
|
37
|
+
|
|
38
|
+
b3: (t) -> (6 * t * t * (1 - t) * (1 - t))
|
|
39
|
+
|
|
40
|
+
b4: (t) -> (4 * t * t * t * (1 - t))
|
|
41
|
+
|
|
42
|
+
b5: (t) -> (t * t * t * t)
|
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
|
|
2
|
+
namespace('agt.geom')
|
|
3
|
+
|
|
4
|
+
# Public: A `Rectangle` geometry is defined with a position, a size
|
|
5
|
+
# and a rotation.
|
|
6
|
+
#
|
|
7
|
+
# ```coffeescript
|
|
8
|
+
# rectangle = new Rectangle 20, 20, 80, 40, Math.PI * 0.1
|
|
9
|
+
# rectangle = new Rectangle x: 20, y: 20, width: 80, height: 40, rotation: Math.PI * 0.1
|
|
10
|
+
# ```
|
|
11
|
+
#
|
|
12
|
+
# <script>window.exampleKey = 'rectangle'</script>
|
|
13
|
+
# <script>drawGeometry(exampleKey, {highlight: true})</script>
|
|
14
|
+
#
|
|
15
|
+
# ### Included Mixins
|
|
16
|
+
#
|
|
17
|
+
# - {agt.geom.Geometry}
|
|
18
|
+
# - {agt.geom.Intersections}
|
|
19
|
+
# - {agt.geom.Path}
|
|
20
|
+
# - {agt.geom.Surface}
|
|
21
|
+
# - {agt.mixins.Aliasable}
|
|
22
|
+
# - [agt.mixins.Cloneable](../../../files/mixins/cloneable.coffee.html)
|
|
23
|
+
# - [agt.mixins.Equatable](../../../files/mixins/equatable.coffee.html)
|
|
24
|
+
# - [agt.mixins.Formattable](../../../files/mixins/formattable.coffee.html)
|
|
25
|
+
# - [agt.mixins.Memoizable](../../../files/mixins/memoizable.coffee.html)
|
|
26
|
+
# - [agt.mixins.Parameterizable](../../../files/mixins/parameterizable.coffee.html)
|
|
27
|
+
# - [agt.mixins.Sourcable](../../../files/mixins/sourcable.coffee.html)
|
|
28
|
+
class agt.geom.Rectangle
|
|
29
|
+
properties = ['x','y','width','height','rotation']
|
|
30
|
+
|
|
31
|
+
@extend agt.mixins.Aliasable
|
|
32
|
+
|
|
33
|
+
@include agt.mixins.Cloneable()
|
|
34
|
+
@include agt.mixins.Equatable.apply(null, properties)
|
|
35
|
+
@include agt.mixins.Formattable.apply(null, ['Rectangle'].concat properties)
|
|
36
|
+
@include agt.mixins.Sourcable.apply(null, ['agt.geom.Rectangle'].concat properties)
|
|
37
|
+
@include agt.mixins.Parameterizable('rectangleFrom', {
|
|
38
|
+
x: NaN
|
|
39
|
+
y: NaN
|
|
40
|
+
width: NaN
|
|
41
|
+
height: NaN
|
|
42
|
+
rotation: NaN
|
|
43
|
+
})
|
|
44
|
+
@include agt.geom.Geometry
|
|
45
|
+
@include agt.geom.Surface
|
|
46
|
+
@include agt.geom.Path
|
|
47
|
+
@include agt.geom.Triangulable
|
|
48
|
+
@include agt.geom.Proxyable
|
|
49
|
+
@include agt.geom.Intersections
|
|
50
|
+
|
|
51
|
+
### Public ###
|
|
52
|
+
|
|
53
|
+
# A specific intersection algorithm when confronting two rectangles.
|
|
54
|
+
#
|
|
55
|
+
# <script>drawShapeIntersections(exampleKey, exampleKey)</script>
|
|
56
|
+
#
|
|
57
|
+
# geom1 - The first rectangle.
|
|
58
|
+
# geom2 - The second rectangle.
|
|
59
|
+
# block - The callback {Function} to call for each intersection.
|
|
60
|
+
# data - A {Boolean} of whether to include extra data per intersection.
|
|
61
|
+
@eachRectangleRectangleIntersections: (geom1, geom2, block, data=false) ->
|
|
62
|
+
if geom1.equals geom2
|
|
63
|
+
for p in geom1.points()
|
|
64
|
+
return if block.call this, p
|
|
65
|
+
else
|
|
66
|
+
@eachIntersections geom1, geom2, block, data
|
|
67
|
+
|
|
68
|
+
# Registers the fast intersections iterators for the Rectangle class
|
|
69
|
+
iterators = agt.geom.Intersections.iterators
|
|
70
|
+
k = 'RectangleRectangle'
|
|
71
|
+
iterators[k] = Rectangle.eachRectangleRectangleIntersections
|
|
72
|
+
|
|
73
|
+
# Creates a new `Rectangle` instance.
|
|
74
|
+
#
|
|
75
|
+
# x - The x coordinate {Number} of the rectangle or a rectangle-like {Object}.
|
|
76
|
+
# y - The y coordinate {Number} of the rectangle.
|
|
77
|
+
# width - The width {Number} of the rectangle.
|
|
78
|
+
# height - The height {Number} of the rectangle.
|
|
79
|
+
# rotation - The rotation {Number} of the rectangle.
|
|
80
|
+
constructor: (x, y, width, height, rotation) ->
|
|
81
|
+
args = @defaultToZero @rectangleFrom.apply this, arguments
|
|
82
|
+
{@x,@y,@width,@height,@rotation} = args
|
|
83
|
+
|
|
84
|
+
# Returns the coordinates of the rectangle's corners in an {Array}.
|
|
85
|
+
#
|
|
86
|
+
# <script>drawGeometryPoints(exampleKey, 'corners')</script>
|
|
87
|
+
#
|
|
88
|
+
# Returns an {Array}.
|
|
89
|
+
corners: -> [@topLeft(), @topRight(), @bottomRight(), @bottomLeft()]
|
|
90
|
+
|
|
91
|
+
# Returns the coordinates of the top left corner of the rectangle.
|
|
92
|
+
#
|
|
93
|
+
# <script>drawGeometryPoints(exampleKey, 'topLeft')</script>
|
|
94
|
+
#
|
|
95
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
96
|
+
topLeft: -> new agt.geom.Point(@x, @y)
|
|
97
|
+
|
|
98
|
+
# Returns the coordinates of the top right corner of the rectangle.
|
|
99
|
+
#
|
|
100
|
+
# <script>drawGeometryPoints(exampleKey, 'topRight')</script>
|
|
101
|
+
#
|
|
102
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
103
|
+
topRight: -> @topLeft().add(@topEdge())
|
|
104
|
+
|
|
105
|
+
# Returns the coordinates of the bottom left corner of the rectangle.
|
|
106
|
+
#
|
|
107
|
+
# <script>drawGeometryPoints(exampleKey, 'bottomLeft')</script>
|
|
108
|
+
#
|
|
109
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
110
|
+
bottomLeft: -> @topLeft().add(@leftEdge())
|
|
111
|
+
|
|
112
|
+
# Returns the coordinates of the bottom right corner of the rectangle.
|
|
113
|
+
#
|
|
114
|
+
# <script>drawGeometryPoints(exampleKey, 'bottomRight')</script>
|
|
115
|
+
#
|
|
116
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
117
|
+
bottomRight: -> @topLeft().add(@topEdge()).add(@leftEdge())
|
|
118
|
+
|
|
119
|
+
# Returns the coordinates of the center of the rectangle.
|
|
120
|
+
#
|
|
121
|
+
# <script>drawGeometry(exampleKey, {center: true})</script>
|
|
122
|
+
#
|
|
123
|
+
# Returns a [Point]{agt.geom.Point}
|
|
124
|
+
center: -> @topLeft().add(@diagonal().scale(0.5))
|
|
125
|
+
|
|
126
|
+
# Returns the coordinates of the center of the upper edge of the rectangle.
|
|
127
|
+
#
|
|
128
|
+
# <script>drawGeometryPoints(exampleKey, 'topEdgeCenter')</script>
|
|
129
|
+
#
|
|
130
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
131
|
+
topEdgeCenter: -> @topLeft().add(@topEdge().scale(0.5))
|
|
132
|
+
|
|
133
|
+
# Returns the coordinates of the center of the bottom edge of the rectangle.
|
|
134
|
+
#
|
|
135
|
+
# <script>drawGeometryPoints(exampleKey, 'bottomEdgeCenter')</script>
|
|
136
|
+
#
|
|
137
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
138
|
+
bottomEdgeCenter: -> @bottomLeft().add(@topEdge().scale(0.5))
|
|
139
|
+
|
|
140
|
+
# Returns the coordinates of the center of the left edge of the rectangle.
|
|
141
|
+
#
|
|
142
|
+
# <script>drawGeometryPoints(exampleKey, 'leftEdgeCenter')</script>
|
|
143
|
+
#
|
|
144
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
145
|
+
leftEdgeCenter: -> @topLeft().add(@leftEdge().scale(0.5))
|
|
146
|
+
|
|
147
|
+
# Returns the coordinates of the center of the right edge of the rectangle.
|
|
148
|
+
#
|
|
149
|
+
# <script>drawGeometryPoints(exampleKey, 'rightEdgeCenter')</script>
|
|
150
|
+
#
|
|
151
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
152
|
+
rightEdgeCenter: -> @topRight().add(@leftEdge().scale(0.5))
|
|
153
|
+
|
|
154
|
+
# Returns an array containing all the rectangle's edges vectors.
|
|
155
|
+
#
|
|
156
|
+
# Returns an {Array}.
|
|
157
|
+
edges: -> [@topEdge(), @topRight(), @bottomRight(), @bottomLeft()]
|
|
158
|
+
|
|
159
|
+
# Returns the rectangle's top edge vector.
|
|
160
|
+
#
|
|
161
|
+
# <script>drawGeometryEdge(exampleKey, 'topLeft', 'topEdge')</script>
|
|
162
|
+
#
|
|
163
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
164
|
+
topEdge: -> new agt.geom.Point @width * Math.cos(@rotation),
|
|
165
|
+
@width * Math.sin(@rotation)
|
|
166
|
+
|
|
167
|
+
# Returns the rectangle's left edge vector.
|
|
168
|
+
#
|
|
169
|
+
# <script>drawGeometryEdge(exampleKey, 'topLeft', 'leftEdge')</script>
|
|
170
|
+
#
|
|
171
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
172
|
+
leftEdge: ->
|
|
173
|
+
new agt.geom.Point @height * Math.cos(@rotation + Math.PI / 2),
|
|
174
|
+
@height * Math.sin(@rotation + Math.PI / 2)
|
|
175
|
+
|
|
176
|
+
# Returns the rectangle's bottom edge vector.
|
|
177
|
+
#
|
|
178
|
+
# <script>drawGeometryEdge(exampleKey, 'bottomLeft', 'bottomEdge')</script>
|
|
179
|
+
#
|
|
180
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
181
|
+
bottomEdge: -> @topEdge()
|
|
182
|
+
|
|
183
|
+
# Returns the rectangle's right edge vector.
|
|
184
|
+
#
|
|
185
|
+
# <script>drawGeometryEdge(exampleKey, 'topRight', 'rightEdge')</script>
|
|
186
|
+
#
|
|
187
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
188
|
+
rightEdge: -> @leftEdge()
|
|
189
|
+
|
|
190
|
+
# Returns the rectangle's diagonal vector.
|
|
191
|
+
#
|
|
192
|
+
# <script>drawGeometryEdge(exampleKey, 'topLeft', 'diagonal')</script>
|
|
193
|
+
#
|
|
194
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
195
|
+
diagonal: -> @leftEdge().add(@topEdge())
|
|
196
|
+
|
|
197
|
+
# Returns the top-most coordinate of the rectangle shape.
|
|
198
|
+
#
|
|
199
|
+
# <script>drawGeometryBound(exampleKey, 'top')</script>
|
|
200
|
+
#
|
|
201
|
+
# Returns a {Number}.
|
|
202
|
+
top: -> Math.min @y, @topRight().y, @bottomRight().y, @bottomLeft().y
|
|
203
|
+
|
|
204
|
+
# Returns the bottom-most coordinate of the rectangle shape.
|
|
205
|
+
#
|
|
206
|
+
# <script>drawGeometryBound(exampleKey, 'bottom')</script>
|
|
207
|
+
#
|
|
208
|
+
# Returns a {Number}.
|
|
209
|
+
bottom: -> Math.max @y, @topRight().y, @bottomRight().y, @bottomLeft().y
|
|
210
|
+
|
|
211
|
+
# Returns the left-most coordinate of the rectangle shape.
|
|
212
|
+
#
|
|
213
|
+
# <script>drawGeometryBound(exampleKey, 'left')</script>
|
|
214
|
+
#
|
|
215
|
+
# Returns a {Number}.
|
|
216
|
+
left: -> Math.min @x, @topRight().x, @bottomRight().x, @bottomLeft().x
|
|
217
|
+
|
|
218
|
+
# Returns the right-most coordinate of the rectangle shape.
|
|
219
|
+
#
|
|
220
|
+
# <script>drawGeometryBound(exampleKey, 'right')</script>
|
|
221
|
+
#
|
|
222
|
+
# Returns a {Number}.
|
|
223
|
+
right: -> Math.max @x, @topRight().x, @bottomRight().x, @bottomLeft().x
|
|
224
|
+
|
|
225
|
+
# Sets the position of the rectangle using its center as reference.
|
|
226
|
+
#
|
|
227
|
+
# <script>drawTransform(exampleKey, {type: 'setCenter', args: [100, 50], width: 150})</script>
|
|
228
|
+
#
|
|
229
|
+
# x - A {Number} for the x coordinate or a point-like {Object}.
|
|
230
|
+
# y - A {Number} for the y coordinate if the first argument
|
|
231
|
+
# was also a number.
|
|
232
|
+
#
|
|
233
|
+
# Returns this [Rectangle]{agt.geom.Rectangle}.
|
|
234
|
+
setCenter: (x, y) ->
|
|
235
|
+
pt = agt.geom.Point.pointFrom(x, y).subtract(@center())
|
|
236
|
+
|
|
237
|
+
@x += pt.x
|
|
238
|
+
@y += pt.y
|
|
239
|
+
this
|
|
240
|
+
|
|
241
|
+
# Adds the passed-in [Point]{agt.geom.Point} to the position
|
|
242
|
+
# of this rectangle.
|
|
243
|
+
#
|
|
244
|
+
# <script>drawTransform(exampleKey, {type: 'translate', args: [50, 0], width: 150})</script>
|
|
245
|
+
#
|
|
246
|
+
# x - A {Number} for the x coordinate or a point-like {Object}.
|
|
247
|
+
# y - A {Number} for the y coordinate if the first argument
|
|
248
|
+
# was also a number.
|
|
249
|
+
#
|
|
250
|
+
# Returns this {Rectangle}.
|
|
251
|
+
translate: (x, y) ->
|
|
252
|
+
pt = agt.geom.Point.pointFrom(x, y)
|
|
253
|
+
|
|
254
|
+
@x += pt.x
|
|
255
|
+
@y += pt.y
|
|
256
|
+
this
|
|
257
|
+
|
|
258
|
+
# Adds the passed-in rotation to the current rectangle rotation.
|
|
259
|
+
#
|
|
260
|
+
# <script>drawTransform(exampleKey, {type: 'rotate', args: [-Math.PI/ 4]})</script>
|
|
261
|
+
#
|
|
262
|
+
# **Note:** This method is also aliased as `rotateAroundCenter`.
|
|
263
|
+
#
|
|
264
|
+
# rotation - The rotation {Number}.
|
|
265
|
+
#
|
|
266
|
+
# Returns this {Rectangle}.
|
|
267
|
+
rotate: (rotation) ->
|
|
268
|
+
{@x,@y} = @topLeft().rotateAround(@center(), rotation)
|
|
269
|
+
@rotation += rotation
|
|
270
|
+
this
|
|
271
|
+
|
|
272
|
+
@alias 'rotate', 'rotateAroundCenter'
|
|
273
|
+
|
|
274
|
+
# Scales the rectangle by multiplying its width and height by the passed-in
|
|
275
|
+
# scale factor. The scaling is performed from the center of the rectangle,
|
|
276
|
+
# which imply changing the rectangle position.
|
|
277
|
+
# You can use the `width` and `height` property to change the size of the
|
|
278
|
+
# rectangle without affecting the position.
|
|
279
|
+
#
|
|
280
|
+
# <script>drawTransform(exampleKey, {type: 'scale', args: [0.6]})</script>
|
|
281
|
+
#
|
|
282
|
+
# scale - The scale {Number} to apply to the rectangle.
|
|
283
|
+
#
|
|
284
|
+
# Returns this {Rectangle}.
|
|
285
|
+
scale: (scale) ->
|
|
286
|
+
center = @center()
|
|
287
|
+
@width *= scale
|
|
288
|
+
@height *= scale
|
|
289
|
+
@setCenter center
|
|
290
|
+
this
|
|
291
|
+
|
|
292
|
+
@alias 'scale', 'scaleAroundCenter'
|
|
293
|
+
|
|
294
|
+
# Inflates the rectangle around its center by the amount of the arguments.
|
|
295
|
+
#
|
|
296
|
+
# <script>drawTransform(exampleKey, {type: 'inflateAroundCenter', args: [10, 10]})</script>
|
|
297
|
+
#
|
|
298
|
+
# x - A {Number} for the width or a point-like {Object}.
|
|
299
|
+
# y - A {Number} for the height if the first argument
|
|
300
|
+
# was also a number.
|
|
301
|
+
#
|
|
302
|
+
# Returns this [Rectangle]{agt.geom.Rectangle}.
|
|
303
|
+
inflateAroundCenter: (x, y) ->
|
|
304
|
+
center = @center()
|
|
305
|
+
@inflate x, y
|
|
306
|
+
@setCenter center
|
|
307
|
+
this
|
|
308
|
+
|
|
309
|
+
# Inflates the rectangle from its origin by the amount of the arguments.
|
|
310
|
+
#
|
|
311
|
+
# <script>drawTransform(exampleKey, {type: 'inflate', args: [10, 10]})</script>
|
|
312
|
+
#
|
|
313
|
+
# x - A {Number} for the width or a point-like {Object}.
|
|
314
|
+
# y - A {Number} for the height if the first argument
|
|
315
|
+
# was also a number.
|
|
316
|
+
#
|
|
317
|
+
# Returns this [Rectangle]{agt.geom.Rectangle}.
|
|
318
|
+
inflate: (x, y) ->
|
|
319
|
+
pt = agt.geom.Point.pointFrom x, y
|
|
320
|
+
@width += pt.x
|
|
321
|
+
@height += pt.y
|
|
322
|
+
this
|
|
323
|
+
|
|
324
|
+
# Inflates the rectangle width to the left by the passed-in value.
|
|
325
|
+
#
|
|
326
|
+
# <script>drawTransform(exampleKey, {type: 'inflateLeft', args: [10]})</script>
|
|
327
|
+
#
|
|
328
|
+
# inflate - a {Number} for the width inflation.
|
|
329
|
+
#
|
|
330
|
+
# Returns this [Rectangle]{agt.geom.Rectangle}.
|
|
331
|
+
inflateLeft: (inflate) ->
|
|
332
|
+
@width += inflate
|
|
333
|
+
offset = @topEdge().normalize(-inflate)
|
|
334
|
+
{@x,@y} = @topLeft().add(offset)
|
|
335
|
+
this
|
|
336
|
+
|
|
337
|
+
# Inflates the rectangle width to the right by the passed-in value.
|
|
338
|
+
#
|
|
339
|
+
# <script>drawTransform(exampleKey, {type: 'inflateRight', args: [10]})</script>
|
|
340
|
+
#
|
|
341
|
+
# inflate - A {Number} for width inflation.
|
|
342
|
+
#
|
|
343
|
+
# Returns this [Rectangle]{agt.geom.Rectangle}.
|
|
344
|
+
inflateRight: (inflate) ->
|
|
345
|
+
@width += inflate
|
|
346
|
+
this
|
|
347
|
+
|
|
348
|
+
# Inflates the rectangle height to the top by the passed-in value.
|
|
349
|
+
#
|
|
350
|
+
# <script>drawTransform(exampleKey, {type: 'inflateTop', args: [10]})</script>
|
|
351
|
+
#
|
|
352
|
+
# x - A {Number} for the height inflation.
|
|
353
|
+
#
|
|
354
|
+
# Returns this [Rectangle]{agt.geom.Rectangle}.
|
|
355
|
+
inflateTop: (inflate) ->
|
|
356
|
+
@height += inflate
|
|
357
|
+
offset = @leftEdge().normalize(-inflate)
|
|
358
|
+
{@x,@y} = @topLeft().add(offset)
|
|
359
|
+
this
|
|
360
|
+
|
|
361
|
+
# Inflates the rectangle height to the bottom by the passed-in value.
|
|
362
|
+
#
|
|
363
|
+
# <script>drawTransform(exampleKey, {type: 'inflateBottom', args: [10]})</script>
|
|
364
|
+
#
|
|
365
|
+
# x - A {Number} for the height inflation.
|
|
366
|
+
#
|
|
367
|
+
# Returns this [Rectangle]{agt.geom.Rectangle}.
|
|
368
|
+
inflateBottom: (inflate) ->
|
|
369
|
+
@height += inflate
|
|
370
|
+
this
|
|
371
|
+
|
|
372
|
+
# Inflates the rectangle to the top left by the amount of the arguments.
|
|
373
|
+
#
|
|
374
|
+
# <script>drawTransform(exampleKey, {type: 'inflateTopLeft', args: [10, 10]})</script>
|
|
375
|
+
#
|
|
376
|
+
# x - A {Number} for the width or a point-like {Object}.
|
|
377
|
+
# y - A {Number} for the height if the first argument
|
|
378
|
+
# was also a number.
|
|
379
|
+
#
|
|
380
|
+
# Returns this [Rectangle]{agt.geom.Rectangle}.
|
|
381
|
+
inflateTopLeft: (x, y) ->
|
|
382
|
+
pt = agt.geom.Point.pointFrom x, y
|
|
383
|
+
@inflateLeft pt.x
|
|
384
|
+
@inflateTop pt.y
|
|
385
|
+
this
|
|
386
|
+
|
|
387
|
+
# Inflates the rectangle to the top right by the amount of the arguments.
|
|
388
|
+
#
|
|
389
|
+
# <script>drawTransform(exampleKey, {type: 'inflateTopRight', args: [10, 10]})</script>
|
|
390
|
+
#
|
|
391
|
+
# x - A {Number} for the width or a point-like {Object}.
|
|
392
|
+
# y - A {Number} for the height if the first argument
|
|
393
|
+
# was also a number.
|
|
394
|
+
#
|
|
395
|
+
# Returns this [Rectangle]{agt.geom.Rectangle}.
|
|
396
|
+
inflateTopRight: (x, y) ->
|
|
397
|
+
pt = agt.geom.Point.pointFrom x, y
|
|
398
|
+
@inflateRight pt.x
|
|
399
|
+
@inflateTop pt.y
|
|
400
|
+
this
|
|
401
|
+
|
|
402
|
+
# Inflates the rectangle to the bottom left by the amount of the arguments.
|
|
403
|
+
#
|
|
404
|
+
# <script>drawTransform(exampleKey, {type: 'inflateBottomLeft', args: [10, 10]})</script>
|
|
405
|
+
#
|
|
406
|
+
# x - A {Number} for the width or a point-like {Object}.
|
|
407
|
+
# y - A {Number} for the height if the first argument
|
|
408
|
+
# was also a number.
|
|
409
|
+
#
|
|
410
|
+
# Returns this [Rectangle]{agt.geom.Rectangle}.
|
|
411
|
+
inflateBottomLeft: (x, y) ->
|
|
412
|
+
pt = agt.geom.Point.pointFrom x, y
|
|
413
|
+
@inflateLeft pt.x
|
|
414
|
+
@inflateBottom pt.y
|
|
415
|
+
this
|
|
416
|
+
|
|
417
|
+
# Inflates the rectangle to the bottom right by the amount of the arguments.
|
|
418
|
+
#
|
|
419
|
+
# <script>drawTransform(exampleKey, {type: 'inflateBottomRight', args: [10, 10]})</script>
|
|
420
|
+
#
|
|
421
|
+
# x - A {Number} for the width or a point-like {Object}.
|
|
422
|
+
# y - A {Number} for the height if the first argument
|
|
423
|
+
# was also a number.
|
|
424
|
+
#
|
|
425
|
+
# Returns this [Rectangle]{agt.geom.Rectangle}.
|
|
426
|
+
inflateBottomRight: (x, y) -> @inflate x, y
|
|
427
|
+
|
|
428
|
+
# Always returns `true`.
|
|
429
|
+
#
|
|
430
|
+
# Returns a {Boolean}.
|
|
431
|
+
closedGeometry: -> true
|
|
432
|
+
|
|
433
|
+
# Returns the rectangle points.
|
|
434
|
+
#
|
|
435
|
+
# <script>drawGeometryPoints(exampleKey, 'points')</script>
|
|
436
|
+
#
|
|
437
|
+
# Returns an {Array}.
|
|
438
|
+
points: ->
|
|
439
|
+
[@topLeft(), @topRight(), @bottomRight(), @bottomLeft(), @topLeft()]
|
|
440
|
+
|
|
441
|
+
# Returns the [Point]{agt.geom.Point} on the perimeter of the rectangle
|
|
442
|
+
# at the given `angle`.
|
|
443
|
+
#
|
|
444
|
+
# angle - The angle {Number}.
|
|
445
|
+
#
|
|
446
|
+
# <script>drawGeometry(exampleKey, {angle: true})</script>
|
|
447
|
+
#
|
|
448
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
449
|
+
pointAtAngle: (angle) ->
|
|
450
|
+
center = @center()
|
|
451
|
+
vec = center.add Math.cos(angle)*10000,
|
|
452
|
+
Math.sin(angle)*10000
|
|
453
|
+
@intersections(points: -> [center, vec])?[0]
|
|
454
|
+
|
|
455
|
+
# Returns the surface {Number} of this rectangle.
|
|
456
|
+
#
|
|
457
|
+
# Returns a {Number}.
|
|
458
|
+
acreage: -> @width * @height
|
|
459
|
+
|
|
460
|
+
# Returns `true` when the given point is contained in the rectangle.
|
|
461
|
+
#
|
|
462
|
+
# In the example below all the green points on the screen represents
|
|
463
|
+
# coordinates that are contained in the rectangle.
|
|
464
|
+
#
|
|
465
|
+
# <script>drawGeometry(exampleKey, {contains: true})</script>
|
|
466
|
+
#
|
|
467
|
+
# x - A {Number} for the x coordinate or a point-like {Object}.
|
|
468
|
+
# y - A {Number} for the y coordinate if the first argument
|
|
469
|
+
# was also a number.
|
|
470
|
+
#
|
|
471
|
+
# Returns a {Boolean}.
|
|
472
|
+
contains: (x, y) ->
|
|
473
|
+
{x,y} = new agt.geom.Point(x, y).rotateAround(@topLeft(), -@rotation)
|
|
474
|
+
(@x <= x <= @x + @width) and (@y <= y <= @y + @height)
|
|
475
|
+
|
|
476
|
+
# Returns a randomly generated point within the rectangle perimeter.
|
|
477
|
+
#
|
|
478
|
+
# <script>drawGeometry(exampleKey, {surface: true})</script>
|
|
479
|
+
#
|
|
480
|
+
# random - An optional [Random]{agt.random.Random} instance to use instead
|
|
481
|
+
# of the default `Math` random method.
|
|
482
|
+
#
|
|
483
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
484
|
+
randomPointInSurface: (random) ->
|
|
485
|
+
unless random?
|
|
486
|
+
random = new agt.random.Random new agt.random.MathRandom
|
|
487
|
+
@topLeft()
|
|
488
|
+
.add(@topEdge().scale random.get())
|
|
489
|
+
.add(@leftEdge().scale random.get())
|
|
490
|
+
|
|
491
|
+
# Returns the length {Number} of the rectangle perimeter.
|
|
492
|
+
#
|
|
493
|
+
# Returns a {Number}.
|
|
494
|
+
length: -> @width * 2 + @height * 2
|
|
495
|
+
|
|
496
|
+
# Returns a [Point]{agt.geom.Point} on the rectangle perimeter using
|
|
497
|
+
# a {Number} between `0` and `1`.
|
|
498
|
+
#
|
|
499
|
+
# <script>drawGeometry(exampleKey, {paths: [0, 1/3, 2/3]})</script>
|
|
500
|
+
#
|
|
501
|
+
# n - A {Number} between `0` and `1`a {Number} between `0` and `1`.
|
|
502
|
+
# pathBasedOnLength - A {Boolean} of whether the position on the path
|
|
503
|
+
# consider the length of the path segments or not.
|
|
504
|
+
# When true, each segment will only weight as much
|
|
505
|
+
# as their own length.
|
|
506
|
+
# When false, every segment have the same weight,
|
|
507
|
+
# resulting in a difference in speed when animating
|
|
508
|
+
# an object along a path.
|
|
509
|
+
#
|
|
510
|
+
# Returns a [Point]{agt.geom.Point}.
|
|
511
|
+
pathPointAt: (n, pathBasedOnLength=true) ->
|
|
512
|
+
[p1,p2,p3] = @pathSteps pathBasedOnLength
|
|
513
|
+
|
|
514
|
+
if n < p1
|
|
515
|
+
@topLeft().add @topEdge().scale Math.map n, 0, p1, 0, 1
|
|
516
|
+
else if n < p2
|
|
517
|
+
@topRight().add @rightEdge().scale Math.map n, p1, p2, 0, 1
|
|
518
|
+
else if n < p3
|
|
519
|
+
@bottomRight().add @bottomEdge().scale Math.map(n, p2, p3, 0, 1) * -1
|
|
520
|
+
else
|
|
521
|
+
@bottomLeft().add @leftEdge().scale Math.map(n, p3, 1, 0, 1) * -1
|
|
522
|
+
|
|
523
|
+
# Returns the angle of the rectangle perimeter at the path position {Number}.
|
|
524
|
+
#
|
|
525
|
+
# <script>drawGeometry(exampleKey, {paths: [0, 1/3, 2/3]})</script>
|
|
526
|
+
#
|
|
527
|
+
# n - A {Number} between `0` and `1`a {Number} between `0` and `1`.
|
|
528
|
+
# pathBasedOnLength - A {Boolean} of whether the position on the path
|
|
529
|
+
# consider the length of the path segments or not.
|
|
530
|
+
# When true, each segment will only weight as much
|
|
531
|
+
# as their own length.
|
|
532
|
+
# When false, every segment have the same weight,
|
|
533
|
+
# resulting in a difference in speed when animating
|
|
534
|
+
# an object along a path.
|
|
535
|
+
#
|
|
536
|
+
# Returns a {Number}.
|
|
537
|
+
pathOrientationAt: (n, pathBasedOnLength=true) ->
|
|
538
|
+
[p1,p2,p3] = @pathSteps pathBasedOnLength
|
|
539
|
+
|
|
540
|
+
if n < p1
|
|
541
|
+
p = @topEdge()
|
|
542
|
+
else if n < p2
|
|
543
|
+
p = @rightEdge()
|
|
544
|
+
else if n < p3
|
|
545
|
+
p = @bottomEdge().scale -1
|
|
546
|
+
else
|
|
547
|
+
p = @leftEdge().scale -1
|
|
548
|
+
|
|
549
|
+
p.angle()
|
|
550
|
+
|
|
551
|
+
# Internal: Calculates the proportions of each step of the rectangle path.
|
|
552
|
+
#
|
|
553
|
+
# Returns an {Array}.
|
|
554
|
+
pathSteps: (pathBasedOnLength=true) ->
|
|
555
|
+
if pathBasedOnLength
|
|
556
|
+
l = @length()
|
|
557
|
+
p1 = @width / l
|
|
558
|
+
p2 = (@width + @height) / l
|
|
559
|
+
p3 = p1 + p2
|
|
560
|
+
else
|
|
561
|
+
p1 = 1 / 4
|
|
562
|
+
p2 = 1 / 2
|
|
563
|
+
p3 = 3 / 4
|
|
564
|
+
|
|
565
|
+
[p1, p2, p3]
|
|
566
|
+
|
|
567
|
+
# {Delegates to: agt.geom.Geometry.drawPath}
|
|
568
|
+
drawPath: (context) ->
|
|
569
|
+
context.beginPath()
|
|
570
|
+
context.moveTo(@x, @y)
|
|
571
|
+
context.lineTo(@topRight().x, @topRight().y)
|
|
572
|
+
context.lineTo(@bottomRight().x, @bottomRight().y)
|
|
573
|
+
context.lineTo(@bottomLeft().x, @bottomLeft().y)
|
|
574
|
+
context.lineTo(@x, @y)
|
|
575
|
+
context.closePath()
|
|
576
|
+
|
|
577
|
+
# Pastes the values of the passed-in rectangle into this one.
|
|
578
|
+
#
|
|
579
|
+
# x - The x coordinate {Number} of the rectangle or a rectangle-like {Object}.
|
|
580
|
+
# y - The y coordinate {Number} of the rectangle.
|
|
581
|
+
# width - The width {Number} of the rectangle.
|
|
582
|
+
# height - The height {Number} of the rectangle.
|
|
583
|
+
# rotation - The rotation {Number} of the rectangle.
|
|
584
|
+
paste: (x, y, width, height, rotation) ->
|
|
585
|
+
values = @rectangleFrom x, y, width, height, rotation
|
|
586
|
+
@[k] = parseFloat v for k,v of values when Math.isFloat v
|
|
587
|
+
|
|
588
|
+
# Internal: Resets all invalid number in the passed-in array to `0`.
|
|
589
|
+
#
|
|
590
|
+
# values - An {Array} containing numeric values.
|
|
591
|
+
#
|
|
592
|
+
# Returns an {Array}.
|
|
593
|
+
defaultToZero: (values) ->
|
|
594
|
+
values[k] = 0 for k,v of values when not Math.isFloat v
|
|
595
|
+
values
|
|
596
|
+
|
|
597
|
+
@proxy 'pathOrientationAt', as: 'Angle'
|
|
598
|
+
@proxy 'points', 'corners', 'edges', as: 'PointList'
|
|
599
|
+
@proxy 'topLeft', 'topRight', 'bottomLeft', 'bottomRight', 'center', 'topEdgeCenter', 'bottomEdgeCenter', 'leftEdgeCenter', 'rightEdgeCenter', 'topEdge', 'leftEdge', 'rightEdge', 'bottomEdge', 'diagonal', 'pathPointAt', as: 'Point'
|