PageSourceSearch

https://renderdiagrams.org/lib/sceneObject_rectangle.js?v=1.0

js renderdiagrams.org collected 2026-10-08 02:13:11 UTC 12,054 bytes, 467 lines download raw bytes

1// ----------------------------------------------------------------------------------------------------------------
2// Rectangle
3// ----------------------------------------------------------------------------------------------------------------
4var lastRectAppearance = new Appearance("#900090", 1, 2);
5
6function Rectangle(center)
7{
8	this.scene				= null;
9	this.points				= [ center.copy(), center.copy(), center.copy(), center.copy() ];
10	this.rows				= 1;
11	this.columns			= 1;
12	this.selected			= false;
13	this.visible			= true;
14	this.frozen				= false;
15	this.appearance			= lastRectAppearance.copy();
16	this.centerPoints		= false;
17	this.onChangeListeners	= [];
18	this.boundsMin			= new Vector(Number.MAX_VALUE,Number.MAX_VALUE);
19	this.boundsMax			= new Vector(-Number.MAX_VALUE,-Number.MAX_VALUE);
20
21	this.getBoundsMin = function()
22	{
23		return this.boundsMin;
24	}
25
26	this.getBoundsMax = function()
27	{
28		return this.boundsMax;
29	}
30
31	this.saveAsJavascript = function()
32	{
33		var str = "var rectObj = new Rectangle(";
34
35		str += "new Vector(0,0)";
36		str += ");\n";
37
38		str += "rectObj.points[0] = new Vector(" + this.points[0].x + ", " + this.points[0].y + ");\n";
39		str += "rectObj.points[1] = new Vector(" + this.points[1].x + ", " + this.points[1].y + ");\n";
40		str += "rectObj.points[2] = new Vector(" + this.points[2].x + ", " + this.points[2].y + ");\n";
41		str += "rectObj.points[3] = new Vector(" + this.points[3].x + ", " + this.points[3].y + ");\n";
42		str += this.appearance.saveAsJavascript("rectObj");
43		str += "rectObj.rows = " + this.rows + ";\n";
44		str += "rectObj.columns = " + this.columns + ";\n";
45		str += "rectObj.centerPoints = " + this.centerPoints + ";\n";
46		str += "rectObj.visible = " + this.visible + ";\n";
47		str += "rectObj.frozen = " + this.frozen + ";\n";
48		
49		if (this.name != undefined)
50		{
51			str += "rectObj.name = \"" + this.name + "\";\n";
52		}
53		
54		str += "rectObj.onChange();\n";
55
56		str += "scene.addObject(rectObj);\n";
57		return str;
58	}
59
60	this.addChangeListener = function (listener)
61	{
62		this.onChangeListeners.push(listener);
63	}
64
65	this.onChange = function(changeDetails)
66	{
67		// Backwards compatibility
68		this.appearance.SetFromOldProperties(this);
69
70		lastRectAppearance = this.appearance.copy();
71
72		var center = avg(this.points[0], this.points[2]);
73		var halfSize = abs(sub(this.points[0], center));
74
75		this.boundsMin = sub(center, halfSize);
76		this.boundsMax = add(center, halfSize);
77
78		for (var i = 0; i != this.onChangeListeners.length; ++i)
79		{
80			this.onChangeListeners[i](this, changeDetails);
81		}
82	}
83
84	this.setSize = function(w,h)
85	{
86		var half = new Vector(w*0.5, h*0.5);
87
88		var center = avg(this.points[0], this.points[2]);
89
90		this.points[0] = add(center, new Vector(-w*0.5, +h*0.5));
91		this.points[1] = add(center, new Vector(+w*0.5, +h*0.5));
92		this.points[2] = add(center, new Vector(+w*0.5, -h*0.5));
93		this.points[3] = add(center, new Vector(-w*0.5, -h*0.5));
94
95		this.onChange();
96	}
97
98	this.draw = function(camera)
99	{
100		camera.drawLineStrip(this.points, true, this.appearance.GetLineColor(), this.appearance.GetLineWidth(this.selected), this.appearance.GetLineDash(), this.appearance.GetFillColor(), this);
101
102		if (this.rows > 1 || this.columns > 1)
103		{
104			var deltaX0 = div(sub(this.points[1], this.points[0]), this.columns);
105			var deltaX1 = div(sub(this.points[2], this.points[3]), this.columns);
106			var deltaY0 = div(sub(this.points[3], this.points[0]), this.rows);
107			var deltaY1 = div(sub(this.points[2], this.points[1]), this.rows);
108
109			var points = [];
110
111			for (var i = 1; i <= this.columns - 1; ++i)
112			{
113				var pX0 = mad(deltaX0, i, this.points[0]);
114				var pX1 = mad(deltaX1, i, this.points[3]);
115
116				points.push(pX0);
117				points.push(pX1);
118			}
119
120			for (var i = 1; i <= this.rows - 1; ++i)
121			{
122				var pY0 = mad(deltaY0, i, this.points[0]);
123				var pY1 = mad(deltaY1, i, this.points[1]);
124
125				points.push(pY0);
126				points.push(pY1);
127			}
128
129			camera.drawLines(points, this.appearance.GetLineColor(), this.appearance.GetLineWidth(this.selected), [], this.appearance.GetFillColor(), this);
130		}
131
132		if (this.centerPoints)
133		{
134			var deltaX0 = div(sub(this.points[1], this.points[0]), this.columns);
135			var deltaY0 = div(sub(this.points[3], this.points[0]), this.rows);
136
137			for (var i = 0.5; i <= this.columns; i += 1)
138			{
139				var pX = mad(deltaX0, i, this.points[0]);
140
141				for (var j = 0.5; j <= this.rows; j += 1)
142				{
143					var pY = mad(deltaY0, j, pX);
144
145					camera.drawCross(pY, camera.invScale(5), 0, "#808080", 2);
146				}
147			}
148		}
149	}
150	
151	this.hitTest = function(a, b, camera)
152	{
153		if (	overlapRectLine(a, b, this.points[0], this.points[1]) ||
154				overlapRectLine(a, b, this.points[1], this.points[2]) ||
155				overlapRectLine(a, b, this.points[2], this.points[3]) ||
156				overlapRectLine(a, b, this.points[3], this.points[0]))
157		{
158			return true;
159		}
160
161		if (this.rows > 1 || this.columns > 1)
162		{
163			var deltaX0 = div(sub(this.points[1], this.points[0]), this.columns);
164			var deltaX1 = div(sub(this.points[2], this.points[3]), this.columns);
165			var deltaY0 = div(sub(this.points[3], this.points[0]), this.rows);
166			var deltaY1 = div(sub(this.points[2], this.points[1]), this.rows);
167
168			for (var i = 1; i <= this.columns - 1; ++i)
169			{
170				var pX0 = mad(deltaX0, i, this.points[0]);
171				var pX1 = mad(deltaX1, i, this.points[3]);
172
173				if (overlapRectLine(a, b, pX0, pX1))
174					return true;
175			}
176
177			for (var i = 1; i <= this.rows - 1; ++i)
178			{
179				var pY0 = mad(deltaY0, i, this.points[0]);
180				var pY1 = mad(deltaY1, i, this.points[1]);
181
182				if (overlapRectLine(a, b, pY0, pY1))
183					return true;
184			}
185		}
186
187		if (this.appearance.fillAlpha > 0)
188		{
189			if (	b.x<this.points[0].x ||
190					a.x>this.points[2].x ||
191					b.y<this.points[2].y ||
192					a.y>this.points[0].y)
193			{
194				return false;
195			}
196
197			return true;
198		}
199
200		return false;
201	}
202	
203	this.getSnapPoints = function()
204	{
205		var points = [	{ type: "node", p: this.points[0] },
206						{ type: "node", p: this.points[1] },
207						{ type: "node", p: this.points[2] },
208						{ type: "node", p: this.points[3] },
209						{ type: "midpoint", p: avg(this.points[0], this.points[1]) },
210						{ type: "midpoint", p: avg(this.points[1], this.points[2]) },
211						{ type: "midpoint", p: avg(this.points[2], this.points[3]) },
212						{ type: "midpoint", p: avg(this.points[3], this.points[0]) },
213						{ type: "center", p: avg(this.points[0], this.points[2]) } ];
214
215		if (this.rows > 1 || this.columns > 1)
216		{
217			var deltaX0 = div(sub(this.points[1], this.points[0]), this.columns);
218			var deltaY0 = div(sub(this.points[3], this.points[0]), this.rows);
219
220			for (var i = 0; i <= this.columns; ++i)
221			{
222				var pX = mad(deltaX0, i, this.points[0]);
223
224				for (var j = 0; j <= this.rows; ++j)
225				{
226					var pY = mad(deltaY0, j, pX);
227
228					if (	((i == 0 || i == (this.columns)) && (j>0 && j<this.rows)) ||
229							((j == 0 || j == (this.rows)) && (i>0 && i<this.columns)) )
230					{
231						points.push({type: "node", p: pY });
232					}
233					else if ( (i>0 && i<this.columns) && (j>0 && j<this.rows) )
234					{
235						points.push({type: "intersection", p: pY });
236					}
237				}
238			}
239		}
240
241
242		if (this.centerPoints)
243		{
244			var deltaX0 = div(sub(this.points[1], this.points[0]), this.columns);
245			var deltaY0 = div(sub(this.points[3], this.points[0]), this.rows);
246
247			for (var i = 0.5; i <= this.columns; i += 1)
248			{
249				var pX = mad(deltaX0, i, this.points[0]);
250
251				for (var j = 0.5; j <= this.rows; j += 1)
252				{
253					var pY = mad(deltaY0, j, pX);
254
255					points.push({type: "node", p: pY });
256				}
257			}
258		}
259
260		return points;
261	}
262
263	this.getDragPoints = function(localSpace, camera)
264	{
265		if (this.isFrozen())
266			return [];
267
268		var points = [	this.points[0],
269						this.points[1],
270						this.points[2],
271						this.points[3],
272						avg(this.points[0], this.points[1]),
273						avg(this.points[1], this.points[2]),
274						avg(this.points[2], this.points[3]),
275						avg(this.points[3], this.points[0])];
276
277		return points;
278	}
279
280	this.drawDragPoint = function(camera, index, position, localSpace, alpha)
281	{
282		if (alpha == undefined)
283			alpha = 1;
284
285		if (index<4)
286		{
287			camera.drawRectangle(this.points[index], camera.invScale(10), "rgba(255,0,0," + alpha + ")", 2);
288		}
289		else
290		{
291			var index0 = index-4;
292			var index1 = (index0+1) % 4;
293
294			var a = avg(this.points[index0], this.points[index1]);
295			var dir = sub(this.points[index1], this.points[index0]).unit().neg();
296			var tan = transpose(dir);
297	
298			var b = add(a, mul(tan, camera.invScale(30)));
299
300			camera.drawArrow(a, b, 8, "rgba(255,0,0," + alpha + ")", 3);
301		}
302	}
303
304	this.setDragPointPos = function(index, p, localSpace, dragStartPoint, camera)
305	{
306		var points = [	this.points[0],
307						this.points[1],
308						this.points[2],
309						this.points[3],
310						avg(this.points[0], this.points[1]),
311						avg(this.points[1], this.points[2]),
312						avg(this.points[2], this.points[3]),
313						avg(this.points[3], this.points[0])];
314
315		if (index < 4)
316		{
317			if (localSpace)
318			{
319				var center = avg(this.points[0], this.points[2]);
320				var halfSize = abs(sub(p, center));
321
322				this.points[0] = sub(center, halfSize);
323				this.points[2] = add(center, halfSize);
324				this.points[1].x = this.points[2].x;
325				this.points[1].y = this.points[0].y;
326				this.points[3].x = this.points[0].x;
327				this.points[3].y = this.points[2].y;
328			}
329			else
330			{
331				this.points[index] = p;
332
333				if (index==0)
334				{
335					this.points[3].x = p.x;
336					this.points[1].y = p.y;
337				}
338				else if (index==1)
339				{
340					this.points[2].x = p.x;
341					this.points[0].y = p.y;
342				}
343				else if (index==2)
344				{
345					this.points[1].x = p.x;
346					this.points[3].y = p.y;
347				}
348				else if (index==3)
349				{
350					this.points[0].x = p.x;
351					this.points[2].y = p.y;
352				}
353			}
354		}
355		else if (index < 8)
356		{
357			if (index==4)
358			{
359				this.points[0].y = p.y;
360				this.points[1].y = p.y;
361			}
362			else if (index==5)
363			{
364				this.points[1].x = p.x;
365				this.points[2].x = p.x;
366			}
367			else if (index==6)
368			{
369				this.points[2].y = p.y;
370				this.points[3].y = p.y;
371			}
372			else if (index==7)
373			{
374				this.points[0].x = p.x;
375				this.points[3].x = p.x;
376			}
377		}
378		else
379		{ }
380
381		if (camera != undefined)
382		{
383			var p0 = this.points[0].copy();
384			var p1 = this.points[2].copy();
385
386			var delta = sub(p1, p0);
387
388			var p = p1.copy();
389			p.x += ((p1.x < p0.x) ? +1 : -1) * camera.invScale(10);
390			p.y += camera.invScale(10);
391
392			camera.drawText(p, "dx: " + delta.x.toFixed(1) + " dy: " + delta.y.toFixed(1), "#000000", (p1.x < p0.x) ? "left" : "right", 0, "12px Arial");
393		}
394
395		this.onChange();
396	}
397
398	this.getOrigin = function()
399	{
400		return this.points[0];
401	}
402	
403	this.setOrigin = function(p)
404	{
405		var delta = sub(p, this.points[0]);
406
407		for (var i = 0; i != 4; ++i)
408		{
409			this.points[i] = add(this.points[i], delta);
410		}
411
412		this.onChange();
413	}
414
415	this.getProperties = function()
416	{
417		var appearanceControl = new PopoutContainer(undefined, "images/color_wheel.svg");
418		{
419			appearanceControl.addControl("", new AppearanceControl(this.appearance, true, true, function(){ this.onChange(); }.bind(this)) );
420		}
421
422		return	[
423					{name: "Appearance", control:appearanceControl },
424					{name: "Rows", control: new PopoutSlider(1, 16, this.rows, 1, function (value) { this.rows = value; this.onChange(); }.bind(this)) },
425					{name: "Columns", control: new PopoutSlider(1, 16, this.columns, 1, function (value) { this.columns = value; this.onChange(); }.bind(this)) },
426					{name: "Center Points", control: new TickBox(this.centerPoints, function (value) { this.centerPoints = value; this.onChange(); }.bind(this)) }
427				];
428	}
429
430	this.toggleVisibility = function(v)
431	{
432		var newVisible = (v!==undefined) ? v : !this.visible;
433		if (this.visible != newVisible)
434		{
435			this.visible = newVisible;
436			this.onChange();
437		}
438	}
439
440	this.isVisible = function()
441	{
442		return this.visible;
443	}
444
445	this.toggleFrozen = function(f)
446	{
447		this.frozen = (f!==undefined) ? f : !this.frozen;
448		this.onChange();
449	}
450
451	this.isFrozen = function()
452	{
453		return this.frozen;
454	}
455
456	this.setSelected = function(selected)
457	{
458		this.selected = selected;
459	}
460
461	this.isSelected = function()
462	{
463		return this.selected;
464	}
465
466	this.onChange();
467}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.