Plotting 3D geometric shapes

79 views
Skip to first unread message

Zeger Hendrikse

unread,
Jan 21, 2025, 8:05:38 AMJan 21
to Glowscript Users
Hi everyone,

I have been able to implement some kind of "matlab-numpy" like classes, that let me plot arbitrary complex geometric surfaces. Or at least, so it seems. Thus far, everything I threw at it rendered according to expectations. For example:

As already mentioned in the thread on Klein's bottle, there are still some details lacking:
  • Stitching is clearly visible
  • Lights are suboptimally placed
Perhaps anybody is willing/able to help me out and/or work together on this? If not, I'll stop working on further improvements for now, as I'm working on other visualizations as well, and I'm pretty happy with the results thus far already ;-)

Kind regards,

Zeger Hendrikse

Bruce Sherwood

unread,
Jan 21, 2025, 1:53:21 PMJan 21
to Glowscript Users
Very beautiful!

Bruce

Max DeMarr

unread,
Jan 21, 2025, 11:06:42 PMJan 21
to Glowscript Users
This is very interesting work,

The nj package has certainly opened up my eyes to potential use cases and I am certainly invested in this work. I took a stab at smoothing the Klein bottle edges a little and this is what I have so far Klein Bottle Edit1.

To detail some of the changes I added:
  1. The Klein bottle exists as a single subplot entity now, not two unique ones for the boundary separation.
  2. Tweaked the theta/phi ranges but this proved inconclusive with changes in resolution.
  3. Added concatenate method to the Numpy class.
  4. Added opacity and shininess sliders/methods. The opacity incorporation proved fruitful but the shininess incorporation didn't work at all even though it should have been the same implementation as the opacity function. I am unsure what went wrong there.
  5. Modified numerous range edge cases to work off of the shapes of the meshgrids instead of solely the length of the meshgrids. For a more detailed understanding, you will have to look at many of the contents of the ranges as the meshgrids are no longer shape [resolution, resolution] and are instead [resolution, 2 x resolution].
  6. Tweaked the _set_vertex_normal_for() method to use a smoothing of the neighboring normal values. This change alone is what results in the lack of any depth you see in the Klein bottle I have. I do not like this lack of shading, and I need to work on a different method that still smooths the joints nicely.
I have not tested how/if this works with your Twisted and Double torus yet. I have ideas for further boundary stitching but it is getting late for me and I will need to work on it tomorrow.

Best,

Maximillian

On Tuesday, January 21, 2025 at 12:53:21 PM UTC-6 Bruce Sherwood wrote:
Very beautiful!

Bruce

Zeger Hendrikse

unread,
Jan 23, 2025, 7:53:24 AMJan 23
to Glowscript Users
Hi  Maximillian,

First of all I would like to say I'm excited to see somebody else taking a serious look at my work.

I'm also very happy with the fact that you managed to get the Klein bottle into a single subplot. I can now unify two programs, which I had to maintain separately until now!!

Speaking of which, I did not share that program, as the plot logic is identical, but it comes with a truckload of toggle buttons to switch between numerous 3D topological shapes. But perhaps at this point, you may find it interesting as well, if only for testing purposes. Here it is.

I intentionally did not incorporate your modifications in that version yet, although I am really excited how much better the Klein bottle already looks.... so much smoother!

You've probably also noted that if you let the phi, theta-parameters range from 0, pi, or 2pi, there always seems to remain a gap. Up until now, I "hacked" that problem by adding just a little bit to the interval of theta and/or phi, sometimes resulting in this ugly stitching. Do you have any ideas how to properly address this, perhaps?

I'll definitely incorporate your additions/improvements/additional sliders/whatnot soon, possibly today or tomorrow already, and if not, surely this weekend!

Thanks already for your contribution, it is really appreciated!

Kind regards,

Zeger.



Op woensdag 22 januari 2025 om 05:06:42 UTC+1 schreef Max DeMarr:

Harlan Gilbert

unread,
Jan 23, 2025, 11:04:12 AMJan 23
to glowscri...@googlegroups.com
Vis a vis the extra padding in the phi, theta parameters:
You probably know this, but for loops in Python stop before the last value, not at the last value.  You always need to go a little beyond, e.g.
for a in range(1,11):        #this will range from 1 to 10

Pardon me if this is familiar to you, as it probably is, and not the problem.

--

---
You received this message because you are subscribed to the Google Groups "Glowscript Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to glowscript-use...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/glowscript-users/318ef026-072d-41d5-8bcb-aee34de854f3n%40googlegroups.com.


--
Harlan Gilbert, Ph.D.
High School Math, Physics, Computer Science, and Philosophy Teacher
Collegium Chair
Green Meadow Waldorf High School
Chestnut Ridge, NY 10977

Zeger Hendrikse

unread,
Jan 23, 2025, 4:07:03 PMJan 23
to Glowscript Users
Dear Harlan,

Yes, I did know the end of a range itself is not included. Since I'm using numjs (a kind of Numpy equivalent), there aren't that many for-next loops though. At least, not explicit, they may very well be implicit, and hence the (a?) cause of the polar coordinates not being connected at the extremes. Thanks for the tip!

Kind regards,

Zeger.

Op donderdag 23 januari 2025 om 17:04:12 UTC+1 schreef Harlan Gilbert:

Harlan Gilbert

unread,
Jan 23, 2025, 4:14:20 PMJan 23
to glowscri...@googlegroups.com
This is the line that caught my attention:
def _linspace(self, start, stop, num): return self._array([x for x in arange(start, stop, (stop - start) / (num - 1))] + [stop])


Harlan Gilbert, Ph.D.
High School Math, Physics, Computer Science, and Philosophy Teacher
Collegium Chair
Green Meadow Waldorf High School
Chestnut Ridge, NY 10977

Max DeMarr

unread,
Jan 23, 2025, 6:51:47 PMJan 23
to Glowscript Users
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

Zeger Hendrikse

unread,
Jan 24, 2025, 8:23:46 AMJan 24
to Glowscript Users
Hi everyone,

I have been looking at/working with the changes from Max this morning. Indeed, quite a few shapes came out way better already, but a few others "broke down", in the sense that they got erroneous connections, such as the top of the conchoid suddenly got connected to its bottom (and "the arc" looked weird too). I concluded I needed a more step-by-step approach, as this morning I just copied the whole code of Max relentlessly over to my own app. The Klein bottle did work though!

Now I've just read you have made even more changes, so I'm going to apply this step-by-step approach with the newly modified code. First thing, tomorrow that is ;-)

I do love the transparency a lot, by the way. Especially the toroid shapes come out so much better now!

Other side note, I got a new idea to simulate interfering water waves using our plotting software, like in a swimming pool. I already think I know/I found how to do it too. But let's first try to finish our optimization efforts though: he is nowhere, who is everywhere,  :-)

Regards,

Zeger

Op vrijdag 24 januari 2025 om 00:51:47 UTC+1 schreef Max DeMarr:

Zeger Hendrikse

unread,
Jan 24, 2025, 8:29:50 AMJan 24
to Glowscript Users
O, I forgot to mention, I did stumble upon the same issue with the range of 50 and 56 as well. I think the numpy.linspace() implementation I came up with is the culprit indeed, although I did not get my hands on where the problem exactly is.

I would die to try it with locally installed Python to track this down. However, in Web VPython we are working with nj.arrays, and with installed Python with numpy.arrays. These are so incompatible, that I did not manage to write an adapter for these yet. I was thinking last night how this could be done, but such an adapter would be a lot of work, basically writing a wrapper around all the NumJs calls :-(

So yeah, difficult issue to sort out, I'm afraid.......

Kind regards,

Zeger

Op vrijdag 24 januari 2025 om 14:23:46 UTC+1 schreef Zeger Hendrikse:

Zeger Hendrikse

unread,
Jan 25, 2025, 6:53:34 AMJan 25
to Glowscript Users
Hi Max,

I made quite some progress as well this morning!
  • I have incorporated your changes integrally and have put you in the caption as well (is the hyperlink ok there, or should I put something else?).
  • I now know which lines are causing the stitching issues:  line 134 and 135 in _create_quads(). If I remove the "-1" from the ranges, everything renders without any tinkering the [0, 2 pi] ranges, including the Klein bottle! However, by removing the "-1", the arc and conchoid render weirdly, so I have kept the "-1" there for now. Do you have any idea what the reason is why this is so? I recall this is also "messy" in the original 3Dplot example on the Glowscript site.
  • I tried to add the double torus as well, but this does not work, so I left it unactivated in the code base for now. To be honest, I don't completely understand the stitching process with the concatenate that you've added. Apparently it works for the Klein bottle but not for the double torus? Do you understand that better perhaps?
  • One more question: on my computer, the shininess slider does not seam to have any effect. Does it on your machine?
Anyhow, thanks again and have a nice weekend!

Kind regards,

Zeger.
Op vrijdag 24 januari 2025 om 14:29:50 UTC+1 schreef Zeger Hendrikse:

Zeger Hendrikse

unread,
Jan 27, 2025, 3:57:06 PMJan 27
to Glowscript Users
In the meantime, I found the shininess bug, it turned out to be a mere typo!

I have also succeeded in porting the software to installed Python, so that's great news as well.

Regards,

Zeger.

Op zaterdag 25 januari 2025 om 12:53:34 UTC+1 schreef Zeger Hendrikse:
Reply all
Reply to author
Forward
0 new messages