1 /*!
  2 *
  3 * RaphaëlTools : Raphaël extension (button, sliders, misc..)
  4 *                    version 0.5.1 (2011-10-06)
  5 *
  6 *                 Copyright (C)  2011  Jan Stransky
  7 *
  8 *      Czech Technical University, Faculty of Civil Engineering,
  9 *  Department of Structural Mechanics, 166 29 Prague, Czech Republic
 10 *
 11 *
 12 *  This program is free software: you can redistribute it and/or modify
 13 *  it under the terms of the GNU General Public License as published by
 14 *  the Free Software Foundation, either version 3 of the License, or
 15 *  (at your option) any later version.
 16 *
 17 *  This program is distributed in the hope that it will be useful,
 18 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 19 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 20 *  GNU General Public License for more details.
 21 *
 22 *  You should have received a copy of the GNU General Public License
 23 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 24 */
 25 
 26 /**
 27 * @fileOverview <a href="http://raphaeljs.com/">Raphaël</a> (svg javascript library) extension by various functions and "classes" (slider, button, etc.). Requires <a href="http://raphaeljs.com/">raphael.js</a> loaded before loading this file. For more information see <a href="http://mech.fsv.cvut.cz/~stransky/software/raphaeltools/">project homepage</a>.
 28 <br /><br/>RaphaëlTools is a free software distributed under <a href='http://www.gnu.org/licenses/gpl.html'>GNU GPL license</a>.
 29 * @author <a href="http://mech.fsv.cvut.cz/~stransky/">Jan Stránský</a>
 30 * @version Version 0.5.1 (2011-10-06)
 31 */
 32 
 33 /** Generic function used for draging ojects. For each dragable object should be defined function dragUpdate(dx,dz): e.g. moving only in x direction etc.
 34 * @param {float} dx x increment of dragging
 35 * @param {float} dz z increment of dragging
 36 * @example
 37 * a = new Arrow(100,59,199,30) // equivalent to a = Arrow.create(100,59,199,30);
 38 * a.dragUpdate = function(dx,dz) { a.translate(dx,dz); }
 39 * a.drag(move,init,reset) // make an object draggable using a.dragUpdate() function when moving*/
 40 function dragMove(dx,dz) {
 41 	this.dragUpdate(dx - (this.deltax || 0), dz - (this.deltaz || 0));
 42 	this.deltax = dx;
 43 	this.deltaz = dz;
 44 }
 45 
 46 /** Generic function used for draging ojects, see {@link dragMove}*/
 47 function dragInit() { this.deltax = this.deltaz = 0; }
 48 
 49 /** Generic function used for draging ojects, see {@link dragMove}*/
 50 function dragReset() { this.dragReset(); }
 51 
 52 
 53 /* ***********************************************************
 54 * other generic functions
 55 ************************************************************/
 56 /** Raphael function loaded from <a href="http://raphaeljs.com">raphael.js file</a>
 57 * @class*/
 58 Raphael = Raphael;
 59 
 60 /** Raphael.el element of {@link Raphael}
 61 * @memberOf Raphael#
 62 */
 63 Raphael.el = Raphael.el;
 64 
 65 /**#@+
 66 * @function
 67 * @memberOf Raphael#
 68 */
 69 // color setting
 70 /** Sets fill color of receiver to red*/     Raphael.el.fillRed     = function() { this.attr({"fill":"#f00"}); }
 71 /** Sets fill color of receiver to green*/   Raphael.el.fillGreen   = function() { this.attr({"fill":"#0f0"}); }
 72 /** Sets fill color of receiver to blue*/    Raphael.el.fillBlue    = function() { this.attr({"fill":"#00f"}); }
 73 /** Sets fill color of receiver to yellow*/  Raphael.el.fillYellow  = function() { this.attr({"fill":"#ff0"}); }
 74 /** Sets fill color of receiver to cyan*/    Raphael.el.fillCyan    = function() { this.attr({"fill":"#0ff"}); }
 75 /** Sets fill color of receiver to magenta*/ Raphael.el.fillMagenta = function() { this.attr({"fill":"#f0f"}); }
 76 /** Sets fill color of receiver to orange*/  Raphael.el.fillOrange  = function() { this.attr({"fill":"#f50"}); }
 77 /** Sets fill color of receiver to black*/   Raphael.el.fillBlack   = function() { this.attr({"fill":"#000"}); }
 78 /** Sets fill color of receiver to white*/   Raphael.el.fillWhite   = function() { this.attr({"fill":"#fff"}); }
 79 /** Sets fill color of receiver to gray*/    Raphael.el.fillGray    = function() { this.attr({"fill":"#777"}); }
 80 /** Sets stroke color of receiver to red*/     Raphael.el.strokeRed     = function() { this.attr({"stroke":"#f00"}); }
 81 /** Sets stroke color of receiver to green*/   Raphael.el.strokeGreen   = function() { this.attr({"stroke":"#0f0"}); }
 82 /** Sets stroke color of receiver to blue*/    Raphael.el.strokeBlue    = function() { this.attr({"stroke":"#00f"}); }
 83 /** Sets stroke color of receiver to yellow*/  Raphael.el.strokeYellow  = function() { this.attr({"stroke":"#ff0"}); }
 84 /** Sets stroke color of receiver to cyan*/    Raphael.el.strokeCyan    = function() { this.attr({"stroke":"#0ff"}); }
 85 /** Sets stroke color of receiver to magenta*/ Raphael.el.strokeMagenta = function() { this.attr({"stroke":"#f0f"}); }
 86 /** Sets stroke color of receiver to orange*/  Raphael.el.strokeOrange  = function() { this.attr({"stroke":"#f50"}); }
 87 /** Sets stroke color of receiver to black*/   Raphael.el.strokeBlack   = function() { this.attr({"stroke":"#000"}); }
 88 /** Sets stroke color of receiver to white*/   Raphael.el.strokeWhite   = function() { this.attr({"stroke":"#fff"}); }
 89 /** Sets stroke color of receiver to gray*/    Raphael.el.strokeGray    = function() { this.attr({"stroke":"#777"}); }
 90 /** Sets fill and stroke color of receiver to red*/     Raphael.el.red     = function() { this.fillRed();     this.strokeRed(); }
 91 /** Sets fill and stroke color of receiver to green*/   Raphael.el.green   = function() { this.fillGreen();   this.strokeGreen(); }
 92 /** Sets fill and stroke color of receiver to blue*/    Raphael.el.blue    = function() { this.fillBlue();    this.strokeBlue(); }
 93 /** Sets fill and stroke color of receiver to yellow*/  Raphael.el.yellow  = function() { this.fillYellow();  this.strokeYellow(); }
 94 /** Sets fill and stroke color of receiver to cyan*/    Raphael.el.cyan    = function() { this.fillCyan();    this.strokeCyan(); }
 95 /** Sets fill and stroke color of receiver to magenta*/ Raphael.el.magenta = function() { this.fillMagenta(); this.strokeMagenta(); }
 96 /** Sets fill and stroke color of receiver to orange*/  Raphael.el.orange  = function() { this.fillOrange();  this.strokeOrange(); }
 97 /** Sets fill and stroke color of receiver to black*/   Raphael.el.black   = function() { this.fillBlack();   this.strokeBlack(); }
 98 /** Sets fill and stroke color of receiver to white*/   Raphael.el.white   = function() { this.fillWhite();   this.strokeWhite(); }
 99 /** Sets fill and stroke color of receiver to gray*/    Raphael.el.gray    = function() { this.fillGreen();   this.strokeGray(); }
100 /** Set width of receiver
101 * @param w new width*/
102 Raphael.el.setWidth = function(w) { this.attr({"stroke-width":w}); }
103 /**#@-*/
104 
105 /** Returns [x,z] components of transformated vector
106 * @param {float} x x component of original vector
107 * @param {float} z z component of original vector
108 * @param {float} sin sin of angle of rotation
109 * @param {float} cos cos of angle of rotation
110 * @returns {[float,float]} coordinates of transformated vector*/
111 vecTrans = function(x,z,sin,cos) { return [x*cos-z*sin,x*sin+z*cos]; }
112 
113 
114 
115 /** 2d xz plane point implementation
116 * @class represents points in 2d zx plane
117 * @param {float} x x coordinate of point
118 * @param {float} z z coordinate of point
119 * @property {float} x x coordinate
120 * @property {float} z z coordinate
121 * @property {[Points2d]} copies array of copies of itself
122 * @property {[[float,float]]} copiesShifts horizontal and verical shifts of copies from receiver*/
123 Point2d = function(x,z) {
124 	this.x = x || 0;
125 	this.z = z || 0;
126 	this.copies = [];
127 	this.copiesShifts = []
128 
129 	/** String representation
130 	* @returns {String} string representation*/
131 	this.toString = function() {
132 		return "Point2d ( "+this.x+","+this.z+" )";
133 	}
134 
135 	/** Copy receiver to given positions
136 	* @param {[[float,float]]} shifts vertical and horizontal shifts of copied points
137 	* @example n = Point2d(100,150);
138 	* shifts=[[100,200],[200,200],[100,300],[200,300]]*/
139 	this.copy = function(shifts) {
140 		for (var i=0; i<shifts.length; i++) {
141 			this.copiesShifts.push(shifts[i]);
142 			this.copies.push(new Point2d(this.x+shifts[i][0],this.z+shifts[i][1]));
143 		}
144 	}
145 
146 	/** Sets new position to receiver
147 	* @param {float} x x coordinate of new position
148 	* @param {float} z z coordinate of new position*/
149 	this.setXZ = function(x,z) {
150 		this.x=x; this.z=z; this.up();
151 	}
152 
153 	/** Set new x coordinate to receiver
154 	* @param x x coordinate of new position*/
155 	this.setX = function(x) {
156 		this.x=x; this.up();
157 	}
158 
159 	/** Set new z coordinate to receiver
160 	* @param z z coordinate of new position*/
161 	this.setZ = function(z) {
162 		this.z=z; this.up();
163 	}
164 
165 	/** Change position of receiver by given values
166 	* @param {float} dx length of translation in x direction
167 	* @param {float} dz length of translation in z direction*/
168 	this.translate = function(dx,dz) {
169 		this.x+=dx; this.z+=dz; this.up();
170 	}
171 
172 	/** Change horizontal position of receiver by given values
173 	* @param {float} dx length of translation in x direction*/
174 	this.translateX = function(dx) {
175 		this.x+=dx; this.up();
176 	}
177 
178 	/** Change vertical position of receiver by given values
179 	* @param {float} dz length of translation in x direction*/
180 	this.translateZ = function(dz) {
181 		this.z+=dz; this.up();
182 	}
183 
184 	/** Update receiver (change positions of stored copies so as stored shifts between receiver and its copies remain constant*/
185 	this.up = function() {
186 		for (var i=0; i<this.copies.length; i++) { this.copies[i].setXZ(this.x+this.copiesShifts[i][0],this.z+this.copiesShifts[i][1]); this.copies[i].up(); }
187 	}
188 }
189 /** Creates new Point2d object, for parameters meaning see {@link Point2d}
190 * @returns {Point2d} new Point2d object*/
191 Point2d.create = function(x,z) {
192 	return new Point2d(x,z);
193 }
194 
195 
196 
197 
198 /** 3d point implementation
199 * @class represents points in 3d space
200 * @param {float} xr x coordinate of point in real space
201 * @param {float} yr y coordinate of point in real space
202 * @param {float} zr z coordinate of point in real space
203 * @property {float} xr x coordinate of point in real space
204 * @property {float} yr y coordinate of point in real space
205 * @property {float} zr z coordinate of point in real space
206 * @property {float} x x coordinate of point in screen projection
207 * @property {float} y y coordinate of point in screen projection (can be used for visibility issues)
208 * @property {float} z z coordinate of point in screen projection
209 * @property {[3x(3 or 4) floats]} p projection matrix
210 * @property {[Points]} copies array of copies of itself
211 * @property {[[float,float]]} copiesShifts horizontal and verical shifts of copies from receiver*/
212 Point3d = function(xr,yr,zr,projection) {
213 	this.xr = xr || 0;
214 	this.yr = yr || 0;
215 	this.zr = zr || 0;
216 	this.copies = [];
217 	this.copiesShifts = []
218 	this.p = projection==undefined? [[1,0,0],[0,1,0],[0,0,1]] : projection;
219 	this.x = this.p[0][0]*this.xr + this.p[0][1]*this.yr + this.p[0][2]*this.zr + (this.p[0][3] || 0);
220 	this.y = this.p[1][0]*this.xr + this.p[1][1]*this.yr + this.p[1][2]*this.zr + (this.p[1][3] || 0);
221 	this.z = this.p[2][0]*this.xr + this.p[2][1]*this.yr + this.p[2][2]*this.zr + (this.p[2][3] || 0);
222 
223 	/** String representation
224 	* @returns {String} string representation*/
225 	this.toString = function() {
226 		return "Point3d ( "+this.xr+","+this.yr+","+this.zr+" )";
227 	}
228 
229 	/** Copy receiver to given positions
230 	* @param {[[float,float,float]]} shifts vertical and horizontal shifts of copied points
231 	* @example n = Point3d(100,150,250);
232 	* shifts=[[100,200,300],[200,200,500],[100,300,100],[200,300,340]]*/
233 	this.copy = function(shifts) {
234 		for (var i=0; i<shifts.length; i++) {
235 			this.copiesShifts.push(shifts[i]);
236 			this.copies.push(new Point3d(this.xr+shifts[i][0],this.yr+shifts[i][1],this.zr+shifts[i][2]));
237 		}
238 	}
239 
240 	/** Sets new position to receiver
241 	* @param {float} xr xr coordinate of new position (in real space)
242 	* @param {float} yr yr coordinate of new position (in real space)
243 	* @param {float} zr zr coordinate of new position (in real space)*/
244 	this.setXYZ = function(xr,yr,zr) {
245 		this.xr=xr; this.yr=yr; this.zr=zr; this.up();
246 	}
247 
248 	/** Set new x coordinate to receiver
249 	* @param x x coordinate of new position (in real space)*/
250 	this.setX = function(xr) {
251 		this.xr=xr; this.up();
252 	}
253 
254 	/** Set new y coordinate to receiver
255 	* @param y y coordinate of new position (in real space)*/
256 	this.setY = function(yr) {
257 		this.yr=yr; this.up();
258 	}
259 
260 	/** Set new z coordinate to receiver
261 	* @param z z coordinate of new position (in real space)*/
262 	this.setZ = function(zr) {
263 		this.zr=zr; this.up();
264 	}
265 
266 	/** Change position of receiver by given values
267 	* @param {float} dx length of translation in x direction (in real space)
268 	* @param {float} dy length of translation in y direction (in real space)
269 	* @param {float} dz length of translation in z direction (in real space)*/
270 	this.translate = function(dx,dy,dz) {
271 		this.xr+=dx; this.zr+=dz; this.yr+=dy; this.up();
272 	}
273 
274 	/** Change horizontal position of receiver by given values
275 	* @param {float} dx length of translation in x direction (in real space)*/
276 	this.translateX = function(dx) {
277 		this.xr+=dx; this.up();
278 	}
279 
280 	/** Change horizontal position of receiver by given values
281 	* @param {float} dy length of translation in y direction (in real space)*/
282 	this.translateY = function(dy) {
283 		this.yr+=dy; this.up();
284 	}
285 
286 	/** Change vertical position of receiver by given values
287 	* @param {float} dz length of translation in x direction (in real space)*/
288 	this.translateZ = function(dz) {
289 		this.zr+=dz; this.up();
290 	}
291 
292 	/** Sets projection matrix
293 	* @param {[2x(3 or 4) floats]} p new projection matrix*/
294 	this.setProjection = function(p) { this.p = p; this.up() }
295 
296 	/** project receiver to xz screen coordinates accordind to this.p*/
297 	this.project = function() {
298 		this.x = this.p[0][0]*this.xr + this.p[0][1]*this.yr + this.p[0][2]*this.zr + (this.p[0][3] || 0);
299 		this.y = this.p[1][0]*this.xr + this.p[1][1]*this.yr + this.p[1][2]*this.zr + (this.p[1][3] || 0);
300 		this.z = this.p[2][0]*this.xr + this.p[2][1]*this.yr + this.p[2][2]*this.zr + (this.p[2][3] || 0);
301 	}
302 
303 	this.rotX = function(a) {
304 		c = Math.cos(a);
305 		s = Math.sin(a);
306 		var p = this.p;
307 		var p10 = p[1][0], p11 = p[1][1], p12 = p[1][2];
308 		var p20 = p[2][0], p21 = p[2][1], p22 = p[2][2];
309 		p[1][0] = p10*c - p20*s;
310 		p[2][0] = p10*s + p20*c;
311 		p[1][1] = p11*c - p21*s;
312 		p[2][1] = p11*s + p21*c;
313 		p[1][2] = p12*c - p22*s;
314 		p[2][2] = p12*s + p22*c;
315 		this.up();
316 	}
317 
318 	this.rotY = function(a) {
319 		c = Math.cos(a);
320 		s = Math.sin(a);
321 		var p = this.p;
322 		var p00 = p[0][0], p01 = p[0][1], p02 = p[0][2];
323 		var p20 = p[2][0], p21 = p[2][1], p22 = p[2][2];
324 		var p = this.p;
325 		p[0][0] = p00*c - p20*s;
326 		p[2][0] = p00*s + p20*c;
327 		p[0][1] = p01*c - p21*s;
328 		p[2][1] = p01*s + p21*c;
329 		p[0][2] = p02*c - p22*s;
330 		p[2][2] = p02*s + p22*c;
331 		this.up();
332 	}
333 
334 	this.rotZ = function(a) {
335 		c = Math.cos(a);
336 		s = Math.sin(a);
337 		var p = this.p;
338 		var p00 = p[0][0], p01 = p[0][1], p02 = p[0][2];
339 		var p10 = p[1][0], p11 = p[1][1], p12 = p[1][2];
340 		p[0][0] = p00*c - p10*s;
341 		p[1][0] = p00*s + p10*c;
342 		p[0][1] = p01*c - p11*s;
343 		p[1][1] = p01*s + p11*c;
344 		p[0][2] = p02*c - p12*s;
345 		p[1][2] = p02*s + p12*c;
346 		this.up();
347 	}
348 
349 	/** Update receiver (change positions of stored copies so as stored shifts between receiver and its copies remain constant*/
350 	this.up = function() {
351 		this.project();
352 		for (var i=0; i<this.copies.length; i++) { this.copies[i].setXYZ(this.xr+this.copiesShifts[i][0],this.yr+this.copiesShifts[i][1],this.zr+this.copiesShifts[i][2]); this.copies[i].up(); }
353 	}
354 
355 	this.up();
356 }
357 /** Creates new Point3d object, for parameters meaning see {@link Point3d}
358 * @returns {Point3d} new Point3d object*/
359 Point3d.create = function(x,y,z,projection) {
360 	return new Point3d(x,y,z,projection);
361 }
362 
363 
364 
365 /** Line given by ax+bz+c=0 clipped in bounding rectangle
366 * @class represents line given by equation clipped in bounding rectangle
367 * @param {Raphael} raphael raphael instance
368 * @param {float} a a in ax+bz+c=0
369 * @param {float} b b in ax+bz+c=0
370 * @param {float} c c in ax+bz+c=0
371 * @param {Point} lt left top corner of bounding rectangle
372 * @param {Point} rb right bottom corner of bounding rectangle (lt.x<rb.x && tl.z<rb.z)
373 * @property {Raphael} raphael Raphael instance
374 * @property {float} a a in ax+bz+c=0
375 * @property {float} b b in ax+bz+c=0
376 * @property {float} c c in ax+bz+c=0
377 * @property {Point} lt left top corner of bounding rectangle
378 * @property {Point} rb right bottom corner of bounding rectangle (lt.x<rb.x && tl.z<rb.z)
379 * @property {Point} point1 1st point of intersection of line with bounding rectangle
380 * @property {Point} point2 2nd point of intersection of line with bounding rectangle
381 * @property {Line} line Line object (see {@link Line})*/
382 LineBR = function(raphael,a,b,c,lt,rb) {
383 	this.raphael = raphael;
384 	this.a = a==undefined? 1. : a;
385 	this.b = b==undefined? 1. : b;
386 	this.c = c==undefined? 1. : c;
387 	this.lt = lt || new Point2d();
388 	this.rb = rb || new Point2d();
389 	this.point1 = new Point2d();
390 	this.point2 = new Point2d();
391 	this.line = new Line(this.raphael,this.point1,this.point2);
392 
393 	/** Sets new a of ax+bz+c=0
394 	*@param {float} a new a in ax+bz+c=0*/
395 	this.setA = function(a) { this.a = a; this.up(); }
396 
397 	/** Sets new a of ax+bz+c=0
398 	*@param {float} a new a in ax+bz+c=0*/
399 	this.setB = function(b) { this.b = b; this.up(); }
400 
401 	/** Sets new a of ax+bz+c=0
402 	*@param {float} a new a in ax+bz+c=0*/
403 	this.setC = function(c) { this.c = c; this.up(); }
404 
405 	/** Sets new a of ax+bz+c=0
406 	*@param {float} a new a in ax+bz+c=0*/
407 	this.setABC = function(a,b,c) { this.a = a; this.b = b; this.c = c; this.up(); }
408 
409 	/** Hide the line*/
410 	this.hide = function() { this.point1.setXZ(-100,-100); this.point2.setXZ(-100,-100); }
411 
412 	/** Finds sections of given line with given bounding rectangle and sets to this.points*/
413 	this.findSections = function() {
414 		var x1,z1,x2,z2;
415 		var a = this.a; var b = this.b; var c = this.c;
416 		var p1 = this.point1; var p2 = this.point2;
417 		var lt = this.lt; var rb = this.rb;
418 		var zmin = lt.z; var zmax = rb.z;
419 		var xmin = lt.x; var xmax = rb.x;
420 		if (a == 0.) {
421 			if (-c/b > zmin && -c/b < zmax) {
422 				p1.setXZ(xmin,-c/b);
423 				p2.setXZ(xmax,-c/b);
424 			}
425 			else { this.hide(); }
426 			return;
427 		}
428 		if (b == 0.) {
429 			if (-c/a > xmin && -c/a < xmax) {
430 				p1.setXZ(-c/a,zmin);
431 				p2.setXZ(-c/a,zmax);
432 			}
433 			else { this.hide(); }
434 			return;
435 		}
436 		x1 = xmin;
437 		x2 = xmax;
438 		z1 = -(a*x1+c)/b;
439 		z2 = -(a*x2+c)/b;
440 		if (z1<zmin && z2<zmin) { this.hide(); return; }
441 		if (z1>zmax && z2>zmax) { this.hide(); return; }
442 		if ((z1>zmin && z1<zmax) && (z2>zmin && z2<zmax)) { p1.setXZ(x1,z1); p2.setXZ(x2,z2); return; }
443 		if ((z1<zmin && z2>zmax) || (z1>zmax && z2<zmin)) {
444 			p1.setXZ(-(b*zmin+c)/a,zmin);
445 			p2.setXZ(-(b*zmax+c)/a,zmax);
446 			return;
447 		}
448 		if (z1 < zmax && z1 > zmin) {
449 			p1.setXZ(x1,z1);
450 			if (z2 < zmin) { p2.setXZ(-(b*zmin+c)/a,zmin); }
451 			else { p2.setXZ(-(b*zmax+c)/a,zmax); }
452 		}
453 		else {
454 			p2.setXZ(x2,z2);
455 			if (z1 < zmin) { p1.setXZ(-(b*zmin+c)/a,zmin); }
456 			else { p1.setXZ(-(b*zmax+c)/a,zmax); }
457 		}
458 	}
459 
460 	/** Update receiver*/
461 	this.up = function() { this.findSections(); this.line.up(); }
462 
463 	this.up();
464 }
465 /** Creates new LineBR object, for parameters meaning see {@link LineBR}
466 * @returns {LineBR} new LineBR object*/
467 LineBR.create = function(raphael,a,b,c,lt,rb) {
468 	return new LineBR(raphael,a,b,c,lt,rb);
469 }
470 
471 
472 
473 
474 
475 /** Line
476 * @class represents line connecting two points
477 * @param {Raphael} raphael raphael instance
478 * @param {Point} point1 1st Point2d
479 * @param {Point} point2 2nd Point2d
480 * @property {Raphael} raphael Raphael instance
481 * @property {Point} point1 first point of line
482 * @property {Point} point2 second point of line
483 * @property {[Lines]} copies array of copies of receiver
484 * @property {[[Points],[Points]]} copiesPoints array of points of copies of receiver
485 * @property {Raphael.el} obj pointer to actual raphael object*/
486 Line = function(raphael,point1,point2) {
487 	this.raphael = raphael;
488 	this.point1 = point1;
489 	this.point2 = point2;
490 	this.copies = [];
491 	this.copiesPoints = [[],[]];
492 	this.obj = null;
493 
494 	/** Sets svg path of receiver*/
495 	this.setPathList = function() { this.pathList = [["M",this.point1.x,this.point1.z],["L",this.point2.x,this.point2.z]]; }
496 	// Create a raphael object and assign it to this.obj
497 	this.makeObj = function() { this.obj = this.raphael.path(this.pathList); }
498 	this.setPathList();
499 	this.makeObj();
500 	// Set this.pathList to this.obj raphael object
501 	this.attrObjPath = function() { this.obj.attr({"path":this.pathList}); }
502 	/** Update receiver (set this.pathList for given internal variables - x,z,angle... - as well as its copies)*/
503 	this.up = function() {
504 		this.setPathList(); this.attrObjPath();
505 		for (var c=0; c<this.copies.length; c++) { this.copies[c].up(); }
506 	}
507 	/** Copy receiver
508 	* @param {[[Points],[Points]]} points points of to be copied lines*/
509 	this.copy = function(points) { // points=[[point1,point2,point3],[point4,point5,point6]] wll make lines 14,25,36
510 		for (var n=0; n<points[0].length; n++) {
511 			this.copiesPoints[0].push(points[0][n]);
512 			this.copiesPoints[1].push(points[1][n]);
513 			this.copies.push(this.makeCopy(points[0][n],points[1][n]));
514 		}
515 		this.up();
516 	}
517 	/** Returns copy of receiver
518 	* @returns {Line} copy of receiver*/
519 	this.makeCopy = function(point1,point2) {
520 		var ret = new Line(this.raphael,point1,point2);
521 		ret.obj.remove();
522 		ret.obj = this.obj.clone();
523 		return ret;
524 	}
525 }
526 /** Creates new Line object, for parameters meaning see {@link Line}
527 * @returns {Line} new Line object*/
528 Line.create = function(raphael,point1,point2) {
529 	return new Line(raphael,point1,point2);
530 }
531 
532 
533 
534 /** Path (for easier modifying)
535 * @class represents svg path
536 * @param {Raphael} raphael raphael instance
537 * @param {Array} pathList path list for raphael path
538 * @property {Raphael} raphael raphael instance
539 * @property {Array} pathList svg array (list) of the object
540 * @property {Raphael.el} obj actual raphael object*/
541 Path = function(raphael,pathList) {
542 	this.pathList = pathList==undefined? [] : pathList;
543 	this.raphael = raphael;
544 	this.obj = this.raphael.path(this.pathList);
545 	// methods
546 	// Set this.pathList to this.obj raphael object
547 	this.attrObjPath = function() { this.obj.attr({"path":this.pathList}); }
548 
549 	/** Sets one specific value in this.pathList (this.pathList[i][j] = val)
550 	* @param {int} i first index
551 	* @param {int} j second index
552 	* @param {float|string} val value to be set*/
553 	this.setItem = function(i,j,val) { this.pathList[i][j] = val; this.attrObjPath(); }
554 
555 	/** Increment one specific value in this.pathList (this.pathList[i][j] = val)
556 	* @param {int} i first index
557 	* @param {int} j second index
558 	* @param {float} val value of incerementation*/
559 	this.iaddItem = function(i,j,val) { this.pathList[i][j] += val; this.attrObjPath(); }
560 
561 	/** Sets new svg line path to receiver
562 	* @param {Array} newPathList newpath list*/
563 	this.setNewPath = function(newPathList) { this.pathList = newPathList; this.attrObjPath(); }
564 }
565 /** Creates new Path object, for parameters meaning see {@link Path}
566 * @returns {Path} new Path object*/
567 Path.create = function(pathList) {
568 	return new Path(pathList);
569 }
570 
571 
572 
573 /** Circle (for easier modifying)
574 * @class represents circle
575 * @param {Raphael} raphael raphael instance
576 * @param {float} [cx=0.] x coordinate of circle center
577 * @param {float} [cz=0.] z coordinate of circle center
578 * @param {float} [r=10.] circle radius
579 * @property {Raphael} raphael raphael instance
580 * @property {float} x x coordinate of circle center
581 * @property {float} z z coordinate of circle center
582 * @property {float} r radius of the circle
583 * @property {Raphael.circle} obj actual raphael object
584 * @property {[Circles]} copies array of copies of receiver
585 * @property {[[float,float]]} copiesShifts array of shifts of copies of receiver*/
586 Circle = function(raphael,x,z,r) {
587 	this.raphael = raphael;
588 	this.x = x==undefined? 0. : x;
589 	this.z = z==undefined? 0. : z;
590 	this.r = r==undefined? 0. : r;
591 	this.copies = [];
592 	this.copiesShifts = [];
593 	this.obj = this.raphael.circle(this.x,this.z,this.r);
594 
595 	/** Sets radius of receiver
596 	* @param {float} r new radius*/
597 	this.setR = function(r) { this.r = r; this.obj.attr({"r":r}); this.up(); }
598 
599 	/** Sets x coordinate of receiver
600 	* @param {float} x new x coordinate*/
601 	this.setX = function(x) { this.x = x; this.obj.attr({"cx":x}); this.up(); }
602 
603 	/** Sets z coordinate of receiver
604 	* @param {float} z new z coordinate*/
605 	this.setZ = function(z) { this.z = z; this.obj.attr({"cy":z}); this.up(); }
606 
607 	/** Sets new coordinates of receiver
608 	* @param {float} x new x coordinate
609 	* @param {float} z new z coordinate*/
610 	this.setXZ = function(x,z) { this.x = x; this.z = z; this.obj.attr({"cx":x,"cy":z}); }
611 
612 	/** Translate along x axis of receiver
613 	* @param {float} dx x distance of translation*/
614 	this.translateX = function(dx) { this.x += dx; this.obj.attr({"cx":this.x}); }
615 
616 	/** Translate along z axis of receiver
617 	* @param {float} dz z distance of translation*/
618 	this.translateZ = function(dz) { this.z += dz; this.obj.attr({"cy":this.z}); }
619 
620 	/** Translate receiver
621 	* @param {float} dx x distance of translation
622 	* @param {float} dz z distance of translation*/
623 	this.translate = function(dx,dz) { this.x += dx; this.z += dz; this.obj.attr({"cx":this.x,"cy":this.z}); }
624 
625 	/** Copy of receiver
626 	* @param {[[float,float]]} shifts shifts of copies*/
627 	this.copy = function(shifts) { for (var i=0; i<shifts.length; i++) { this.copiesShifts.push(shifts[i]); this.copies.push(this.makeCopy()); this.up()} }
628 	this.makeCopy = function() {
629 		var ret = new Circle(this.raphael,this.x,this.z,this.r)
630 		ret.obj.remove();
631 		ret.obj = this.obj.clone();
632 		return ret;
633 	}
634 
635 	/** Update*/
636 	this.up = function() { 
637 		for (var c=0; c<this.copies.length; c++) {
638 			this.copies[c].setXZ(this.x+this.copiesShifts[c][0],this.z+this.copiesShifts[c][1]);
639 			this.copies[c].setR(this.r);
640 		}
641 	}
642 }
643 /** Creates new Circle object, for parameters meaning see {@link Circle}
644 * @returns {Circle} new Circle object*/
645 Circle.create = function(raphael,x,z,r) {
646 	return new Circle(raphael,x,z,r);
647 }
648 
649 
650 
651 
652 /** Ellipse
653 * @class represents ellipse
654 * @param {Raphael} raphael raphael instance
655 * @param {float} [cx=0.] x coordinate of circle center
656 * @param {float} [cz=0.] z coordinate of circle center
657 * @param {float} [a=10.] x semiaxis
658 * @param {float} [b=10.] z semiaxis
659 * @param {float} [angle=0.] rotation
660 * @param {int} [nSeg=0.] number of segments
661 * @property {Raphael} raphael raphael instance
662 * @property {float} cx x coordinate of circle center
663 * @property {float} cz z coordinate of circle center
664 * @property {float} a x semiaxis
665 * @property {float} b z semiaxis
666 * @property {float} angle rotation
667 * @property {int} nSeg number of segments*/
668 Ellipse = function(raphael,cx,cz,a,b,angle,nSeg) {
669 	this.raphael = raphael;
670 	this.cx = cx==undefined? 0. : cx;
671 	this.cz = cz==undefined? 0. : cz;
672 	this.a = a==undefined? 10. : a;
673 	this.b = b==undefined? 10. : b;
674 	this.angle = angle==undefined? 0. : angle;
675 	this.nSeg = nSeg==undefined? 32 : nSeg;
676 	this.pathList = [];
677 	this.obj = this.raphael.path([]);
678 
679 	/** Sets a (x semiaxis) of receiver
680 	* @param {float} r new radius*/
681 	this.setA = function(a) { this.a = a; this.up(); }
682 
683 	/** Sets b (z semiaxis) of receiver
684 	* @param {float} r new radius*/
685 	this.setB = function(b) { this.b = b; this.up(); }
686 
687 	/** Sets a (x semiaxis) and b (z semiaxis) of receiver
688 	* @param {float} a new a (x semiaxis)
689 	* @param {float} b new b (x semiaxis)*/
690 	this.setAB = function(a,b) { this.a = a; this.b = b; this.up(); }
691 
692 	/** Sets x coordinate of center of receiver
693 	* @param {float} cx new x coordinate*/
694 	this.setX = function(cx) { this.cx = cx; this.up(); }
695 
696 	/** Sets z coordinate of center of receiver
697 	* @param {float} cz new z coordinate*/
698 	this.setZ = function(cz) { this.cz = cz; this.up(); }
699 
700 	/** Sets new coordinates of receiver
701 	* @param {float} cx new x coordinate
702 	* @param {float} cz new z coordinate*/
703 	this.setXZ = function(cx,cz) { this.cx = cx; this.cz = cz; this.up(); }
704 
705 	/** Sets new coordinates of receiver and new semiaxes
706 	* @param {float} cx new x coordinate
707 	* @param {float} cz new z coordinate
708 	* @param {float} a new a (x semiaxis)
709 	* @param {float} b new b (x semiaxis)
710 	* @param {float} angle new angle*/
711 	this.setAll = function(cx,cz,a,b,angle) { this.cx = cx; this.cz = cz; this.a = a; this.b = b; this.angle = angle; this.up(); }
712 
713 	/** Sets rotation of receiver
714 	* @param {float} cz new z coordinate*/
715 	this.setAngle = function(angle) { this.angle = angle; this.up(); }
716 
717 	/** Translate along x axis of receiver
718 	* @param {float} dx x distance of translation*/
719 	this.translateX = function(dx) { this.cx += dx; this.up(); }
720 
721 	/** Translate along z axis of receiver
722 	* @param {float} dz z distance of translation*/
723 	this.translateZ = function(dz) { this.cz += dz; this.up(); }
724 
725 	/** Translate receiver
726 	* @param {float} dx x distance of translation
727 	* @param {float} dz z distance of translation*/
728 	this.translate = function(dx,dz) { this.cx += dx; this.cz += dz; this.up(); }
729 
730 	/** Sets svg path of receiver*/
731 	this.setPathList = function() {
732 		this.pathList = [];
733 		var c = Math.cos(this.angle);
734 		var s = Math.sin(this.angle);
735 		var t,xl,zl;
736 		for (var i=0; i<this.nSeg; i++) {
737 			t = i*2*Math.PI/this.nSeg;
738 			xl = this.a*Math.cos(t);
739 			zl = this.b*Math.sin(t);
740 			if (i==0) { this.pathList[0] = ["M",this.cx+c*xl+s*zl,this.cz-s*xl+c*zl]; }
741 			else { this.pathList[i] = ["L",this.cx+c*xl+s*zl,this.cz-s*xl+c*zl]; }
742 		}
743 		this.pathList.push(["Z"]);
744 		this.obj.attr({"path":this.pathList});
745 	}
746 
747 	/** Update*/
748 	this.up = function() { 
749 		this.setPathList();
750 	}
751 
752 	this.up();
753 }
754 /** Creates new Ellipse object, for parameters meaning see {@link Ellipse}
755 * @returns {Circle} new Ellipse object*/
756 Ellipse.create = function(raphael,cx,cz,a,b,angle,nSeg) {
757 	return new Ellipse(raphael,cx,cz,a,b,angle,nSeg);
758 }
759 
760 
761 
762 
763 /** Slider
764 * @class abstract class epresenting generic slider
765 * @param {Raphael} raphael raphael instance
766 * @param {Object} params parameters,see below
767 * @param {float} [params.x=100.] x coordinate of left/upper end
768 * @param {float} [params.z=100.] z coordinate of left/upper end
769 * @param {float} [params.length=100.] length of slider [pixels]
770 * @param {float} [params.rcirc=5.] radius of slider's circle
771 * @param {float} [params.val1=0.] value when the slider is at the very beginning
772 * @param {float} [params.val2=1.] value when the slider is at the very end
773 * @param {float} [params.initVal=(val1+val2)/2] initial value
774 * @param {float} [params.gap=3.] gap between end of the slider's line and the slider's circle when the circle is at extreme position
775 * @property {Raphael} raphael raphael instance
776 * @property {float} x x coordinate of left/upper end
777 * @property {float} z z coordinate of left/upper end
778 * @property {float} len len of slider [pixels]
779 * @property {float} rcirc radius of slider's circle
780 * @property {float} val1 value when the slider is at the very beginning
781 * @property {float} val2 value when the slider is at the very end
782 * @property {float} initVal initial value
783 * @property {float} gap gap between end of the slider's line and the slider's circle when the circle is at extreme position
784 * @property {float} lenVals length span of getable values
785 * @property {Raphael.el} line line
786 * @property {Circle} circ Circle*/
787 Slider = function(raphael,params) {
788 	this.constructorSlider = function(raphael,params) {
789 		this.raphael = raphael;
790 		this.x = params.x==undefined? 100. : params.x;
791 		this.z = params.z==undefined? 100. : params.z;
792 		this.len = params.length==undefined? 100. : params.length;
793 		this.rcirc = params.rcirc==undefined? 5. : params.rcirc;
794 		this.gap = params.gap==undefined? 3. : params.gap;
795 		this.start = this.gap+this.rcirc;
796 		this.stop = this.len - this.start;
797 		this.val1 = params.val1==undefined? 0. : params.val1;
798 		this.val2 = params.val2==undefined? 1. : params.val2;
799 		this.initVal = params.initVal==undefined? .5*(this.val1+this.val2) : params.initVal;
800 		this.lenVals = this.len - 2*this.start;
801 		this.line = this.raphael.rect(this.x,this.z-2,this.len,4).attr({"fill":"#bbb"});
802 		this.circ = new Circle(this.raphael,this.x,this.z,this.rcirc);
803 		this.circ.obj.attr({"cursor":"move","fill":"#f00"})
804 		this.circ.obj.slider = this;
805 		this.circ.obj.circ = this.circ;
806 	}
807 }
808 
809 
810 /** Horizontal slider
811 * @class represents horizontal slider
812 * @param {Raphael} raphael raphael instance
813 * @param {Object} params parameters, see below
814 * @param {float} [params.x=100.] x coordinate of left/upper end
815 * @param {float} [params.z=100.] z coordinate of left/upper end
816 * @param {float} [params.length=100.] length of slider [pixels]
817 * @param {float} [params.rcirc=5.] radius of slider's circle
818 * @param {float} [params.val1=0.] value when the slider is at the very beginning
819 * @param {float} [params.val2=1.] value when the slider is at the very end
820 * @param {float} [params.initVal=(val1+val2)/2] initial value
821 * @param {float} [params.gap=3.] gap between end of the slider's line and the slider's circle when the circle is at extreme position
822 * @property {Raphael} raphael raphael instance
823 * @property {float} x x coordinate of left/upper end
824 * @property {float} z z coordinate of left/upper end
825 * @property {float} len len of slider [pixels]
826 * @property {float} rcirc radius of slider's circle
827 * @property {float} val1 value when the slider is at the very beginning
828 * @property {float} val2 value when the slider is at the very end
829 * @property {float} initVal initial value
830 * @property {float} gap gap between end of the slider's line and the slider's circle when the circle is at extreme position
831 * @property {float} lenVals length span of getable values
832 * @property {Raphael.el} line line
833 * @property {Circle} circ circle*/
834 HorizontalSlider = function(raphael,params) {
835 	this.inheritFrom = Slider; this.inheritFrom();
836 
837 	/** Constructor, see {@link HorizontalSlider} for parameters description*/
838 	this.constructorHorizontalSlider = function(raphael,params) {
839 		this.constructorSlider(raphael,params);
840 		var initPos;
841 		if (this.lenVals<0) {
842 			initPos = this.len*.5;
843 			this.lenVals = 1.;
844 		}
845 		else {
846 			initPos = this.start+this.lenVals/(this.val2-this.val1)*(this.initVal-this.val1);
847 			if (initPos < this.start) { initPos = this.start; }
848 			if (initPos > this.stop)  { initPos = this.stop; }
849 		}
850 		this.circ.setXZ(this.x+initPos,this.z);
851 		this.circ.obj.dragReset = function() { this.slider.pos = this.circ.x; };
852 		this.circ.obj.dragReset();
853 		this.circ.obj.dragUpdate = function(dx,dz) {
854 			this.slider.pos += dx;
855 			if (this.slider.pos >= this.slider.x+this.slider.start && this.slider.pos <= this.slider.x+this.slider.len-this.slider.start) {
856 				this.circ.setX(this.slider.pos);
857 				this.slider.onmove();
858 			}
859 		}
860 		/**@ignore*/
861 		this.circ.obj.drag(dragMove,dragInit,dragReset);
862 	}
863 
864 	/** Get current value from receiver
865 	* @returns {float} current value*/
866 	this.getVal = function() {
867 		var dx = this.circ.x-this.x-this.start;
868 		return this.val1+dx*(this.val2-this.val1)/this.lenVals;
869 	}
870 
871 	/** Set value to receiver
872 	* @param {float} new value*/
873 	this.setVal = function(newVal) {
874 		var newPos;
875 		if (this.lenVals<0) {
876 			newPos = this.len*.5;
877 			this.lenVals = 1.;
878 		}
879 		else {
880 			newPos = this.start+this.lenVals/(this.val2-this.val1)*(newVal-this.val1);
881 			if (newPos < this.start) { newPos = this.start; }
882 			if (newPos > this.stop)  { newPos = this.stop; }
883 		}
884 		this.circ.setXZ(this.x+newPos,this.z);
885 		this.circ.obj.dragReset();
886 	}
887 
888 	/** What to do when moving. Initially empty function, overwrite it by desired actions*/
889 	this.onmove = function() {}
890 
891 	this.constructorHorizontalSlider(raphael,params);
892 }
893 /** Creates new HorizontalSlider object, for parameters meaning see {@link HorizontalSlider}
894 * @returns {HorizontalSlider} new HorizontalSlider object*/
895 HorizontalSlider.create = function(raphael,params) {
896 	return new HorizontalSlider(raphael,params);
897 }
898 
899 
900 
901 /** Button
902 * @class represents button
903 * @param {Raphael} raphael raphael instance
904 * @param {Object} params parameters, see below
905 * @param {string} [params.str="str"] displayed string of button
906 * @param {float} [params.x=100.] x coordinate of left upper end
907 * @param {float} [params.z=100.] z coordinate of left upper end
908 * @param {float} [params.width=100.] length of slider [pixels]
909 * @param {float} [params.height=30.] length of slider [pixels]
910 * @param {float} [params.fontSize=20.] font size of button str
911 * @param {float} [params.rCorner=4.] radius of button corners camber
912 * @param {color} [params.bgColor="#bbb"] background color of button
913 * @param {color} [params.bgColorWhenClicked="#aaa"] background color of button when clicked
914 * @property {Raphael} raphael raphael instance
915 * @property {float} x x coordinate of left upper end
916 * @property {float} z z coordinate of left upper end
917 * @property {float} width length of slider [pixels]
918 * @property {float} height length of slider [pixels]
919 * @property {float} fontSize font size of button text
920 * @property {color} bgColor background color of button
921 * @property {color} bgColorWhenClicked background color of button when clicked
922 * @property {Raphael.rect} rect rectangle of receiver
923 * @property {Raphael.text} text object of receiver*/
924 Button = function(raphael,params) {
925 	this.constructorButton = function(raphael,params) {
926 		this.raphael = raphael;
927 		var str = params.str==undefined? 'str' : params.str;
928 		this.x = params.x==undefined? 100. : params.x;
929 		this.z = params.z==undefined? 100. : params.z;
930 		this.width = params.width==undefined? 100. : params.width;
931 		this.height = params.height==undefined? 30. : params.height;
932 		var fontSize = params.fontSize==undefined? 20. : params.fontSize;
933 		this.bgColor = params.bgColor==undefined? "#bbb" : params.bgColor;
934 		this.bgColorWhenClicked = params.bgColorWhenClicked==undefined? "#aaa" : params.bgColorWhenClicked;
935 		var rCorner = params.rCorner==undefined? 4. : params.rCorner;
936 		this.rect = this.raphael.rect(this.x,this.z,this.width,this.height,rCorner).attr({"fill":this.bgColor,"cursor":"pointer"})
937 		this.rect.button = this;
938 		this.text = this.raphael.text(this.x+.5*this.width,this.z+.5*this.height,str).attr({"font-size":fontSize,"cursor":"pointer"})
939 		this.text.button = this;
940 
941 		/** What to do when clicked. Initially empty function, overwrite it by desired actions*/
942 		this.onclick = function() {}
943 
944 		this.doThisWhenClicked = function() {
945 			this.text.attr({"x":this.x+.5*this.width+2})
946 			this.rect.attr({"fill":this.bgColorWhenClicked})
947 			this.onclick();
948 		}
949 		this.doThisWhenUnclicked = function() {
950 			this.text.attr({"x":this.x+.5*this.width})
951 			this.rect.attr({"fill":this.bgColor})
952 		}
953 		this.rect.mousedown(function(event) {this.button.doThisWhenClicked();})
954 		this.rect.mouseup(function(event) {this.button.doThisWhenUnclicked();})
955 		this.text.mousedown(function(event) {this.button.doThisWhenClicked();})
956 		this.text.mouseup(function(event) {this.button.doThisWhenUnclicked();})
957 		this.rect.mouseout(function(event) {this.button.doThisWhenUnclicked();})
958 		this.text.mouseout(function(event) {this.button.doThisWhenUnclicked();})
959 	}
960 
961 	this.constructorButton(raphael,params);
962 }
963 /** Creates new Button object, for parameters meaning see {@link Button}
964 * @returns {Button} new Button object*/
965 Button.create = function(raphael,params) {
966 	return new Button(raphael,params);
967 }
968 
969 
970 
971 
972 /** Text in rectangular frame
973 * @class represents text in rectangular frame
974 * @param {Raphael} raphael rapheal instance
975 * @param {Object} params parameters, see below
976 * @param {float} [params.x=100.] x coordinate of left lower corner [pixel]
977 * @param {float} [params.z=100.] z coordinate of left lower corner [pixel]
978 * @param {float} [params.width=100.] width [pixel]
979 * @param {float} [params.height=100.] height [pixel]
980 * @param {string} [params.str="string"] string to be shown
981 * @param {float} [params.fontSize=20.] font size
982 * @property {float} x x coordinate of top left corner
983 * @property {float} z z coordinate of top left corner
984 * @property {float} width width of rectangle
985 * @property {float} height height of rectangle
986 * @property {string} str text to display
987 * @property {float} fontSize font size
988 * @property {Raphael.text} text raphael text object
989 * @property {Raphael.rect} rect raphael rect object*/
990 TextRect = function(raphael,params) {
991 
992 	/** Constructor, see {@link TextRect} for parameters description*/
993 	this.constructorTextRect = function(raphael,params) {
994 		this.x = params.x==undefined? 100. : params.x;
995 		this.z = params.z==undefined? 100. : params.z;
996 		this.width = params.width==undefined? 100. : params.width;
997 		this.height = params.height==undefined? 100. : params.height;
998 		this.str = params.str==undefined? "string" : params.str;
999 		this.fontSize = params.fontSize==undefined? 20 : params.fontSize;
1000 		this.rect = raphael.rect(this.x,this.z-this.height,this.width,this.height);
1001 		this.text = raphael.text(this.x+.5*this.width,this.z-.5*this.height,this.str).attr({"font-size":this.fontSize});
1002 	}
1003 
1004 	/** Update receiver (set this.pathList for given internal variables)*/
1005 	this.up = function() {
1006 		this.rect.attr({"x":this.x,"y":(this.z-this.height)});
1007 		this.text.attr({"x":(this.x+.5*this.width),"y":(this.z-.5*this.height),"text":this.str,"font-size":this.fontSize});
1008 	}
1009 
1010 	/** Sets new x position of receiver (this.x = x)
1011 	* @param {float} x new x coordinate [pixel]*/
1012 	this.setX = function(x) { this.x = x; this.up(); }
1013 
1014 	/** Sets new z position of receiver (this.z = z)
1015 	* @param {float} z new z coordinate [pixel]*/
1016 	this.setZ = function(z) { this.z = z; this.up(); }
1017 
1018 	/** Sets new x and z position of receiver (this.x = x; this.z = z)
1019 	* @param {float} x new x coordinate [pixel]
1020 	* @param {float} z new z coordinate [pixel]*/
1021 	this.setXZ = function(x,z) { this.x = x; this.z = z; this.up(); }
1022 
1023 	/** Sets new text of receiver
1024 	* @param {string} str new string*/
1025 	this.setStr = function(str) { this.str = str; this.up(); }
1026 
1027 	this.constructorTextRect(raphael,params);
1028 }
1029 /** Creates new TextRect object, for parameters meaning see {@link TextRect}
1030 * @returns {TextRect} new TextRect object*/
1031 TextRect.create = function(raphael,params) {
1032 	return new TextRect(raphael,params);
1033 }
1034 
1035 
1036 
1037 
1038 
1039