从由独立线创建的形状创建多边形

时间:2016-11-15 22:35:31

标签: javascript svg

我有一组10条线被安排来创建一个形状。这些线是独立的(不连续)。我想通过找到构建多边形的连续点来构建多边形,使其与形状匹配。任何想法?

以下示例:



<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Create Polygon From Lines</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style='padding:10px;font-family:arial'>
<center>
<h4>Create Polygon From Lines</h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
A group of independent lines are connected to form a shape. Create a polygon that matches the shape.
</div>
<table><tr>
<td>
<div style="padding:10px;width:400px;text-align:justify">

<b>Scenerio:</b><br />
The shape is shown dashed:
Lines have been randomly placed and are not contiguous.<br>
We must arrange the points so a polygon can be drawn that matches the shape, i.e, the points must be sequential.
</div>
</td>
<td>
<div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400" overflow="visible">
<g id=lineG fill="none" stroke=black stroke-width=1 stroke-dasharray="4 4" />
<polygon id=myPolygon stroke='blue' fill='none' stroke-width='3' />
</svg>
</div>
</td>
</tr></table>
 <script>
var Lines=[]  //---[x1,y1,x2,y2]---
Lines[0]=[170, 148, 140, 200]
Lines[1]=[140, 200, 170, 251]
Lines[2]=[230, 251, 260, 200]
Lines[3]=[170, 148, 200, 96]
Lines[4]=[230, 251, 200, 303]
Lines[5]=[200, 303, 170, 251]
Lines[6]=[281, 118, 251, 66]
Lines[7]=[251, 66, 200, 96]
Lines[8]=[281, 118, 311, 170]
Lines[9]=[311, 170, 260, 200]

var NS="http://www.w3.org/2000/svg"
//---onLoad---
function placeLines()
{
    for(var k=0;k<Lines.length;k++)
    {
       var line=document.createElementNS(NS,"line")
       line.setAttribute("x1",Lines[k][0])
       line.setAttribute("y1",Lines[k][1])
       line.setAttribute("x2",Lines[k][2])
       line.setAttribute("y2",Lines[k][3])
       lineG.appendChild(line)
    }
}

document.addEventListener("onload",placeLines(),false)

</script>
</body>
</html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

您可以使用polygon属性 points 。在下面的示例中,我只是制作了一个正方形,但您可以根据需要修改点数组...

另请注意,我将其修改为使用array.map() - 它比创建变量更简单,使用该变量作为数组中的索引,然后在每次迭代后递增它。有关详情,请通读these exercises

&#13;
&#13;
<center>
<h4>Create Polygon From Lines</h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
A group of independent lines are connected to form a shape. Create a polygon that matches the shape.
</div>
<table><tr>
<td>
<div style="padding:10px;width:200px;text-align:justify">

<b>Scenerio:</b><br />
The shape is shown dashed:
Lines have been randomly placed and are not contiguous.<br>
We must arrange the points so a polygon can be drawn that matches the shape, i.e, the points must be sequential.
</div>
</td>
<td>
<div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400" overflow="visible">
<g id="shapeG" fill="none" stroke=black stroke-width=1 stroke-dasharray="4 4" />
<polygon id=myPolygon stroke='blue' fill='none' stroke-width='3' />
</svg>
</div>
</td>
</tr></table>
 <script>
var points=[  //figure out the points for your polygon
     [100, 100], // this is a simple square
     [200, 100],
     [200, 200],
     [100, 200]
];
var NS="http://www.w3.org/2000/svg"
//---onLoad---
function placeLines() {
    var polygon=document.createElementNS(NS,"polygon");

    var pointsAttribute = points.map(function(point) {
        return point[0]+' '+point[1];
    }).join(', ');
    polygon.setAttribute("points",pointsAttribute);
    document.getElementById('shapeG').appendChild(polygon);
}

document.addEventListener("onload",placeLines(),false)

</script>
&#13;
&#13;
&#13;

修改

您询问了如何从行列表中计算连续点。我不确定这样做的最佳方法是什么,但一种方法是创建一个linked-list点(也可能被视为图形)。看一下这个例子:

&#13;
&#13;
function Point(value) {
  this.value = value;
  this.next = null;
}
Point.prototype.SetNext = function(nextPoint) {
  this.next = nextPoint;
};

function PointList() {
  this.items = [];
}
PointList.prototype.addOrGet = function(value) {
  var foundPoint = this.items.find(function(item) {
    return item.value == value;
  });
  if (foundPoint) {
    return foundPoint;
  }
  //create new point
  var newPoint = new Point(value);
  this.items.push(newPoint);
  return newPoint;
};
PointList.prototype.GetPointsInOrder = function() {
  var current = this.items[0],
    next, nextPoints = [];
  for (var counter = 0; counter < this.items.length; counter++) {
    next = current.next;
    if (next) {
      nextPoints.push(next.value);
      current = next;
    }
  }
  return nextPoints.join(', ');
}

var Lines = [] //---[x1,y1,x2,y2]---
Lines[0] = [170, 148, 140, 200]
Lines[1] = [140, 200, 170, 251]
Lines[2] = [230, 251, 260, 200]
Lines[3] = [170, 148, 200, 96]
Lines[4] = [230, 251, 200, 303]
Lines[5] = [200, 303, 170, 251]
Lines[6] = [281, 118, 251, 66]
Lines[7] = [251, 66, 200, 96]
Lines[8] = [281, 118, 311, 170]
Lines[9] = [311, 170, 260, 200]

var NS = "http://www.w3.org/2000/svg"

function placeLines() {
  var placedLines = [];
  var polygon = document.createElementNS(NS, "polygon");
  var linePoints = [],
    point1, point2, indexOfPoint1, indexOfPoint2;
  var pointList = new PointList(),
    point1, point2, point1str, point2str;
  for (var k = 0; k < Lines.length; k++) {
    point1str = Lines[k][0] + ' ' + Lines[k][1];
    point2str = Lines[k][2] + ' ' + Lines[k][3];
    point1 = pointList.addOrGet(point1str);
    point2 = pointList.addOrGet(point2str);
    if (!point1.next) {
      point1.SetNext(point2);
    } else if (!point2.next) {
      point2.SetNext(point1);
    }
  }
  polygon.setAttribute("points", pointList.GetPointsInOrder());
  document.getElementById('lineG').appendChild(polygon);
}
document.addEventListener("onload", placeLines(), false);
&#13;
<div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'>
  <svg id="mySVG" width="400" height="400" overflow="visible">
    <g id=lineG fill="none" stroke=black stroke-width=1 stroke-dasharray="4 4" />
    <polygon id=myPolygon stroke='blue' fill='none' stroke-width='3' />
  </svg>
</div>
&#13;
&#13;
&#13;