Add new shapes for vertexes.

This commit is contained in:
Oleg Sh 2021-04-15 14:18:47 +02:00
parent 2172acb28f
commit b60e70c089
5 changed files with 230 additions and 13 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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');

View File

@ -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;