我正在尝试制作3D六角形,因此它将看起来像3D足球。 在这里,我附上了示例代码,其中我使用D3库绘制了拼写图。
在上图中,我在正投影上绘制了六边形,现在我想像红线一样使它成为3D六边形(红线仅用于最终目标,但最终,当所有六边形都安装在上面时,我将其删除。)
任何帮助将不胜感激。
代码:
var width = 1300,
height = 600,
radius = 60;
var projection_ = d3.geo.orthographic().scale(475).translate([width / 2, height / 2]).clipAngle(90).precision(.1);
var pathOrtho = d3.geo.path().projection(projection_);
var topology = hexTopology(radius, width, height);
var projection = hexProjection(radius);
var path = d3.geo.path().projection(projection).pointRadius(2);;
var graticule = d3.geo.graticule();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("defs").append("path")
.datum({type: "Sphere"})
.attr("id", "sphere")
.attr("d", pathOrtho);
svg.append("use")
.attr("class", "stroke")
.attr("xlink:href", "#sphere");
svg.append("path")
.datum(topojson.mesh(topology, topology.objects.hexagons))
.attr("class", "mesh")
.attr("d", path);
svg.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", pathOrtho);
function hexTopology(radius, width, height) {
var dx = radius * 2 * Math.sin(Math.PI / 3),
dy = radius * 1.5,
m = Math.ceil((height + radius) / dy) + 1,
n = Math.ceil(width / dx) + 1,
geometries = [],
arcs = [];
for (var j = -1; j <= m; ++j) {
for (var i = -1; i <= n; ++i) {
var y = j * 2, x = (i + (j & 1) / 2) * 2;
arcs.push([[x, y - 1], [1, 1]], [[x + 1, y], [0, 1]], [[x + 1, y + 1], [-1, 1]]);
}
}
for (var j = 0, q = 3; j < m; ++j, q += 6) {
for (var i = 0; i < n; ++i, q += 3) {
geometries.push({
type: "Polygon",
arcs: [[q, q + 1, q + 2, ~(q + (n + 2 - (j & 1)) * 3), ~(q - 2), ~(q - (n + 2 + (j & 1)) * 3 + 2)]],
fill: true
});
}
}
return {
transform: {translate: [0, 0], scale: [1, 1]},
objects: {hexagons: {type: "GeometryCollection", geometries: geometries}},
arcs: arcs
};
}
function hexProjection(radius) {
var dx = radius * 2 * Math.sin(Math.PI / 3),
dy = radius * 1.5;
return {
stream: function(stream) {
return {
point: function(x, y) { stream.point(x * dx / 2, (y - (2 - (y & 1)) / 3) * dy / 2); },
lineStart: function() { stream.lineStart(); },
lineEnd: function() { stream.lineEnd(); },
polygonStart: function() { stream.polygonStart(); },
polygonEnd: function() { stream.polygonEnd(); }
};
}
};
}