Open bathoorn opened 1 month ago
I also create a snapshot in the test directory which would look like this
which I know see is slightly tilted :)
You can use this to create panels for your geodesic dome greenhouse so it looks like a globe from the outside
Fantastic! Can we use a better name, though? I know about https://en.wikipedia.org/wiki/Geodesic_polyhedron and https://en.wikipedia.org/wiki/Geodesic_dome but the "geodesic" term on its own is just the shortest path on the surface.
Of course we can. I just needed something to start with. Possibly we can also just add it to the Icosahedron as that is the v1. And then this is the v2. I am still working on making the parent list parametric.
But you can see what it looks like so far here
I was looking further into creating different frequency geodesic spheres when trying to split i triangle length in three parts i do the following:
// icosahedron based class I geodesic sphere
const polyhedron = [
[0, 3, 11],
[0, 5, 3],
[0, 7, 5],
[0, 9, 7],
[0, 11, 9], // North
[2, 11, 3],
[3, 4, 2],
[4, 3, 5],
[5, 6, 4],
[6, 5, 7],
[7, 8, 6],
[8, 7, 9],
[9, 10, 8],
[10, 9, 11],
[11, 2, 10], // Equator
[1, 2, 4],
[1, 4, 6],
[1, 6, 8],
[1, 8, 10],
[1, 10, 2], // South
].map((face) => {
const t = face.map((i) => vertices[i]);
// create 3 polygons from these using centroid and midpoints
const a0 = d3.geoInterpolate(t[0], t[1])(0.33333);
const a1 = d3.geoInterpolate(t[1], t[0])(0.33333);
const b2 = d3.geoInterpolate(t[1], t[2])(0.33333);
const b3 = d3.geoInterpolate(t[2], t[1])(0.33333);
const c4 = d3.geoInterpolate(t[2], t[0])(0.33333);
const c5 = d3.geoInterpolate(t[0], t[2])(0.33333);
const m = d3.geoCentroid({
type: "MultiPoint",
coordinates: t,
});
return [
[t[0], a0, c5],
[c5, m, c4], [c5, a0, m], [a0, a1, m],
[c4, b3, t[2]], [c4, m, b3], [m, b2, b3], [m, a1, b2], [a1, t[1], b2]
];
});
but it looks like it generates some artifacts. Is there a better way to do this?
forgot to include an image of the kind of artifacts
my feeling is that there needs to be a split between 6 and 7 but for some reason there is not.
But it is not related to those triangles.
if I change parents from [-1, 2, 0, 2, 5, 1, 5, 3, 7] to [-1, 2, 0, 2, 5, 1, 5, 6, 7] it will look like this
I think what is happening here is that the triangular faces (in blue) do not correspond to the voronoi cells of their centroids (in red); for instance the top vertex defined for triangle 8 is closer to the centroid of triangle 3.
In fact I don't think we can use the voronoi projection for this geometry, and must instead construct the corresponding polyhedral projection.
(images generated at https://observablehq.com/d/5a8c5a187d98fa01)
ah thanks for these images and all your help in getting me to understand how this works.
so why this worked in the other polyhedrons and not here is because in a geodesic sphere not all triangles are the same shape. That is why the voronoi can run into issues determining the edges. As the distance from the center will not always produce the right face now. This will work if all faces are equal shapes.
I will switch it over to the polyhedral projection.
currently voronoi uses this function to determine which face a coordinate is on
function find0(lambda, phi) {
let d0 = Infinity;
let found = -1;
for (let i = 0; i < faces.length; i++) {
const d = geoDistance(faces[i].site, [lambda, phi]);
if (d < d0) {
d0 = d;
found = i;
}
}
return found;
}
i will do some homework to figure out how to do the calculations for a geodesic sphere.
have a feeling this might help me get there pentaDome_070206.pdf
Exactly: find0
is a (relatively slow) search for the closest center, which only serves geometries that are a voronoi tesselation of the sphere (hence the name of the voronoi projection helper). The most generic method is to run through all faces and return that which "polygonContains" the point. It might be a bit slower, but probably OK.
i will first as quick and dirty try that using this method
lol here they call it the fill-rule but i read it as the Fil-rule fill-rule
i am trying this
function myfind(lambda, phi) {
let found = -1;
let faces = polyhedron.flat().map((face) => [...face, face[0]]);
for (let i = 0; i < faces.length; i++) {
if (d3.polygonContains(faces[i], [lambda, phi])) {
found = i;
}
}
return found;
}
and feeding it into the projection like this
d3.geoPolyhedralVoronoi()
.polygons(polygons)
.parents(parents)
.faceFind(myfind)
.angle(0)
.rotate([108,0])
.scale(131.777)
.center([162, 0]);
but that results in an error: TypeError: Cannot read properties of undefined (reading 'project')
so i might have to go into d3.geoPolyhedral() all the way
Note that d3.polygonContains
is for planar polygons, here we need the equivalent for spherical coordinates ( EDIT: d3.geoPolygonContains
d3.geoContains
).
True and the difference then is that instead of straight lines we are dealing geodesics?
On Wed, 14 Aug 2024, 12:43 Philippe Rivière, @.***> wrote:
Note that d3.polygonContains is for planar polygons, here we need the equivalent for spherical coordinates (d3.geoPolygonContains).
— Reply to this email directly, view it on GitHub https://github.com/d3/d3-geo-polygon/issues/72#issuecomment-2288420758, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFZWJYMNZTEMZO5CO36YRLZRMYEPAVCNFSM6AAAAABLGW5GTSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEOBYGQZDANZVHA . You are receiving this because you authored the thread.Message ID: @.***>
succes! it is called geoContains and it works for any geoJson object.
function myfind(lambda, phi) {
let found = -1;
let faces = polyhedron.flat().map((face) => ({
type: "Polygon",
coordinates: [[...face, face[0]]],
}));
for (let i = 0; i < faces.length; i++) {
if (d3.geoContains(faces[i], [lambda, phi])) {
found = i;
}
}
return found;
}
oops, sorry for the typo! The projection is beautiful!
Using this I can generate a cover for a geodesic dome for a specific geographical location. This one is for Amsterdam. Then Amsterdam will be at the top point. It does I frequency 3 class I dome.
Later this week I will create a pull request for it. Right now I hacked it into the voronoi by replacing the findface function.
Hi,
I was messing around again and created a v2 geoDesic projection. I starts of with the icosahedron and splits up the triangle in sub triangles. For a v2 a triangle is split up into 4 sub triangles.
Here is an example![image](https://github.com/user-attachments/assets/de299a6c-a0d8-401c-af84-66faad3b75cd)
I am currently working on making the projection parametric so geoDesic(2) would create a v2 and geoDesic(3) would create a v3.
If you are interested in adding this I can create a pull request.