使用 javascript 在 SVG 中的大多边形内创建小多边形
Create small polygons inside large polygons in SVG using javascript
我对 SVG 很陌生graphics.I 我正在尝试在 svg 矩形内创建多个 SVG 多边形。
我面临着在大多边形内创建小多边形的挑战。
我的多边形是多边形的,而不仅仅是三角形和矩形。如何获取内部多边形的点,我有父多边形的点以及父子多边形之间的间距
<svg width="120" height="120" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg">
<polygon id="poly_depth1" points="60,20 100,40 100,80 60,100 20,80 20,40" fill="blue"/>
</svg>
考虑上面的例子,我有一个 ID 为 poly_depth1 的多边形,我想在这个 polygon.I 中创建另一个 10px 的多边形,想使用普通 JavaScript 或 D3.The 多边形应保持相同的形状。
points 属性定义多边形每个角的 x 和 y 坐标。如果你想要更小或更大的多边形,你需要增加或减去多边形的 x 和 y 坐标的距离。
<svg width="140" height="140" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg">
<polygon id="poly_depth1" points="60,20 100,40 100,80 60,100 20,80 20,40" fill="blue"/>
<polygon id="poly_depth2" points="60,35 90,50 90,70 60,85 30,70 30,50" fill="red"/>
</svg>
这里有一些代码可以做你想做的事(我相信)。
对于多边形中的每个点,它都会计算一个新点,该新点距离多边形中心更远的指定距离。
然后它使用调整后的点集附加一个新的多边形。
// A reference to the original polygon
var poly1 = document.getElementById("poly_depth1");
// Calculate the average of the x and y coordinates.
// So we have a point inside the polygon
var poly2points = getInsidePolygon(poly1, 10);
// Create a new polygon with the adjusted points
var poly2 = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
poly2.setAttribute("id", "poly_depth2");
poly2.setAttribute("points", poly2points.join(','))
poly1.ownerSVGElement.appendChild(poly2);
function getInsidePolygon(poly, distance)
{
var points = poly.points;
var centre = getCentrePoint(points);
// For each polygon point, move towards the centre point by
// 'distance' and return that point
var result = []
for (var i=0; i<points.numberOfItems; i++) {
var pt = points.getItem(i);
var adjustedPt = getPointAlongLine(pt.x, pt.y, centre.x, centre.y, distance);
result.push(adjustedPt.x.toFixed(4));
result.push(adjustedPt.y.toFixed(4));
}
return result;
}
function getCentrePoint(points)
{
// Average all the X and Y points to get the polygon centre point
var midX = 0, midY = 0;
for (var i=0; i<points.numberOfItems; i++) {
var pt = points.getItem(i);
midX += pt.x;
midY += pt.y;
}
return {
x: midX / points.numberOfItems,
y: midY / points.numberOfItems
}
}
function getPointAlongLine(x1, y1, x2, y2, distance)
{
// Return the point that is "distance" along the line from x1,y1 to x2,y2.
var dx = x2 - x1;
var dy = y2 - y1;
var len = Math.sqrt(dx * dx + dy * dy);
return {
x: x1 + dx * (distance / len),
y: y1 + dy * (distance / len)
}
}
#poly_depth2 {
fill: red;
fill-opacity: 0.4;
}
<svg width="240" height="240" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg">
<polygon id="poly_depth1" points="60,20 100,40 100,80 60,100 20,80 20,40" fill="blue"/>
</svg>
我对 SVG 很陌生graphics.I 我正在尝试在 svg 矩形内创建多个 SVG 多边形。
我面临着在大多边形内创建小多边形的挑战。
我的多边形是多边形的,而不仅仅是三角形和矩形。如何获取内部多边形的点,我有父多边形的点以及父子多边形之间的间距
<svg width="120" height="120" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg">
<polygon id="poly_depth1" points="60,20 100,40 100,80 60,100 20,80 20,40" fill="blue"/>
</svg>
考虑上面的例子,我有一个 ID 为 poly_depth1 的多边形,我想在这个 polygon.I 中创建另一个 10px 的多边形,想使用普通 JavaScript 或 D3.The 多边形应保持相同的形状。
points 属性定义多边形每个角的 x 和 y 坐标。如果你想要更小或更大的多边形,你需要增加或减去多边形的 x 和 y 坐标的距离。
<svg width="140" height="140" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg">
<polygon id="poly_depth1" points="60,20 100,40 100,80 60,100 20,80 20,40" fill="blue"/>
<polygon id="poly_depth2" points="60,35 90,50 90,70 60,85 30,70 30,50" fill="red"/>
</svg>
这里有一些代码可以做你想做的事(我相信)。
对于多边形中的每个点,它都会计算一个新点,该新点距离多边形中心更远的指定距离。
然后它使用调整后的点集附加一个新的多边形。
// A reference to the original polygon
var poly1 = document.getElementById("poly_depth1");
// Calculate the average of the x and y coordinates.
// So we have a point inside the polygon
var poly2points = getInsidePolygon(poly1, 10);
// Create a new polygon with the adjusted points
var poly2 = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
poly2.setAttribute("id", "poly_depth2");
poly2.setAttribute("points", poly2points.join(','))
poly1.ownerSVGElement.appendChild(poly2);
function getInsidePolygon(poly, distance)
{
var points = poly.points;
var centre = getCentrePoint(points);
// For each polygon point, move towards the centre point by
// 'distance' and return that point
var result = []
for (var i=0; i<points.numberOfItems; i++) {
var pt = points.getItem(i);
var adjustedPt = getPointAlongLine(pt.x, pt.y, centre.x, centre.y, distance);
result.push(adjustedPt.x.toFixed(4));
result.push(adjustedPt.y.toFixed(4));
}
return result;
}
function getCentrePoint(points)
{
// Average all the X and Y points to get the polygon centre point
var midX = 0, midY = 0;
for (var i=0; i<points.numberOfItems; i++) {
var pt = points.getItem(i);
midX += pt.x;
midY += pt.y;
}
return {
x: midX / points.numberOfItems,
y: midY / points.numberOfItems
}
}
function getPointAlongLine(x1, y1, x2, y2, distance)
{
// Return the point that is "distance" along the line from x1,y1 to x2,y2.
var dx = x2 - x1;
var dy = y2 - y1;
var len = Math.sqrt(dx * dx + dy * dy);
return {
x: x1 + dx * (distance / len),
y: y1 + dy * (distance / len)
}
}
#poly_depth2 {
fill: red;
fill-opacity: 0.4;
}
<svg width="240" height="240" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg">
<polygon id="poly_depth1" points="60,20 100,40 100,80 60,100 20,80 20,40" fill="blue"/>
</svg>