@@ -2,36 +2,65 @@ package {
2
2
import flash.geom.* ;
3
3
import flash.filters.* ;
4
4
import flash.display.* ;
5
-
5
+
6
+ [SWF (width=500,height=400)]
6
7
public class demo_roads extends Sprite {
7
8
8
- public var a0: Point = new Point (150 , 30 );
9
- public var a1: Point = new Point (350 , 50 );
10
- public var a2: Point = new Point (450 , 200 );
11
- public var ak: Number = 30 ;
12
-
9
+ // Compare circle drawing to bezier approximation
10
+ public var c: Point = new Point (180 , 200 );
13
11
public var b0: Point = Point . polar(100 , Math . PI );
14
12
public var b1: Point = Point . polar(150 , Math . PI * 2 / 3 );
15
13
public var b2: Point = Point . polar(100 , Math . PI / 3 );
16
-
14
+
15
+ // Left side: bezier roads
17
16
public var c0: Point = new Point (150 , 30 );
18
17
public var c1: Point = new Point (50 , 20 );
19
18
public var c2: Point = new Point (25 , 120 );
20
19
public var c3: Point = new Point (10 , 180 );
21
20
public var c4: Point = new Point (30 , 240 );
22
21
23
- public function demo_roads () {
24
- addChild (new Debug(this ));
22
+ // Right side: arc roads
23
+ public var a0: Point = new Point (250 , 30 );
24
+ public var a1: Point = new Point (370 , 150 );
25
+ public var a2: Point = new Point (300 , 300 );
26
+ public var ak: Number = 70 ;
25
27
26
- var c : Point = new Point (150 , 100 );
28
+ // Right side: what the same arc road would look like with bezier
29
+ public var overlayArc: Sprite = new Sprite ();
30
+ public var overlayBez: Sprite = new Sprite ();
31
+
32
+ // Number of lanes in various areas
33
+ public var lanesL0: int = 2 ;
34
+ public var lanesR0: int = 3 ;
35
+ public var lanesL1: int = 3 ;
36
+ public var lanesR1: int = 3 ;
37
+ public var lanesL2: int = 3 ;
38
+ public var lanesR2: int = 2 ;
39
+
40
+ public function demo_roads () {
41
+ overlayBez. alpha = 0.2 ;
42
+ addChild (overlayBez);
43
+ addChild (overlayArc);
44
+
27
45
b0 = b0. add (c );
28
46
b1 = b1. add (c );
29
47
b2 = b2. add (c );
30
48
31
- addChild (new Draggable(Model. Cartesian(Model. ref(this , 'ak' )
32
- . clamped(10 , 200 )
33
- . add (300 ),
34
- Model. constant(20 ))
49
+ var laneModels = [ 'lanesL0' , 'lanesR0' , 'lanesL1' , 'lanesR1' , 'lanesL2' , 'lanesR2' ];
50
+ for (var i: int = 0 ; i < laneModels. length ; i++ ) {
51
+ addChild (new Draggable(Model. Cartesian(Model. ref(this , laneModels[ i] )
52
+ . clamped(1 , 5 )
53
+ . rounded()
54
+ . multiply(10 )
55
+ . add (10 + 60 * Math . floor (i/ 2 )),
56
+ Model. constant(360 + 30 * (i% 2 )))
57
+ . callback(redraw)));
58
+ }
59
+
60
+ addChild (new Draggable(Model. Cartesian(Model. constant(390 ),
61
+ Model. ref(this , 'ak' )
62
+ . clamped(10 , 150 )
63
+ . add (20 ))
35
64
. callback(redraw)));
36
65
37
66
for each (var p: Point in [ c0, c1, c2, c3, c4, b0, b1, b2, a0, a1, a2] ) {
@@ -68,22 +97,22 @@ package {
68
97
69
98
// Draw a background
70
99
graphics . beginFill (0xbbbb99 );
71
- graphics . drawRect (- 1000 , - 1000 , 2000 , 2000 );
100
+ graphics . drawRect (0 , 0 , 500 , 400 );
72
101
graphics . endFill ();
73
102
74
103
// Draw a slider base for the arc size slider
75
104
graphics . lineStyle (5 , 0x777777 );
76
- graphics . moveTo (300 , 20 );
77
- graphics . lineTo (500 , 20 );
105
+ graphics . moveTo (390 , 30 );
106
+ graphics . lineTo (390 , 170 );
78
107
graphics . lineStyle ();
79
108
80
109
// Draw the Bezier curve road
81
- drawTestRoadSegment(graphics , c0, c1, c2, 2 , 2 , 3 , 2 );
82
- drawTestRoadSegment(graphics , c2, c3, c4, 3 , 2 , 3 , 2 );
110
+ drawTestRoadSegment(graphics , c0, c1, c2, lanesR1, lanesL1, lanesR1, lanesL1 );
111
+ drawTestRoadSegment(graphics , c2, c3, c4, lanesR1, lanesL1, lanesR2, lanesL2 );
83
112
84
113
// Draw a circle and a Bezier curve approximating it
85
114
graphics . lineStyle (1 , 0xbb6600 );
86
- graphics . drawCircle (150 , 100 , 100 );
115
+ graphics . drawCircle (c . x , c . y , 100 );
87
116
graphics . lineStyle (1 , 0x669900 );
88
117
graphics . moveTo (b0. x , b0. y );
89
118
graphics . lineTo (b1. x , b1. y );
@@ -107,6 +136,8 @@ package {
107
136
graphics . lineStyle ();
108
137
109
138
// Draw a road that uses a circular arc to join straight segments
139
+ var graphics1: Graphics = overlayArc. graphics ;
140
+ graphics1. clear ();
110
141
var a10: Point = a0. subtract (a1); a10. normalize (1 );
111
142
var a12: Point = a2. subtract (a1); a12. normalize (1 );
112
143
var p: Point = V . intersection
@@ -115,19 +146,47 @@ package {
115
146
116
147
var p1: Point = V . intersection (a1, a10, p, V . left (a10));
117
148
var p2: Point = V . intersection (a1, a12, p, V . right (a12));
118
- var lanes: int = 2 ;
119
-
120
- drawTestRoadSegment(graphics , a0, Point . interpolate (a0, p1, 0.5 ), p1, lanes, lanes, lanes, lanes);
121
- drawTestRoadSegment(graphics , p1, a1, p2, lanes, lanes, lanes, lanes);
122
- drawTestRoadSegment(graphics , p2, Point . interpolate (p2, a2, 0.5 ), a2, lanes, lanes, lanes, lanes);
123
- drawPoint(graphics , p, 0xffff00 , 3 , 0x000000 );
124
- drawPoint(graphics , p1, 0xffff00 , 2 , 0x000000 );
125
- drawPoint(graphics , p2, 0xffff00 , 2 , 0x000000 );
126
- graphics . lineStyle (1 , 0xffff00 , 0.5 );
127
- graphics . moveTo (p1. x , p1. y );
128
- graphics . lineTo (p. x , p. y );
129
- graphics . lineTo (p2. x , p2. y );
130
- graphics . lineStyle ();
149
+
150
+ drawTestRoadSegment(graphics1, a0, Point . interpolate (a0, p1, 0.5 ), p1, lanesL0, lanesR0, lanesL1, lanesR1);
151
+ drawTestRoadSegment(graphics1, p2, Point . interpolate (p2, a2, 0.5 ), a2, lanesL1, lanesR1, lanesL2, lanesR2);
152
+ drawPoint(graphics1, p, 0xffff00 , 3 , 0x000000 );
153
+ drawPoint(graphics1, p1, 0xffff00 , 2 , 0x000000 );
154
+ drawPoint(graphics1, p2, 0xffff00 , 2 , 0x000000 );
155
+ graphics1. lineStyle (1 , 0xffff00 , 0.5 );
156
+ graphics1. moveTo (p1. x , p1. y );
157
+ graphics1. lineTo (p. x , p. y );
158
+ graphics1. lineTo (p2. x , p2. y );
159
+ graphics1. lineStyle ();
160
+
161
+ // Split arc into segments, each approximated by a bezier curve
162
+ var threshold : Number = Math . PI / 2 ;
163
+ function drawArc(center: Point , radius : Number , angle1: Number , angle2: Number ): void {
164
+ var angle : Number = 0.5 * (angle1 + angle2);
165
+ var da: Number = angle2 - angle1;
166
+ if (da < 0.0 ) da += 2 * Math . PI ;
167
+
168
+ if (da > Math . PI / 4 ) {
169
+ drawArc(center, radius , angle1, angle );
170
+ drawArc(center, radius , angle , angle2);
171
+ } else {
172
+ var p1: Point = center. add (Point . polar (radius , angle1));
173
+ var p2: Point = center. add (Point . polar (radius , angle2));
174
+ var pc: Point = center. add (Point . polar (radius / Math . cos (da/ 2 ), angle ));
175
+
176
+ drawTestRoadSegment(graphics1, p1, pc, p2, lanesL1, lanesR1, lanesL1, lanesR1);
177
+ }
178
+ }
179
+
180
+ drawArc(p, p. subtract (p1). length ,
181
+ Math . atan2 (p1. y - p. y , p1. x - p. x ),
182
+ Math . atan2 (p2. y - p. y , p2. x - p. x ));
183
+
184
+ // Show what the same road looks like with bezier curves
185
+ var graphics2: Graphics = overlayBez. graphics ;
186
+ graphics2. clear ();
187
+ drawTestRoadSegment(graphics2, a0, Point . interpolate (a0, p1, 0.5 ), p1, lanesL0, lanesR0, lanesL1, lanesR1);
188
+ drawTestRoadSegment(graphics2, p1, a1, p2, lanesL1, lanesR1, lanesL1, lanesR1);
189
+ drawTestRoadSegment(graphics2, p2, Point . interpolate (p2, a2, 0.5 ), a2, lanesL1, lanesR1, lanesL2, lanesR2);
131
190
}
132
191
133
192
public function offsetBezier (b0 :Point , b1 :Point , b2 :Point , d0 :Number , d2 :Number ):Array {
0 commit comments