|
6 | 6 | <g :transform="getFieldTransformation">
|
7 | 7 |
|
8 | 8 | <!-- draw field background -->
|
9 |
| - <rect :x="-(fieldLength/2+boundaryWidth)" |
10 |
| - :y="-(fieldWidth/2+boundaryWidth)" |
11 |
| - :width="fieldLength+boundaryWidth*2" |
12 |
| - :height="fieldWidth+boundaryWidth*2" |
13 |
| - style="fill:green;fill-opacity:1;stroke:none"></rect> |
14 |
| - |
15 |
| - <!-- draw field borders --> |
16 |
| - <line v-show="!useShapesFromGeometry" |
17 |
| - :x1="-fieldLength/2" |
18 |
| - :y1="-fieldWidth/2" |
19 |
| - :x2="-fieldLength/2" |
20 |
| - :y2="fieldWidth/2" |
21 |
| - style="stroke:white;stroke-width:10px"></line> |
22 |
| - <line v-show="!useShapesFromGeometry" |
23 |
| - :x1="-fieldLength/2" |
24 |
| - :y1="fieldWidth/2" |
25 |
| - :x2="fieldLength/2" |
26 |
| - :y2="fieldWidth/2" |
27 |
| - style="stroke:white;stroke-width:10px"></line> |
28 |
| - <line v-show="!useShapesFromGeometry" |
29 |
| - :x1="fieldLength/2" |
30 |
| - :y1="fieldWidth/2" |
31 |
| - :x2="fieldLength/2" |
32 |
| - :y2="-fieldWidth/2" |
33 |
| - style="stroke:white;stroke-width:10px"></line> |
34 |
| - <line v-show="!useShapesFromGeometry" |
35 |
| - :x1="fieldLength/2" |
36 |
| - :y1="-fieldWidth/2" |
37 |
| - :x2="-fieldLength/2" |
38 |
| - :y2="-fieldWidth/2" |
39 |
| - style="stroke:white;stroke-width:10px"></line> |
40 |
| - <line v-show="!useShapesFromGeometry" |
41 |
| - :x1="0" |
42 |
| - :y1="fieldWidth/2" |
43 |
| - :x2="0" |
44 |
| - :y2="-fieldWidth/2" |
45 |
| - style="stroke:white;stroke-width:10px"></line> |
46 |
| - <!-- center circle --> |
47 |
| - <circle v-show="!useShapesFromGeometry" |
48 |
| - :r="centerCircleRadius" |
49 |
| - style="stroke:white;stroke-width:10px;fill-opacity:0"></circle> |
50 |
| - <!-- penalty areas --> |
51 |
| - <rect v-show="!useShapesFromGeometry" |
52 |
| - :x="-(fieldLength)/2" |
53 |
| - :y="-(penAreaWidth)/2" |
54 |
| - :width="penAreaDepth" |
55 |
| - :height="penAreaWidth" |
56 |
| - style="stroke: white;stroke-width:10px; fill-opacity:0"></rect> |
57 |
| - <rect v-show="!useShapesFromGeometry" |
58 |
| - :x="(fieldLength/2)-penAreaDepth" |
59 |
| - :y="-penAreaWidth/2" |
60 |
| - :width="penAreaDepth" |
61 |
| - :height="penAreaWidth" |
62 |
| - style="stroke: white;stroke-width:10px; fill-opacity:0"></rect> |
63 |
| - |
64 |
| - <!-- goals --> |
65 |
| - <line :x1="-fieldLength/2" |
66 |
| - :y1="-goalWidth/2" |
67 |
| - :x2="-fieldLength/2-goalDepth" |
68 |
| - :y2="-goalWidth/2" |
69 |
| - style="stroke:black;stroke-width:10px"></line> |
70 |
| - <line :x1="-fieldLength/2" |
71 |
| - :y1="goalWidth/2" |
72 |
| - :x2="-fieldLength/2-goalDepth" |
73 |
| - :y2="goalWidth/2" |
74 |
| - style="stroke:black;stroke-width:10px"></line> |
75 |
| - <line :x1="-fieldLength/2-goalDepth" |
76 |
| - :y1="-goalWidth/2" |
77 |
| - :x2="-fieldLength/2-goalDepth" |
78 |
| - :y2="goalWidth/2" |
79 |
| - style="stroke:black;stroke-width:10px"></line> |
80 |
| - |
81 |
| - <line :x1="fieldLength/2" |
82 |
| - :y1="-goalWidth/2" |
83 |
| - :x2="fieldLength/2+goalDepth" |
84 |
| - :y2="-goalWidth/2" |
85 |
| - style="stroke:black;stroke-width:10px"></line> |
86 |
| - <line :x1="fieldLength/2" |
87 |
| - :y1="goalWidth/2" |
88 |
| - :x2="fieldLength/2+goalDepth" |
89 |
| - :y2="goalWidth/2" |
90 |
| - style="stroke:black;stroke-width:10px"></line> |
91 |
| - <line :x1="fieldLength/2+goalDepth" |
92 |
| - :y1="-goalWidth/2" |
93 |
| - :x2="fieldLength/2+goalDepth" |
94 |
| - :y2="goalWidth/2" |
95 |
| - style="stroke:black;stroke-width:10px"></line> |
96 |
| - |
97 |
| - <!-- lines from geometry --> |
98 |
| - <line v-for="l of lines" |
99 |
| - v-bind:key="l" |
| 9 | + <rect :x="-(field.fieldLength/2+field.boundaryWidth)" |
| 10 | + :y="-(field.fieldWidth/2+field.boundaryWidth)" |
| 11 | + :width="field.fieldLength+field.boundaryWidth*2" |
| 12 | + :height="field.fieldWidth+field.boundaryWidth*2" |
| 13 | + :style="{fill: 'green', fillOpacity: 1, stroke: 'none'}"></rect> |
| 14 | + |
| 15 | + <line v-for="(l,i) of field.lines" |
| 16 | + :key="'line-' + i" |
100 | 17 | :x1="l.p1.x"
|
101 | 18 | :y1="l.p1.y"
|
102 | 19 | :x2="l.p2.x"
|
103 | 20 | :y2="l.p2.y"
|
104 |
| - style="stroke:white;stroke-width:10px"></line> |
| 21 | + :style="[defStyle, l]"> |
| 22 | + </line> |
105 | 23 |
|
106 |
| - <!-- arcs from geometry (only circles supported for now --> |
107 |
| - <circle v-for="a of arcs" |
108 |
| - v-bind:key="a" |
| 24 | + <circle v-for="(a,i) of field.circles" |
| 25 | + :key="'circle-' + i" |
109 | 26 | :cx="a.center.x"
|
110 | 27 | :cy="a.center.y"
|
111 | 28 | :r="a.radius"
|
112 |
| - style="stroke:white;stroke-width:10px;fill-opacity:0"></circle> |
113 |
| - |
114 |
| - <!-- robots --> |
115 |
| - <path v-for="r of getRobotsYellow" |
116 |
| - v-bind:key="r" |
117 |
| - :d=" |
118 |
| - 'M ' + r.x + r.botRightX() + ',' + r.y + r.botRightY() + |
119 |
| - 'A ' + r.botRadius + ' ' + r.botRadius + ' 0 1 1 ' + r.x + r.botLeftX() + ',' + r.y + r.botLeftY() + |
120 |
| - 'L ' + r.x + r.botRightX() + ','+ r.y + r.botRightY()" |
121 |
| - style="stroke:black;stroke-width:0.3em;fill: yellow; fill-opacity:1"></path> |
122 |
| - |
123 |
| - <path v-for="r of getRobotsBlue" |
124 |
| - v-bind:key="r" |
125 |
| - :d=" |
126 |
| - 'M ' + r.x + r.botRightX() + ',' + r.y + r.botRightY() + |
127 |
| - 'A ' + r.botRadius + ' ' + r.botRadius + ' 0 1 1 ' + r.x + r.botLeftX() + ',' + r.y + r.botLeftY() + |
128 |
| - 'L ' + r.x + r.botRightX() + ','+ r.y + r.botRightY()" |
129 |
| - style="stroke:black;stroke-width:0.3em;fill: blue; fill-opacity:1"></path> |
130 |
| - |
131 |
| - <!-- robot ids --> |
132 |
| - <text v-for="r of getRobotsYellow" |
133 |
| - v-bind:key="r" |
134 |
| - :x="r.x" |
135 |
| - :y="r.y" |
136 |
| - :dx="'-40'" |
137 |
| - :dy="'45'" |
138 |
| - :textLength="r.botRadius+20" |
139 |
| - :lengthAdjust="'spacingAndGlyphs'" |
140 |
| - class="bot-id" |
141 |
| - style="stroke-width:0;fill: black"> |
142 |
| - {{r.id}} |
143 |
| - </text> |
| 29 | + :style="[defStyle, a]"> |
| 30 | + </circle> |
144 | 31 |
|
145 |
| - <text v-for="r of getRobotsBlue" |
146 |
| - v-bind:key="r" |
147 |
| - :x="r.x" |
148 |
| - :y="r.y" |
149 |
| - :dx="'-40'" |
150 |
| - :dy="'45'" |
151 |
| - :textLength="r.botRadius+20" |
| 32 | + <path v-for="(p,i) of field.paths" |
| 33 | + :key="'path-' + i" |
| 34 | + :d="pathFromD(p.d)" |
| 35 | + :style="[defStyle, p]"></path> |
| 36 | + |
| 37 | + <text v-for="(t,i) of field.texts" |
| 38 | + :key="'text-' + i" |
| 39 | + :x="t.p.x" |
| 40 | + :y="t.p.y" |
| 41 | + :dx="t.d.x" |
| 42 | + :dy="t.d.y" |
| 43 | + :textLength="t.textLength" |
152 | 44 | :lengthAdjust="'spacingAndGlyphs'"
|
153 |
| - class="bot-id" |
154 |
| - style="stroke-width:0;fill: white"> |
155 |
| - {{r.id}} |
| 45 | + :style="[defStyle, t]"> |
| 46 | + {{t.text}} |
156 | 47 | </text>
|
157 |
| - |
158 |
| - <!-- balls --> |
159 |
| - <circle v-for="r of balls" |
160 |
| - v-bind:key="r" |
161 |
| - :r="ballRadius" |
162 |
| - :cx="r.x" |
163 |
| - :cy="r.y" |
164 |
| - style="stroke:black;stroke-width:0.3em;fill: orangered; fill-opacity:1"> |
165 |
| - </circle> |
166 |
| - <circle v-for="r of balls" |
167 |
| - v-bind:key="r" |
168 |
| - :r="300" |
169 |
| - :cx="r.x" |
170 |
| - :cy="r.y" |
171 |
| - style="stroke:red;stroke-width:0.5em; fill-opacity:0"> |
172 |
| - </circle> |
173 | 48 | </g>
|
174 | 49 | </svg>
|
175 | 50 | </template>
|
|
179 | 54 |
|
180 | 55 | export default {
|
181 | 56 | name: "Field",
|
182 |
| - data: function () { |
183 |
| - return { |
184 |
| - rotateField: true, |
185 |
| - useShapesFromGeometry: false, |
186 |
| - fieldWidth: 2000, |
187 |
| - fieldLength: 3000, |
188 |
| - boundaryWidth: 300, |
189 |
| - penAreaWidth: 1000, |
190 |
| - penAreaDepth: 500, |
191 |
| - goalWidth: 600, |
192 |
| - goalDepth: 180, |
193 |
| - centerCircleRadius: 500, |
194 |
| - ballRadius: 21.5, |
195 |
| - lines: [{p1: {x: 100, y: 100}, p2: {x: 500, y: 1000}}], |
196 |
| - arcs: [], |
197 |
| - robotsYellow: {}, |
198 |
| - robotsBlue: {}, |
199 |
| - balls: [] |
| 57 | + props: { |
| 58 | + rotateField: { |
| 59 | + type: Boolean, |
| 60 | + default: false |
| 61 | + }, |
| 62 | + defStyle: { |
| 63 | + type: Object, |
| 64 | + default: function () { |
| 65 | + return { |
| 66 | + strokeWidth: 10, |
| 67 | + stroke: 'white', |
| 68 | + fillOpacity: 0 |
| 69 | + } |
| 70 | + } |
| 71 | + }, |
| 72 | + field: { |
| 73 | + type: Object, |
| 74 | + default: function () { |
| 75 | + let fieldWidth = 2000; |
| 76 | + let fieldLength = 3000; |
| 77 | + let centerCircleRadius = 500; |
| 78 | + return { |
| 79 | + fieldWidth: fieldWidth, |
| 80 | + fieldLength: fieldLength, |
| 81 | + boundaryWidth: 300, |
| 82 | + penAreaWidth: 1000, |
| 83 | + penAreaDepth: 500, |
| 84 | + goalWidth: 600, |
| 85 | + goalDepth: 180, |
| 86 | + centerCircleRadius: centerCircleRadius, |
| 87 | + ballRadius: 21.5, |
| 88 | + lines: [ |
| 89 | + { |
| 90 | + p1: {x: -fieldLength / 2, y: -fieldWidth / 2}, |
| 91 | + p2: {x: -fieldLength / 2, y: fieldWidth / 2} |
| 92 | + }, |
| 93 | + { |
| 94 | + p1: {x: -fieldLength / 2, y: fieldWidth / 2}, |
| 95 | + p2: {x: fieldLength / 2, y: fieldWidth / 2} |
| 96 | + }, |
| 97 | + { |
| 98 | + p1: {x: fieldLength / 2, y: fieldWidth / 2}, |
| 99 | + p2: {x: fieldLength / 2, y: -fieldWidth / 2} |
| 100 | + }, |
| 101 | + { |
| 102 | + p1: {x: fieldLength / 2, y: -fieldWidth / 2}, |
| 103 | + p2: {x: -fieldLength / 2, y: -fieldWidth / 2} |
| 104 | + }, |
| 105 | + { |
| 106 | + p1: {x: 0, y: fieldWidth / 2}, |
| 107 | + p2: {x: 0, y: -fieldWidth / 2} |
| 108 | + } |
| 109 | + ], |
| 110 | + circles: [ |
| 111 | + { |
| 112 | + center: {x: 0, y: 0}, |
| 113 | + radius: centerCircleRadius, |
| 114 | + stroke: 'white', |
| 115 | + strokeWidth: 10, |
| 116 | + fill: '', |
| 117 | + fillOpacity: 0 |
| 118 | + } |
| 119 | + ], |
| 120 | + paths: [ |
| 121 | + { |
| 122 | + d: [ |
| 123 | + { |
| 124 | + type: 'M', |
| 125 | + args: [925, -550] |
| 126 | + }, |
| 127 | + { |
| 128 | + type: 'A', |
| 129 | + args: [90, 90, 0, 1, 1, 925, -450] |
| 130 | + }, |
| 131 | + { |
| 132 | + type: 'L', |
| 133 | + args: [925, -550] |
| 134 | + } |
| 135 | + ], |
| 136 | + stroke: 'white', |
| 137 | + strokeWidth: '10', |
| 138 | + fill: 'yellow', |
| 139 | + fillOpacity: 1 |
| 140 | + } |
| 141 | + ], |
| 142 | + texts: [ |
| 143 | + { |
| 144 | + text: '1', |
| 145 | + p: {x: 990, y: -510}, |
| 146 | + d: {x: -40, y: 45}, |
| 147 | + textLength: 110, |
| 148 | + strokeWidth: 0, |
| 149 | + fill: 'black', |
| 150 | + font: 'bold 7em sans-serif', |
| 151 | + fillOpacity: 1 |
| 152 | + } |
| 153 | + ] |
| 154 | + } |
| 155 | + } |
200 | 156 | }
|
201 | 157 | },
|
202 | 158 | computed: {
|
203 |
| - getRobotsYellow() { |
204 |
| - return this.robotsYellow.values; |
205 |
| - }, |
206 |
| - getRobotsBlue() { |
207 |
| - return this.robotsBlue.values; |
208 |
| - }, |
209 | 159 | getFieldTransformation() {
|
210 | 160 | if (this.rotateField) {
|
211 |
| - return 'rotate(90) scale(' + (this.fieldWidth / this.fieldLength) + ')'; |
| 161 | + return 'rotate(90) scale(' + (this.field.fieldWidth / this.field.fieldLength) + ')'; |
212 | 162 | }
|
213 | 163 | return '';
|
214 | 164 | },
|
215 | 165 | viewBox() {
|
216 |
| - return (-(this.fieldLength / 2 + this.boundaryWidth)) |
217 |
| - + ' ' + (-(this.fieldWidth / 2 + this.boundaryWidth)) |
218 |
| - + ' ' + (this.fieldLength + this.boundaryWidth * 2) |
219 |
| - + ' ' + (this.fieldWidth + this.boundaryWidth * 2); |
| 166 | + return (-(this.field.fieldLength / 2 + this.field.boundaryWidth)) |
| 167 | + + ' ' + (-(this.field.fieldWidth / 2 + this.field.boundaryWidth)) |
| 168 | + + ' ' + (this.field.fieldLength + this.field.boundaryWidth * 2) |
| 169 | + + ' ' + (this.field.fieldWidth + this.field.boundaryWidth * 2); |
| 170 | + }, |
| 171 | + }, |
| 172 | + methods: { |
| 173 | + pathFromD: function (pd) { |
| 174 | + let d = ''; |
| 175 | + for (let s of pd) { |
| 176 | + d += s.type; |
| 177 | + for (let a of s.args) { |
| 178 | + d += ' ' + a |
| 179 | + } |
| 180 | + } |
| 181 | + return d; |
220 | 182 | }
|
221 | 183 | }
|
222 | 184 | }
|
|
0 commit comments