mirror of
https://github.com/UnickSoft/graphonline.git
synced 2025-07-03 00:06:40 +00:00
Add new shapes for vertexes.
This commit is contained in:
parent
2172acb28f
commit
b60e70c089
@ -151,38 +151,79 @@ BaseEdge.prototype.GetEdgePositionsShift = function()
|
||||
|
||||
BaseEdge.prototype.GetEdgePositions = function()
|
||||
{
|
||||
var res = [];
|
||||
|
||||
if (this.vertex1 == this.vertex2)
|
||||
{
|
||||
res.push(this.vertex1.position);
|
||||
res.push(this.vertex2.position);
|
||||
return res;
|
||||
}
|
||||
|
||||
var position1 = this.vertex1.position;
|
||||
var position2 = this.vertex2.position;
|
||||
var diameter1 = this.vertex1.model.diameter + parseInt(this.vertex1.currentStyle.lineWidth);
|
||||
var diameter2 = this.vertex2.model.diameter + parseInt(this.vertex2.currentStyle.lineWidth);
|
||||
var diameter1 = this.vertex1.model.diameter + parseInt(this.vertex1.currentStyle.GetStyle({}).lineWidth);
|
||||
var diameter2 = this.vertex2.model.diameter + parseInt(this.vertex2.currentStyle.GetStyle({}).lineWidth);
|
||||
|
||||
var direction = position1.subtract(position2);
|
||||
|
||||
var direction1 = direction;
|
||||
var direction2 = direction;
|
||||
var d1 = diameter1;
|
||||
var d2 = -diameter2;
|
||||
var d2 = diameter2;
|
||||
|
||||
if (this.model.type == EdgeModels.cruvled)
|
||||
{
|
||||
var dist = position1.distance(position2);
|
||||
var point1 = this.model.GetCurvedPoint(position1, position2, 10.0 / dist);
|
||||
direction1 = position1.subtract(point1);
|
||||
direction1 = position1.subtract(point1);
|
||||
|
||||
var point2 = this.model.GetCurvedPoint(position1, position2, 1.0 - 10.0 / dist);
|
||||
direction2 = position2.subtract(point2);
|
||||
|
||||
d2 = diameter2;
|
||||
}
|
||||
else
|
||||
{
|
||||
direction2 = direction2.multiply(-1);
|
||||
}
|
||||
|
||||
direction1.normalize(1.0);
|
||||
direction1 = direction1.multiply(0.5);
|
||||
direction2.normalize(1.0);
|
||||
direction2 = direction2.multiply(0.5);
|
||||
|
||||
var res = [];
|
||||
res.push(position1.subtract(direction1.multiply(d1)));
|
||||
res.push(position2.subtract(direction2.multiply(d2)));
|
||||
var vertexes = [];
|
||||
vertexes.push({vertex : this.vertex1, direction : direction1, position : position1, diameter : d1});
|
||||
vertexes.push({vertex : this.vertex2, direction : direction2, position : position2, diameter : d2});
|
||||
|
||||
vertexes.forEach(function(data)
|
||||
{
|
||||
var shape = data.vertex.currentStyle.GetStyle({}).shape;
|
||||
if (shape == VertexCircleShape)
|
||||
{
|
||||
var direction = data.direction.multiply(0.5);
|
||||
|
||||
res.push(data.position.subtract(direction.multiply(data.diameter)));
|
||||
}
|
||||
else if (shape == VertexSquareShape || shape == VertexTriangleShape)
|
||||
{
|
||||
var lineFinish1 = data.direction.multiply(-1).multiply(1000.0);
|
||||
|
||||
var pointsVertex1 = shape == VertexSquareShape ? GetSquarePoints(data.diameter) : GetTrianglePoints(data.diameter);
|
||||
pointsVertex1.push(pointsVertex1[0]);
|
||||
|
||||
for (var i = 0; i < pointsVertex1.length - 1; i ++)
|
||||
{
|
||||
var hitText = Point.hitTest(new Point(0, 0), lineFinish1, pointsVertex1[i], pointsVertex1[i + 1]);
|
||||
if (hitText != null)
|
||||
{
|
||||
res.push(data.position.add(hitText));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -77,3 +77,46 @@ BaseVertex.prototype.IsUndefinedPosition = function ()
|
||||
{
|
||||
return this.hasUndefinedPosition;
|
||||
}
|
||||
|
||||
BaseVertex.prototype.HitTest = function (pos)
|
||||
{
|
||||
var shape = this.hasOwnProperty('currentStyle') ? this.currentStyle.GetStyle({}).shape : VertexCircleShape;
|
||||
var width = this.hasOwnProperty('currentStyle') ? this.currentStyle.GetStyle({}).lineWidth : 0;
|
||||
|
||||
if (shape == VertexCircleShape)
|
||||
{
|
||||
return this.position.distance(pos) < this.model.diameter / 2.0 + width;
|
||||
}
|
||||
else if (shape == VertexSquareShape || shape == VertexTriangleShape)
|
||||
{
|
||||
var relativPos = (new Point(pos.x, pos.y)).subtract(this.position);
|
||||
var lineFinish1 = relativPos.add(new Point(1000, 0));
|
||||
var lineFinish2 = relativPos.add(new Point(-1000, 0));
|
||||
|
||||
var pointsVertex1 = shape == VertexSquareShape ? GetSquarePoints(this.model.diameter + width) : GetTrianglePoints(this.model.diameter + width);
|
||||
pointsVertex1.push(pointsVertex1[0]);
|
||||
|
||||
var hitNumber1 = 0;
|
||||
var hitNumber2 = 0;
|
||||
|
||||
console.log("Points");
|
||||
for (var i = 0; i < pointsVertex1.length - 1; i ++)
|
||||
{
|
||||
console.log(pointsVertex1[i] + " " + pointsVertex1[i + 1]);
|
||||
var hitTest = Point.hitTest(relativPos, lineFinish1, pointsVertex1[i], pointsVertex1[i + 1]);
|
||||
if (hitTest != null)
|
||||
{
|
||||
hitNumber1++;
|
||||
}
|
||||
hitTest = Point.hitTest(relativPos, lineFinish2, pointsVertex1[i], pointsVertex1[i + 1]);
|
||||
if (hitTest != null)
|
||||
{
|
||||
hitNumber2++;
|
||||
}
|
||||
}
|
||||
|
||||
return hitNumber1 == 1 && hitNumber2 == 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -3,6 +3,41 @@
|
||||
*/
|
||||
|
||||
// Test graph: http://localhost:8080/?graph=oimDPgsdgiAjWGBHZZcst
|
||||
|
||||
|
||||
// Vertex shape
|
||||
const VertexCircleShape = 0,
|
||||
VertexSquareShape = 1,
|
||||
VertexTriangleShape = 2;
|
||||
|
||||
function GetSquarePoints(diameter)
|
||||
{
|
||||
var res = [];
|
||||
|
||||
var a = diameter;
|
||||
res.push(new Point(-a / 2, - a / 2));
|
||||
res.push(new Point(a / 2, -a / 2));
|
||||
res.push(new Point(a / 2, a / 2));
|
||||
res.push(new Point(-a / 2, a / 2));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function GetTrianglePoints(diameter)
|
||||
{
|
||||
var res = [];
|
||||
|
||||
var effectiveDiameter = diameter * 1.5;
|
||||
var upOffset = effectiveDiameter / 2;
|
||||
var downOffset = effectiveDiameter / 4;
|
||||
var lrOffset = effectiveDiameter * 3 / (Math.sqrt(3) * 4);
|
||||
|
||||
res.push(new Point(0, - upOffset));
|
||||
res.push(new Point(lrOffset, downOffset));
|
||||
res.push(new Point(- lrOffset, downOffset));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function BaseVertexStyle()
|
||||
{
|
||||
@ -24,7 +59,10 @@ BaseVertexStyle.prototype.GetStyle = function (baseStyle)
|
||||
baseStyle.fillStyle = this.fillStyle;
|
||||
if (this.hasOwnProperty('mainTextColor'))
|
||||
baseStyle.mainTextColor = this.mainTextColor;
|
||||
if (this.hasOwnProperty('shape'))
|
||||
baseStyle.shape = this.shape;
|
||||
|
||||
baseStyle.lineWidth = parseInt(baseStyle.lineWidth);
|
||||
return baseStyle;
|
||||
}
|
||||
|
||||
@ -42,6 +80,7 @@ function CommonVertexStyle()
|
||||
this.strokeStyle = '#c7b7c7';
|
||||
this.fillStyle = '#68aeba';
|
||||
this.mainTextColor = '#f0d543';
|
||||
this.shape = VertexCircleShape;//VertexSquareShape;
|
||||
|
||||
this.baseStyles = [];
|
||||
}
|
||||
@ -219,7 +258,10 @@ BaseVertexDrawer.prototype.Draw = function(baseGraph, graphStyle)
|
||||
{
|
||||
this.SetupStyle(graphStyle);
|
||||
this.DrawShape(baseGraph);
|
||||
this.context.stroke();
|
||||
|
||||
if (this.currentStyle.lineWidth != 0)
|
||||
this.context.stroke();
|
||||
|
||||
this.context.fill();
|
||||
|
||||
this.DrawCenterText(baseGraph.position, baseGraph.mainText, graphStyle.mainTextColor, graphStyle.fillStyle, true, true, 16);
|
||||
@ -236,6 +278,7 @@ BaseVertexDrawer.prototype.Draw = function(baseGraph, graphStyle)
|
||||
|
||||
BaseVertexDrawer.prototype.SetupStyle = function(style)
|
||||
{
|
||||
this.currentStyle = style;
|
||||
this.context.lineWidth = style.lineWidth;
|
||||
this.context.strokeStyle = style.strokeStyle;
|
||||
this.context.fillStyle = style.fillStyle;
|
||||
@ -244,7 +287,35 @@ BaseVertexDrawer.prototype.SetupStyle = function(style)
|
||||
BaseVertexDrawer.prototype.DrawShape = function(baseGraph)
|
||||
{
|
||||
this.context.beginPath();
|
||||
this.context.arc(baseGraph.position.x, baseGraph.position.y, baseGraph.model.diameter / 2.0, 0, 2 * Math.PI);
|
||||
if (this.currentStyle.shape == VertexCircleShape)
|
||||
{
|
||||
this.context.arc(baseGraph.position.x, baseGraph.position.y, baseGraph.model.diameter / 2.0, 0, 2 * Math.PI);
|
||||
}
|
||||
else if (this.currentStyle.shape == VertexSquareShape)
|
||||
{
|
||||
var points = GetSquarePoints(baseGraph.model.diameter);
|
||||
|
||||
this.context.moveTo(baseGraph.position.x + points[points.length - 1].x, baseGraph.position.y + points[points.length - 1].y);
|
||||
|
||||
var context = this.context;
|
||||
|
||||
points.forEach(function(point) {
|
||||
context.lineTo(baseGraph.position.x + point.x, baseGraph.position.y + point.y);
|
||||
});
|
||||
}
|
||||
else if (this.currentStyle.shape == VertexTriangleShape)
|
||||
{
|
||||
var points = GetTrianglePoints(baseGraph.model.diameter)
|
||||
|
||||
this.context.moveTo(baseGraph.position.x + points[points.length - 1].x, baseGraph.position.y + points[points.length - 1].y);
|
||||
|
||||
var context = this.context;
|
||||
|
||||
points.forEach(function(point) {
|
||||
context.lineTo(baseGraph.position.x + point.x, baseGraph.position.y + point.y);
|
||||
});
|
||||
}
|
||||
|
||||
this.context.closePath();
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ BaseHandler.prototype.GetSelectedGraph = function(pos)
|
||||
var res = null;
|
||||
for (var i = 0; i < this.app.graph.vertices.length; i ++)
|
||||
{
|
||||
if (this.app.graph.vertices[i].position.distance(pos) < this.app.graph.vertices[i].model.diameter / 2.0)
|
||||
if (this.app.graph.vertices[i].HitTest(pos))
|
||||
{
|
||||
// Select last of them.
|
||||
res = this.app.graph.vertices[i];
|
||||
@ -1376,7 +1376,7 @@ SetupVertexStyle.prototype.show = function(index)
|
||||
style.mainTextColor = $( "#vertexTextColor" ).val();
|
||||
|
||||
if (fullStyle.lineWidth != $( "#vertexStrokeSize" ).val())
|
||||
style.lineWidth = $( "#vertexStrokeSize" ).val();
|
||||
style.lineWidth = parseInt($( "#vertexStrokeSize" ).val());
|
||||
|
||||
var canvas = document.getElementById( "VertexPreview" );
|
||||
var context = canvas.getContext('2d');
|
||||
|
@ -95,6 +95,11 @@ Point.prototype.inverse = function()
|
||||
{
|
||||
return new Point(-this.x, -this.y);
|
||||
};
|
||||
|
||||
Point.prototype.cross = function(point)
|
||||
{
|
||||
return this.x * point.y - this.y * point.x;
|
||||
};
|
||||
|
||||
Point.interpolate = function(pt1, pt2, f){
|
||||
return new Point(pt1.x * (1.0 - f) + pt2.x * f, pt1.y * (1.0 - f) + pt2.y * f);
|
||||
@ -116,6 +121,63 @@ Point.toString = function(){
|
||||
return x + " " + y;
|
||||
}
|
||||
|
||||
Point.projection = function (point, line1, line2)
|
||||
{
|
||||
var x = line2.y - line1.y;
|
||||
var y = line1.x - line2.x;
|
||||
var l = (line1.cross(line2) + line1.cross(point) + line2.cross(point))/(x*(line2.y - line1.y) + y*(line1.x - line2.x));
|
||||
var res = new Point(point.x + x * l, point.y + y * l);
|
||||
return res;
|
||||
}
|
||||
|
||||
Point.hitTest = function (pt11, pt12, pt21, pt22)
|
||||
{
|
||||
var res = null;
|
||||
var n = 0.0;
|
||||
|
||||
var x1 = pt11.x;
|
||||
var y1 = pt11.y;
|
||||
var x2 = pt12.x;
|
||||
var y2 = pt12.y;
|
||||
var x3 = pt21.x;
|
||||
var y3 = pt21.y;
|
||||
var x4 = pt22.x;
|
||||
var y4 = pt22.y;
|
||||
|
||||
if (y2 - y1 != 0.0)
|
||||
{ // a(y)
|
||||
var q = (x2 - x1) / (y1 - y2);
|
||||
var sn = (x3 - x4) + (y3 - y4) * q;
|
||||
if (sn == 0.0)
|
||||
{
|
||||
return res;
|
||||
} // c(x) + c(y)*q
|
||||
|
||||
var fn = (x3 - x1) + (y3 - y1) * q; // b(x) + b(y)*q
|
||||
n = fn / sn;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((y3 - y4) == 0.0)
|
||||
{
|
||||
return res;
|
||||
} // b(y)
|
||||
n = (y3 - y1) / (y3 - y4); // c(y)/b(y)
|
||||
}
|
||||
|
||||
// x3 + (-b(x))*n && y3 +(-b(y))*n
|
||||
res = new Point(x3 + (x4 - x3) * n, y3 + (y4 - y3) * n);
|
||||
|
||||
var epsilon = 1E-5;
|
||||
if (! (res.x >= Math.min(x1, x2) - epsilon && res.x >= Math.min(x3, x4) - epsilon && res.x <= Math.max(x1, x2) + epsilon && res.x <= Math.max(x3, x4) + epsilon &&
|
||||
res.y >= Math.min(y1, y2) - epsilon && res.y >= Math.min(y3, y4) - epsilon && res.y <= Math.max(y1, y2) + epsilon && res.y <= Math.max(y3, y4) + epsilon))
|
||||
{
|
||||
res = null;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function Rect(minPoint, maxPoint){
|
||||
this.minPoint = minPoint;
|
||||
this.maxPoint = maxPoint;
|
||||
|
Loading…
x
Reference in New Issue
Block a user