It is indeed as Harlan says, there are many erroneous problems that were arising with the edge cases of the range functions. I have a particularly puzzling question to ask at the end of this message, related to this (perhaps connected to the arrange function). Regarding the phi/theta overlapping ranges, I deliberately left those temporary fixes in as I knew there was much more work to address with the ranges and figuring out how to get the loops to look around, past the edges of the lists. I have figured out how to stitch these borders seamlessly and get the vertices/quads to look around past the edge of the lists. I needed to include some logic to these phi/theta ranges so that a duplicate point didn't exist at the borders when doing this stitching process. I have fully included my changes into the program I linked above which I will link again
here.
There is one last issue regarding these borders which I have no clue how to fix at the moment. If you look at the model I have, you will immediately see it on the left of the Klein bottle, at the arm, I will call it. The top of this arm, the direction where it curves nicely, is the start of the meshgrid. The bottom of this arm, towards the fun Klein bottle inversion, is the end of the meshgrid. This boundary which joins at the arm tries to stitch the start and end of the meshgrid, like taping Duct tape to itself. The issue arises with the fact that the Klein bottle ends up inverting the sides of the meshgrid matrix, similar to how a Mobius strip looks. If you turn the opacity down, you can see further details as to what is happening inside of this boundary. It performs a weird reach around on this last set of points at the end of the meshgrid, to connect meshgrid verts (as if there were no inversion from a Mobius strip element, so another inversion).
One solution to skirt past this is reintroducing the normal calculations I featured originally. These calculations were completely wrong as it was averaging the initialized normal vector, which was vec(0,1,0). As a consequence, all vertices had the same normal vector and produced this weird gloss. If you use this, it completely scrubs over the problematic area at the arm of the bottle, but looks horrible and is incorrect. I am not sure how to smooth this boundary, without simply leaving a thin border line there.
Weirdly enough, the program will break down when you try to use resolution = 50, but it seems to work for every other value I pass into it. From testing, when the program makes a linspace array at this resolution value, it creates a length 51 array, not a length 50 array, which you would expect. I see that in the linspace definition, the [stop] is added onto the end, as Harlan points out, to reinclude this edge value which would otherwise be skipped. For some reason, and this only occurs with resolution=50 in the following code,
resolution = 50
theta = np.linspace(0, pi * (1 - 1/(2 * resolution)), resolution)
phi = np.linspace(0, 2 * pi * ( 1 - 1/resolution), resolution)
print(phi.shape, theta.shape)
the array phi has shape [51], while the array theta has shape [50] as to be expected. My intuition was that it has something to do with the (num - 1) in the linspace method but I couldn't derive a fix at all. This wasn't a problem I encountered before, until after I added the (1-1/resolution) term. I've been running the program with resolution 56 as an arbitrary side skirt.
Best,
- Maximillian