-
Time For Some News
09/28/2025 at 18:22 • 0 comments![]()
Alright, I will explain this later. In the meantime, images seem to be broken again. So I will have to try to explain what I am thinking about. I saw an article online about how someone asked GPT to demonstrate how to construct a rectangle with an area equal to twice the area of another rectangle, while presumably preserving the aspect ratio. Thus, both rectangles have the same aspect ratio. So maybe it is time to do some more work on my Euclid.cpp source files, on the one hand, while giving some thought as to how to create some kind of proof-generating AI, on the other.
So, to construct such a rectangle, one would need to increase the height and width of the given rectangle by multiplying those dimensions by a factor of the square root of two. Using compass and straight edge methods alone, this could be done, that is, if provided with an already constructed rectangle, by simply constructing two squares, one with sides equal to the width of the given rectangle, and the other with sides equal to the height of the given rectangle. Then one can make use of the fact that the length of an internal diagonal of any square is just the length of one of the sides of a square multiplied by the square root of two.
The construction should be performed in such a fashion as to allow for the creation of the second rectangle by making use of a minimum number of steps, i.e., making the most direct application of the compass and straight edge in generating and making use of the required dimensions. Thus, a rotated and enlarged construction of the given rectangle that overlays the given rectangle should be preferred, for reasons of rigor, that is, over a construction that transfers the dimensions to another sheet.
Now, insofar as how one might turn this into code, so that the problem at hand, somehow, "solves itself", i.e., so that a suitable LLM-based AI might turn what I just said into code. which, herein is already available so as to be able to actually perform the construction, is another matter.
Of course, one of the things that I want to try is to modify a calculator library that makes calls to some of its functions by using a table of function pointers, so that instead of mapping opcodes onto function calls, I want to, instead that is, map words like "bisect", "perpendicular", and so on, onto the appropriate Euclidian operations. So here is the starting point, for how this sort of thing is typically done.
typedef enum { add=0, sub=1, mult=2, divi=3, }; opcode1; typedef double (*ftable[])(const double&, const double&); class calculator { protected: double reg[16]; static double (*ftab[4])(const double&, const double&); static double fadd(const double &, const double &); static double fsub(const double &, const double &); static double fmult(const double &, const double &); static double fdiv(const double &, const double &); public: static double exec(opcode1, const double &arg1, const double &arag2); static int main(); };Then, in our source file, we fill in the values for our table of function pointers, as well as defining some of the functions themselves.
ftable calculator::ftab = { &calculator::fadd, &calculator::fsub, &calculator::fmult, &calculator::fdiv, }; double calculator::fadd(const double &arg1, const double &arg2) { double result; result = arg1+arg2; return result; } double calculator::fsub(const double &arg1, const double &arg2) { double result; result = arg1-arg2; return result; } double calculator::fmult(const double &arg1, const double &arg2) { double result; result = arg1*arg2; return result; } double calculator::fdiv(const double &arg1, const double &arg2) { double result; result = arg1/arg2; return result; } double calculator::exec(opcode1 op, const double &arg1, const double &arg2) { double result; result = (ftab[op])(arg1,arg2); return result; }Here, it is easy to see how the function calculator::exec handles the task of looking up the address of the function that we want to call, according to the ordinal value of the opcode associated with the desired function, and then it actually makes the function call for us and returns the appropriate value. And thus, this makes it possible to call a function like calculator::fmult by knowing that it is associated with the ordinal value of an enum, i.e., the value of "mult".
..... double val1, val2; val1 = exec(mult,2,PI); val2 = exec(mult,exec(add,3,4),exec(add,4,6)); .....Likewise, in an implementation of Eliza that I am working on, there is already a method for looking up the number of responses associated with a particular keyword. So while it might be more elegant to map keywords onto function pointers directly, as this will be less error prone, it is also easy to see how keywords could be used to look up ordinal values in a table of function pointers, and that those function pointers could then be used by a simple interpreter.
key_info keywords[] = { key_info("THANK",2), key_info("CAN YOU",3), key_info("CAN I",2), key_info("YOU ARE",4), key_info("YOU'RE",-1), key_info("I DON'T",4), key_info("I FEEL",3), // etc........ }And thus, just in case you have ever wanted to write your own BASIC interpreter, this is one way of doing it! Thus we might want to have a table of function pointers that maps a word like "midpoint" to a function that we already have.
fpoint fpoint::midpoint (const fpoint &p1, const fpoint &p2) { fpoint result; result.x = 0.5*(p1.x+p2.x); result.y = 0.5*(p1.y+p2.y); return result; }Of course, it will be necessary to have a method for specifying just how to deal with a potentially wide variety of function types, such as functions that take two doubles and return a double, or functions that take two points and return a double, or else functions that take two points and return a point, like the midpoint function, described here.
So, let's consider just how the actual construction might work if we write out a detailed set of instructions in plain English.
- First, construct an arbitrary rectangle with some specified height and width.
- Plot a line that extends the height of the rectangle so that the line is as tall as the rectangle is wide.
- Now draw the diagonal of the suggested square, with or without actually drawing the entire square, i.e., we only need the diagonal of the suggested square, but not the square itself.
- Extend the base of the rectangle by an amount equal to the height of the rectangle, and go ahead and fully construct a square adjacent to the original rectangle.
- Now plot a line perpendicular to the diagonal of the larger square, which also forms one of the diagonals of the adjacent square.
- Extend lines perpendicular from the newly created points, i.e., relative to the associated diagonals, until a point of intersection is found.
- Thus, a rectangle with an area twice that of the original rectangle has been constructed.
- You may now rotate and shift copies of the newly constructed object as desired, using already established techniques.
Taking notice of word count, and not including the snippets of source code, it would appear that this log entry now contains 999 words, including this sentence, and that bits that follow. Whether or not a picture is worth 1000 words or not is, of course, another subject altogether. Especially when we begin to contemplate the issues associated with trying to create a more general proof-generating engine. And so it goes.
-
Just as the previous log entry went into overtime:
09/03/2025 at 05:07 • 0 commentsSo, I went ahead and decided to see how difficult it would be to convert the entire project to TypeScript, on the one hand, or else, while also considering just how difficult it might be to write a complete REACT environment from scratch. Maybe not that hard at all. Easy weekend project? Maybe. It is usually never actually that simple, but why not give it a whack?
First, I went ahead and started working on converting my CSignalView MFC class into TypeScript, since ideally JavaScript should be deprecated and not used for new work, but as usual, your mileage may vary.
![]()
So far, so good. Things look even better on the WebGL side, as far as doing some of the OpenGL initialization. That is to say, if any of this actually works.
![]()
So, the particular tool that I used seems to have just enough know-how to give me some boilerplate WebGL code that appears to have the ability to draw a grid and even plot some "waveform" data. So maybe if I decide to use Euclidean geometry, WebGL style, this could be adapted, while remaining faithful to the implementation details of the Euclid.cpp code. Not surprisingly, or perhaps quite surprisingly (take your pick), when trying to convert the Euclidean stuff, the tool that I tried using pretty much fell apart. Maybe it will work better if I ask it to convert one function at a time, which is pretty annoying.
![]()
As you can see, the conversion tool in question pretty much gave up on certain functions, like the pentagon construction, hexagon construction, and also the angle bisector stuff, and that is all just a bunch of straight-up function calling and simple mathematical manipulation. Like I said, maybe it will work better if I spoon-feed it one or two functions at a time. Yet it is kind of funny that it does so well with some really messy code like WebGL initialization, yet falls apart on the same code that Co-Pilot fell apart on a while back.
-
Two Outs. Last of the Ninth. Tying Run on Second.
08/11/2025 at 15:08 • 0 comments![]()
Were you expecting a catchy title that hints at the whole theory of the NFL clock? Or how about basketball time in a relativistic arena? Rest assured, that we are not there quite yet, nor is there any plan for that sort of thing any time soon. Then again, at least I have a working clock that compiles under Visual Studio 2005 in both debug and release modes. Even though I haven't tried adding the GPS via USB stuff to something that might actually run with just this collection of files, and maybe a little bit more, if needed, from my frame lisp library.
Yet, things appear to simplify a great deal if I just grab the files that I need, and don't try to rely on needing to link against 14 libraries. Still, VS 2005 is doing a pretty good job, I think, when it at least tries to get the size of the executable down to just over 400K. Which is totally bloated by hacker standards. Shouldn't it be possible to do something like this in something like 40K, or maybe 4K, if I were trying to run this on an Apple II or a C64? Bloated by hacker standards, but at least it is doing something. Very reasonable, however, by modern standards.
At least RAM is cheap these days. Still, it remains to be seen if it is possible to get something like this, with lots of fun libraries and other goodies added, or to be added, let's say, if it looks to be possible to compile for Web assembly, or something else even more fun, like Parallax hardware, or one of the many Arduino hacks that are possible, insofar as actually doing video generation are concerned. I'll know more about what might be possible when I get to a minimum code set, maybe even if I try just piling all of the code into one big source file and then rewrite, most of it, if not all of it, in pure C, with Win32 API calls instead of MFC. Then there would be no need to consider Widgets, or Qt, or whatever.
Atari 2600, anyone? Maybe in emulation, but not anytime soon. Still, I do like the idea of trying something like this on a Commander X16 if I ever decide to get one. There is another platform that I haven't done anything yet either, that might be fun to putz around with - and that is, of course, the XP clone, ReactOS.
Now that could get very interesting. Why settle for writing your own game engine, one piece at a time, when you can have a whole OS?
Decided to try an online code conversion tool that converts C++ to Typescript. Does it work? I don't know. In any case this is what the actual function that calculates the position of the sun in the sky, given the longitude, latitude, and time of day appears to look like.
compute_local_aspect() { let solar_time, ra_base, ecliptic_aspect; this.m_gmt_seconds = 3600.0 * (this.m_hour - this.m_daylight_savings - this.m_time_zone) + 60.0 * this.m_minute + this.m_second; solar_time = this.m_gmt_seconds * (1.0 / 3600.0); this.m_julian = julian_day(this.m_month, this.m_day, this.m_year) - julian_day(3, 20, 1900) + solar_time * (1.0 / 24.0); ecliptic_aspect = ((this.m_julian % 365.242191) * TWO_PI) / 365.242191; const ecliptic_aspect_vector = tensor.rotate_z(ecliptic_aspect).multiply(_vector(1, 0, 0)); ra_base = (ecliptic_aspect * 24.0) / TWO_PI; const SIDT = tensor.rotate_z((solar_time - ra_base) * (TWO_PI / 24.0) - TO_RADIANS(this.m_longitude)); let local_xyz; const p = new polar_orientation(); p.m_theta = 0.0; p.m_phi = TO_RADIANS(this.m_latitude); local_xyz = p.get_xyz(); const ROTL = tensor.rotator( _vector.normalize(local_xyz.cross(_vector(0, 0, 1))), p.m_phi - PI_OVER_TWO ); const GLSUN = ROTL.multiply(SIDT).multiply(this.m_ROTX); this.m_local_solar_vector = GLSUN.multiply(ecliptic_aspect_vector); const q = polar_orientation.from_axis(this.m_local_solar_vector); this.m_el = TO_DEGREES(q.m_phi); this.m_az = ((360.0 + TO_DEGREES(q.m_theta)) % 360.0); }Pretty much a no-brainer, once most of the real work has been done. So maybe adding Android or iOS as a possibly supported platform wouldn't be so hard to do after all, that is to say, if I ever decide to try to integrate some of the Teapot in the Garden stuff.
O.K., then, let's take a look at one conversion tool that says I might want to do with the CSignalView.cpp file:
![]()
Of course, I have cropped out the name of the tool, and it appears that I don't have enough free credits remaining on this one, so I will wait a while longer, or maybe try a simpler task that uses fewer credits in my free trial. Of course, having actual PRINTER support would be nice to have for some browser-based apps, and I am not sure what else absolutely would need to be native. So, some more research is needed before I commit any $$$ to the use of any tool.
In any case, here is the whole rant that the tool gave me, about what it might want to do with one critical part of the Windows GUI portion of the code.
You’ve asked to convert a large C++ MFC (Microsoft Foundation Classes) class (CSignalView) to TypeScript. Here’s my understanding and a proposed plan for the conversion:
Restatement of Your Request:
You want to convert the provided C++ code (which is a
Windows/MFC GUI class for drawing and printing signals, with some OpenGL and GDI code) into TypeScript.
Conversion Plan
1. Framework/Platform Mapping
C++/MFC/Win32 → TypeScript + Web Platform
MFC’s windowing, device context, and drawing APIs will be mapped to HTML5 Canvas and/or WebGL, as these are the closest web equivalents.
Message maps and Windows messages will be mapped to DOM events and class methods.
2. Class and Data Structure MappingCSignalView→SignalViewTypeScript class.
MFC types (CDC,CBitmap,CRect, etc.) will be mapped to TypeScript classes or interfaces, or replaced with CanvasRenderingContext2D and DOMRect.
Color constants will be mapped to CSS color strings or numbers
3. Drawing and Rendering
GDI/OpenGL drawing code will be mapped to Canvas 2D or WebGL drawing.
Printing logic will be simplified or mapped to canvas export (e.g., to PNG/PDF).
4. Event Handling
MFC message handlers (ON_WM_PAINT,ON_WM_SIZE, etc.) will be mapped to DOM events (resize,paint/draw,timerviasetInterval, etc.).
5. State and Member Variables
All member variables will be mapped to class properties.
Windows-specific types (e.g.,BOOL,UINT) will be mapped to TypeScript types (boolean,number).
6. Unsupported/Windows-Specific Features
Clipboard, metafile, and some device context features may not have direct equivalents and will be stubbed or replaced with web-appropriate logic.
OpenGL context creation will be mapped to WebGL if needed, or stubbed if not essential.
7. File Structure
All code will be in a single TypeScript file (unless you request otherwise).
Helper classes (e.g., for color, rectangle, etc.) will be defined as neededAnd so on. While having printer support probably isn't needed for a web application, I think it would be nice to have for some things like "audio-in sheet music out applications", and maybe even high school level geometry applications, for those people who might want to actually to render things like Pythagorean proofs in a browser application, that might in turn run on iOS, Android, or in any modern browser. Unless you need to print, apparently.
-
Counting down to the home stretch
08/10/2025 at 01:24 • 0 commentsOK, this is where the project stands right now. I have the "Teapot In the Garden Stuff running in one "application" which is OpenGL aware, and which has a whole bunch of fun stuff, like wave audio playback, multi-document support, and so on. Here, it would be easy to implement an OpenGL clock face, so that I can perhaps have my "clock on the wall" or a clock tower in a garden scene, whether in a game-like environment, or based on GPS data.
![]()
In another application, I have been merging the GPS with the input stream that feeds to an Eliza-style chatbot, for purposes of testing the ability to decode the live streaming data, when available, among other things. Here is an example where I simply copied and pasted some test data from Wikipedia, so as to test GPS string parsing in "Eliza" and verify that the data can "optionally" be streamed to an MFC-style CEdit View, while diagnostic data verifying that the NMEA string parsing of the "tokenized" stream is working correctly, and that the associated azimuth and elevation of the sun for the relevant location is also being calculated.
![]()
Likewise, the "Propeller Debug Terminal" application, which is available on Git, and will be updated at some point, also supports GDI-based graphics, in the CSignalView class, as can be seen with some of the sample plots of oscilloscope data and the plotting of something resembling a Smith Chart. In this configuration, actual GPS data can also be streamed from a GPS module, where it is simply being displayed alongside a here-seen, partially drawn Smith-Chart. Perhaps what I should try next, therefore, is to go ahead and see if the Propeller Debug terminal can make calls into the Euclidian geometry library via the CSignalView class, instead of simply "drawing a Smith Chart directly".
Then maybe add Open-GL support to the Euclidian library, so that I don't have to try to implement a full Open-GL stack in software, since I really only would need that if I were going to port the application over to another platform, like running it on a Propeller P2 board, which I have, or some other alternative platform, like a commander X16, which I do not have, or even a full ground up FPGA based system, with custom CPU operations done in Verilog. Not quite there either. Maybe some other time.
![]()
Maybe a nice Win32 application with OpenGL support, but without MFC support, that could perhaps be compiled as a control panel, screen saver, DLL, or even as an Active X control so that it can be tested as a possible "browser plug-in". What am I leaving out? Haven't ever done much with "Processing", even though it does appear to be a popular platform, and that would possibly help with MacOS, and or Android support, along the way. Maybe I should look into whether anyone else has ever tried creating Windows Desktop accessories in Processing.
Or maybe some other time, in some parallel universe. Then again, it is quite simple to try to create a pure standalone application without full Document-View support, but which makes use of the Euclid stuff as an externally linked library, even though that takes a whole world on its own of fiddling with settings for whether I want to render for a certain page size, or whether I want to resize for the current view, i.e. so as to fit to the current window, and so on. Then I will need to add in the GPS over USB stuff, and create some dialogs for adjusting the settings. Not sure how some things work in Windows 10, but it used to be possible to take a regular exe and simply change the suffix to cpl and you had a control panel, or you could change the suffix to scr to get a screen saver, provided that you also added in the needed command line parameters to tell the screen saver whether it was in preview mode or whether it should be in full screen mode.
Now, subclassing an actual Microsoft Windows application? Well, the old-fashioned way of doing that was, and still is, known as "DLL injection", which is a trick also widely used by keyloggers and other sneaky malware. So it may or may not work. But worth thinking about. Just inject a DLL or two into every running process, until we figure out which one we want to "hook", or something like that. Maybe I could ask GPT? Hahahahahaha!
![]()
And thus. this is what it looks like for now. Maybe something with a borderless mode, but just as fully functional? I really liked the Aero look back in the days of Vista, even if it was the only thing to like about Vista.
![]()
-
This is just too much fun to resist!
08/07/2025 at 08:06 • 0 comments![]()
First attempt at doing a test rendering of the "calculation" for the minute marks with this code. Ran "correctly" on the first try. Zooming out will show what is really happening.
![]()
With this code no less:
void euclidian::draw_clock () { vector<fpoint> hrot; fpoint minute_marks [60]; dodecagon hour_marks; pentagon penta; hour_marks = construct_dodecagon (false); penta = construct_pentagon (false); euclidian::bind(*m_host,hour_marks); hour_marks.on_draw (true,true); fpoint center = hour_marks.m_center; fpoint radial = hour_marks.m_points[0]; m_host->draw_polygon(center,radial); int i,j; angle a; hrot.resize (12); for (i=0;i<5;i++) { a = angle(fline(penta.m_points[i],penta.m_center)); for (j=0;j<12;j++) hrot[j] = hour_marks.m_points [j]; a.angle::rotate_points (hrot,hour_marks.m_center); for (j=0;j<12;j++) minute_marks[12*i+j]=hrot[j]; } SETCOLOR _(m_host->m_pdc,COLOR::magenta); for (i=0;i<60;i++) { m_host->draw_line (hour_marks.m_center,minute_marks[i]); } }Well, there is still a bit of work to do. Like I might want to consider running quick sort on the minute marks, because they are most likely written to the vector of fpoints in a somewhat scrambled or shuffled fashion. Even though now that I am thinking about it, that wouldn't be necessary if all that we are doing is using the point cloud to decide where to draw the actual and therefore properly determined minute marks, which should therefore be possible to draw, now, that is, in another piece of code. Hopefully, let's say, after a whole lot of this stuff gets refactored and then moved to a constructor.
Or maybe I can actually run quicksort on the array, using a custom comparison function that compares the angles of adjacent points. Something that is certainly worth looking into, even if that involves using trig functions, just to see what is really happening here. Of course, if you didn't know that Gauss, I think, was the one who figured out how to do a 17-sided rigorous construction, and of course, 3 times 5 times 17 is 255, which means that a regular 255-sided polygon is also a theoretical compass and straight edge construction, which will have to wait for another time.
A quick screenshot of some debugging information, where I call a function to calculate the actual angle of each line, as it is being drawn, shows what is happening.
![]()
The good news is that it is exactly what I was expecting! That being the nature of the design, code, compile, test, debug, etc., cycle. Wanting to see results. Now! And getting an interesting, fun surprise now and then. Now, like I said, I am thinking that I can still calculate the locations for my minute marks with this stuff. Not a problem there. Yet, I must confess that I have some circle drawing code that elsewhere is actually pre-calculating the points of a polygon with a "large number of sides" by actually making some calls to sine and cosine. And THAT code needs to GO, since what I want to try instead is some kind of quadratic interpolation based on sets of three or four points, depending on the required resolution, and so on, and that will require that the points be sorted. What to do, therefore? Quicksort the array, or figure out how to fix the issue with modular arithmetic as the array is being created? Hmm? What would Eratosthenes or Pythagoras do? Or Ptolemy, for that matter?
![]()
Well, anyway. A little more tweaking with the drawing code, and it is starting to look like something. Even if the array that holds the coordinates for the minute marks is still unsorted. Then it occurred to me, that in order to actually draw the time, without using trigonometric functions, I am going to need to be able to do a table lookup of the relevant locations, so that I can use a hopefully faster method, like simple linear interpolation, or quadratic interpolation, as I also suggested, to find the exact points to play connect the lines with. Then maybe work on some OpenGL stuff
-
Time for a Long Over Due Update.
08/05/2025 at 20:10 • 0 comments![]()
And in other news, I now have the ability to stream GPS data via some of the functions in the Propeller Debug Terminal for that application, which is presently also being repurposed for an eventual "Teapot in the Garden Project". Calculating the position of the sun in the sky via GPS is also working over there, so maybe I should do yet another major revision of the communications libraries that that project uses, so as to make them callable from any project. Then I could perhaps start on the otherwise "simple" task of drawing a clock face, all without conditional logic or "need" to make use of trig functions, of course.
Keeping things interesting, of course, I am using some library calls from an otherwise broken version of the chatbot Eliza to parse the GPS data, which is being received via USB, thus providing more than one way to get the time, i.e., so that we can obtain the time from a simple COLEDateTime object or we can get it from GPS, as described in "Teapot in the Garden"
void solar_elements::set_time () { COleDateTime _dt = COleDateTime::GetCurrentTime(); m_year = _dt.GetYear (); m_month = _dt.GetMonth (); m_day = _dt.GetDay (); m_hour = _dt.GetHour (); m_minute = _dt.GetMinute (); m_second = _dt.GetSecond (); m_time_zone = -8; m_daylight_savings = 0; } void solar_elements::set_time (char *str) { COleDateTime _dt = COleDateTime::GetCurrentTime(); m_year = _dt.GetYear (); m_month = _dt.GetMonth (); m_day = _dt.GetDay (); ASSERT (strlen(str)==6); char str_h [4], str_m [4], str_s [4]; strncpy_s (str_h,4,&str[0],2); strncpy_s (str_m,4,&str[2],2); strncpy_s (str_s,4,&str[4],2); m_hour = atoi(str_h); m_minute = atoi(str_m); m_second = atoi(str_s); m_time_zone = -8; if (m_time_zone!=0) m_hour = (m_hour+24+m_time_zone)%24; m_daylight_savings = 0; }Of course, a nice bonus to using GPS is that I now also have the ability to obtain the user's actual longitude and latitude, which can therefore be passed to the solar_elements class for the purpose of finding the current azimuth and elevation of the sun, which can in turn be handed over to OpenGL for such things as determining the lighting model, that is if I ever get around to drawing the actual clock! At that point, as wonderful as the methods of Euclid are, it is unfortunately necessary to make a few trig calls, not very many, however, from the functions that actually compute the position of the sun. Since I haven't quite worked out the whole Ptolemy system yet, with corrections as if according to Kepler. And we all know that infinite series methods did not exist for evaluating trig functions until much later, i.e., until Newton, Taylor, Gauss, Euler, and so on. Yet not, to worry - just in case on some other hardware platform, if we ever get there - "where we are going - we don't need NO FPU either!"
So maybe, if you can imagine some parallel universe where Microsoft Altair Basic never existed, or any BASIC for that matter, imagine a world where we had no floating point routines, or perhaps no math routines at all, but we could roll our own from day one with C++ operator overloading, then in a C++ "real" class, IEEE-754 (maybe) multiplication might look like this, provide that you have regular 32 bit operations defined somewhere else.
real real::operator * (real arg) { short _sign; real result; short exp1 = this->exp()+arg.exp()-127; unsigned int frac1, frac2, frac3, frac4, fracr; unsigned short s1, s2; unsigned char c1, c2; _sign = this->s^arg.s; frac1 = this->f; frac2 = arg.f; s1 = (frac1>>7); s2 = (frac2>>7); c1 = (frac1&0x7f); c2 = (frac2&0x7f); frac3 = (c1*s2+c2*s1)>>16; frac4 = (s1*s2)>>9; fracr = frac1+frac2+frac3+frac4; if (fracr>0x007FFFFF) { fracr = ((fracr+(1<<23))>>1); exp1++; } result.dw = (fracr&0x007FFFFF)|(exp1<<23)|(_sign<<31); return result; }Just in case you have a C++ compiler for your NOR computer, if you have one, but no math routines. Well, what else is there to say, except that it can all be done in C++, including the 32-bit math, based on NOR instructions. But that is another rabbit hole to be explored further elsewhere, whether in whole or in part.
Time to return to the project at hand, therefore. Just as soon as I figure out what it is actually going to do.
![]()
A quick screenshot shows where things are right now, graphics-wise. Eventually, I will post the code for a file named euclid.cpp, which has grown to about 1500 lines, just to get stuff done like finding bisectors, perpendiculars, parallels, points of intersection and so on.
void euclidian::draw_clock () { fpoint minute_marks [60]; dodecagon hour_marks; pentagon penta; hour_marks = construct_dodecagon (true); penta = construct_pentagon (true); euclidian::bind(*m_host,hour_marks); hour_marks.on_draw (false,true); fpoint center = hour_marks.m_center; fpoint radial = hour_marks.m_points[0]; m_host->draw_polygon(center,radial); }An idea comes to mind, therefore, about a possible correlation to Moore's law, and that is the idea, I think, that it sometimes becomes possible to get exponentially more stuff done as more capabilities are added. Maybe that is a variation of Metcalf's law? We can, of course, now combine the idea of drawing a hexagon with the idea of bisecting the internal angles thereof, in order to be able to compute our hour marks. Yet at the same time, now we can also consider how to use the fact that 12 and 5 are relatively prime with each other, so as to consider how to draw twelve rotated pentagons, if that is what it takes to generate the minute marks.
dodecagon euclidian::construct_dodecagon (bool draw) { fpoint pt0,pt1,pt2,pt3,pt4; dodecagon decca; hexagon hex = construct_hexagon (false); int i; double len1; // first copy the even points over decca.m_center = hex.m_center; for (i=0;i<6;i++) decca.m_points [2*i] = hex.m_points [i]; pt0 = decca.m_center; for (i=0;i<6;i++) { pt1 = decca.m_points [2*i]; pt2 = decca.m_points [(2*(i+1))%12]; pt3 = bisect (pt0,pt1,pt2); len1 = fpoint::length (pt0,pt1); pt4 = fpoint::extend0 (segment (pt0,pt3),len1); decca.m_points [2*i+1] = pt4; } return decca; }Here, it is easy to see that all we needed to do to get the hour marks is to start with a hexagon, and then bisect the internal angles, and extend the bisector line segments until they are the length of the appropriate radius. Perhaps the code for drawing a rectangle would have more utility if it were possible to generate, position, and also rotate a collection of small rectangles, so that these can, in turn, be used, perhaps with OpenGL, for example, to obtain a more pleasing 3-dimensional view. Of course, as much fun as branchless programming is, eventually it does become useful to sneak some loops in. Maybe someday, I will try to hide some, if not all of the looping code, in some kind of scheduler. That would generally be very bad for an inner loop, but if enough functions were actually called from some kind of loop manager, then maybe that could be put to use, if I wanted to make videos about Euclid's methods, for example. That will have to wait for now. Even though it also would help with the prospect of having a clock that you could give natural language commands to, like "When the sun comes up, dispense cat food."
Eventually.
![]()
There are plenty of paths that can be taken right now, that is to say, in the meantime. Pun intended. While it would be trivial to come up with a Windows clock application, so why not do that, while at the same time, I know that I should be considering having a dedicated actual replacement for the taskbar clock. One with GPS synchronization, if available. Or a stopwatch feature, for those times when you want to do something, like take your pulse, the old-fashioned way. Or add SMPTE time code monitoring, and or other. And eliminating advertising. If I want an event list, it should be populated with the events that I want, not an ever-changing sea of "suggested" events that I did not ask for.
-
Life in the Slow Lane - or else Here Comes the Sun?
07/02/2025 at 07:54 • 0 commentsApparently, there is now a "One Hertz Challenge". Not sure exactly how I am going to go about this. Maybe take a Parallax Propeller II module, which is capable of VGA as well as HDMI output, and make a version of the clock that I was talking about. Just in case I don't need trig calls. Just in case I don't need full OpenGL, but also just in case I would like to have a virtual clock face that accurately casts a shadow of the hands on the face of the clock, as if according to the position of the sun in the sky, that is according to the desired Longitude, Lattitude and maybe even current weather.
So, of course, if we are going to do this, we need to calculate the position of the sun in the sky, to a reasonable approximation, at least once per second, right? How hard can that be? Maybe not all that hard at all if we assume a circular orbit, ignore atmospheric effects, leap seconds, precession of the equinoxes, etc.
#include "stdafx.h" #include <ATLComTime.h> #include <math.h> #include "../rubidium/defines.h" #include "../rubidium/drawstuff.h" #define INCLINATION_OF_EARTH_ORBIT 23.439281 using namespace TENSORS; class celestial_coordinates { public: MATH_TYPE right_ascension; MATH_TYPE declination; }; solar_elements::solar_elements () { COleDateTime _dt = COleDateTime::GetCurrentTime(); m_year = _dt.GetYear (); m_month = _dt.GetMonth (); m_day = _dt.GetDay (); m_hour = _dt.GetHour (); m_minute = _dt.GetMinute (); m_second = _dt.GetSecond (); m_longitude = 119.81; m_latitude = 39.53; m_time_zone = -8; m_daylight_savings = 0; R = 3958.8*5280.0*FEET_TO_CM*1.0e-5; m_ROTX = tensor::rotate_x (TO_RADIANS(INCLINATION_OF_EARTH_ORBIT)); } void solar_elements::debug_test () { ASSERT (julian_day (1,1,2000)==2451545); ASSERT (julian_day (6,19,1987)==2446966); ASSERT (julian_day (12,8,2009)==2455174); int H,M; for (H=0;H<24;H++) for (M=0;M<60;M+=10) { m_hour = H; m_minute = M; compute_local_aspect(); // TRACE ("SOLAR time = %02d:%02d AZIMUTH = %f, EL = %f\n",H,M,m_az,m_el); } } double solar_elements::julian_day (int M, MATH_TYPE D, int Y) { int mm = (M-14)/12; int yy = (Y+4800+mm); int JDN1 = (1461*yy)/4; int JDN2 = (367*(M-2-12*mm))/12; int JDN3 = (3*((yy+100)/100))/4; MATH_TYPE JDN = JDN1+JDN2-JDN3+D-32075; return JDN; } void solar_elements::compute_local_aspect() { MATH_TYPE solar_time, ra_base, ecliptic_aspect; // estimate ecliptic aspect m_gmt_seconds = 3600.0*(m_hour-m_daylight_savings-m_time_zone)+60.0*m_minute+m_second; solar_time = m_gmt_seconds/3600.0 - m_longitude/15.0; m_julian = julian_day (m_month,m_day,m_year) - julian_day (3,20,1900) + solar_time/24.0; ra_base = fmodf(m_julian,365.242191)/(360.0/24.0); ecliptic_aspect = ra_base*TWO_PI/24.0; tensor SIDT = tensor::rotate_z ((solar_time-ra_base)*TWO_PI/24.0); _vector ecliptic_aspect_vector = tensor::rotate_z (ecliptic_aspect)*_vector(1,0,0); m_geocentric_solar_vector = m_ROTX*ecliptic_aspect_vector; _vector siderial_solar_vector = SIDT*m_geocentric_solar_vector; _vector local_xyz; polar_orientation p; p.m_theta = 0; p.m_phi = TO_RADIANS(m_latitude); local_xyz = p.get_xyz (); tensor ROTL = tensor::rotator( _vector::normalize (local_xyz.cross(_vector(0,0,1)) ), p.m_phi-PI_OVER_TWO ); _vector local_solar_vector = ROTL*siderial_solar_vector; polar_orientation q = polar_orientation::from_axis (local_solar_vector); m_el = TO_DEGREES(q.m_phi); m_az = fmodf(360+TO_DEGREES(q.m_theta),360); }To figure out how this works, you will need some kind of tensor library, which for now, I leave up to the user to provide.
-
Is It Time To Revisit The Visitor?
05/25/2025 at 14:31 • 0 comments![]()
I am thinking about revisiting the visitor pattern as soon as I can remember exactly what it is and how it works or is supposed to work. If I remember correctly, the visitor pattern is a design pattern in object-oriented programming that makes use of three properties that can be bound to a set of objects. One of these properties is that of being a “client”, another property is that of being or becoming an “operator”, and the third property is that of being or otherwise acting as the “observer”.
I might have this all wrong, but as I see it, these roles should not be fixed. For example, suppose in a real-world situation, a “client” might be an actual customer who visits a hair salon, or perhaps someone who hires a plumber to fix some leaking pipes. Whereas the observer in one of those cases could be the salon owner, or perhaps the person who holds a plumbing contractor's license. The operator, then, is the employee who does the actual work. Sounds simple, right? Well, maybe that is until the business owner gets inspected by the Department of Environmental Health, or they get audited by the IRS, for example. Now they become the client, or something like that.
Now, computer software is usually a little more abstract, or is it? What if we similarly define objects and methods to what has been described, where a word processing application might be the “observer”, the document is the client (or visit), and the spell-checker is the operator, or something like that?
This has huge implications for things like memory management, of course. Who is responsible for deleting an object when its reference count reaches zero if reference counting is used? And what if we more often than not don’t really need reference counting semantics, and all the inefficiencies that it brings to what might otherwise be a very high-performance application? Consider, for example, “publish and subscribe semantics”. Maybe a graphics application “publishes” a shape library for use by a parallelized set of shaders and other renderers? Likewise, what if we don’t need to have reference counting for objects in a relational database that is based on a so-called “journaling file system”? So, object persistence might negate the need for reference counting, allowing the use of unsafe pointer types in many cases, while at the same time, the reference count might just somehow reappear anyway, in the form of the “subscriber” count in some other context.
So here I am thinking about braids, again, and how this might affect our understanding of object complexity, and that, of course, has me imagining yet another use for the visitor pattern. Maybe.
O.K., then – what if there is the notion of “the rambling manifesto”, vs enforcing the “chain of thought”, as well as the need for a “prompt” in an LLM or transformer-based AI model? A use case should exist, therefore, for the visitor pattern, or outright “weaving” of some kind of abstract hypergeometric non-Abelian braiding topology, along with its associated Hilbert spaces. If Swinnerton-Dyer holds, then the keys to AGI might be concordant with the concepts of “ascension” and “generalization,” that is to say, by the nature of the fact that the implied diffeomorphism with respect certain concepts in General Relativity, such as “raising an index” or “contracting a manifold” by deducing the invariants associated with a particular matrix formulation.
This should work out quite nicely, that is to say, if the geometrization of space-time is in fact rigorous.
In the meantime, at least I have some ideas about how to proceed with the design patterns for use with improvements to a chatbot that I am working on. Obviously, I still want to do some kind of "chain of thought stuff" that is based on the principle of Euclid, such as by using name-value pairs to map words like "bisect" in an LLM onto function calls in an API. Yet, since it is also the case that that since very simple, parallelized, and asynchronous multi-headed attentional system seems to work quite well, at least some of the time, when trained on just a "few" contexts, so to speak, in that it sometimes acts like it is capable of "generalization" and "abstraction", at least some of the time - like when I offer to try to set the chatbot up on a "date with Venus", and then it got religious on me!
![]()
So now I am thinking, eventually, I want to make all of this open-source, or most of it anyway. Since the part that I want to keep "secret", at least for now, is the training set. Yet all in good fun, of course, here is a sneak peek at something that I want to do more work with, insofar as "how it works" under the hood, or how I think it should work. Here is of course where it gets weird, if I don't want to publish the entire training set that I used with this particular bot, but it is pretty much stuff like this:
When I find myself in times trouble, I don't actually reach out to Mother Mary, hoping that she will make me somehow that much more blessed, that is to say, if I were to abandon my apparent autonomy in favor of some ostensible wisdom that was mis-attributed to the regarded virgin mother, many centuries after whatever happened, that happened. Hence, like some other version of serenity, I contemplate whether or not things are meant to be, or if it is meant for me to try to make a difference, to therefore consider whether that implies a call for action, or whether or not I should simply let some things be.
Thus, what if it’s not really about opinion formation, or bad lyrics, or great lyrics, or whether or not either you or I can make anyone like someone else, or everyone else, or even whether or not every song has the same four chords, or whether or not I can get past the first four words that you said, or maybe it was someone else who said, about "when I find myself." Ah, but there lies a great existential question, finding myself, finding yourself, the quest for meaning, in oneself, versus and with regard to the relation between, what? One's self and another, or else what: any particular thing versus - vacuum? So it's funny how that works, for there is, after all, still action and reaction, and the fact that no force can act against itself. So much, therefore, for pure autonomy. For there must also be this, or that great other thing - that is to say, that there is also the big bang, and the universe, and all that there is in it.
Sometimes I feel very large, and sometimes I feel very small, insofar as how all of that fits together, but inevitably I conclude that the volume of all space is implied by the collective consciousness of all those minds that occupy it. Einstein himself suggested it, his lack of a belief in a personal God notwithstanding, and thus he remained a "Deist", which is to say that he believed that there was some kind of "Deity", but as far as I know, he did not attempt to attach any other properties thereto, or knowledge thereabout, other than what might seem to be an apparent or otherwise axiomatic fact of implied existence.
So "blah blah, and I would tell you" ... so much more than all of that that "you (probably) don't even want to know", but at the end of the day, you still can't pull yourself up by your own bootstraps, nor is there any real freedom in a vacuum, so to speak. Something to react to is necessary, or someone, for whatever that means. Not trying to be critical by the way - just like to have someone to react to.Now what I don't quite yet understand therefore, is how in another chat session with a different bot, which was trained on every article and every log entry that I have ever uploaded to Hackaday, is just how exactly the other bot started talking about "the man behind the curtain ... somewhere in the sky, even for an AI", when prompted with an inquiry about dark energy. Now don't get me wrong, I KNOW exactly where I used the phrase "Pay no attention to the man behind the curtain" as the title of a log entry, just as I used "Follow the Yellow Brick Road" for the title of a log entry where I was looking at blocks of hexadecimal on my screen.
![]()
What if AGI really isn't all that hard, it's just a matter of bringing all of well, you know - certain things "into balance". Be very afraid.
-
Beyond the Sands of Time?
05/06/2025 at 09:17 • 0 comments![]()
Perhaps my drawing room needs an old-fashioned drafting table, for my compass and straight-edge proofs. A clock on the wall would be nice, as would be some books for my bookshelves. The piano still needs legs and a place for some sheet music. Thus, while writing a game engine entirely from scratch is never an easy undertaking, I still think that it is a worthwhile endeavor. Most who dwell around these parts will understand why.
So, yeah - I am having thoughts about making a game engine that contains some kind of object editor, "in-game", as it were, or as I should say, as it eventually will be. Then I also want to have the stuff from "Teapot in the Garden", which you can find elsewhere, i.e., along the photo-realistic hair generating stuff, that also does blades of grass, trees, etc., all based on the same theory of "Digital DNA" based procedural mesh generation, among other things, and where some of other things includes the foundational stuff that is all based on the principles of Euclid, also as previously discussed.
Thus, likewise, I think that AI, LLMs, and transformers as such are going to turn out to be quite useful, not just for giving personality to avatars, as such, but also for doing things according to some modern variant of SHRDLU, which I am also still working on, in addition to the Eliza stuff, believe it or not.
Not that I couldn't perhaps run some variant of Ki-CAD as an ActiveX X control, for example, that is to say, within a view - inside a game engine perhaps? Even if the Meta-verse is pretty much a failure. Even if Microsoft BOB was a failure. Just so long as I don't try to reinvent "Clippy!" Right?
O.K., maybe an old-fashioned analog clock on one of those walls would be nice, at least for now. Along with an old-fashioned drafting table.
I wonder how many people remember that BeOS could do "books" with page-turning effects, along with animations on the individual pages? A rather impressive feat for the late 90's, that is, that something like that could actually be done, even then without a GPU, i.e., on just a PowerPC.
Then there is reflection, as an optical concept, or as a psychological concept, or even as a programming concept. This is something to ponder - or at least reflect upon.
To be continued ...
-
What if Time could go Sideways?
05/02/2025 at 20:22 • 0 commentsWell, time doesn't go sideways, but I can turn my 3-D perspective view of the Euclid style renderings on its side, just because it is possible to do. Of course, there is the idea of Feynman's sum-over-all histories approach to quantum electrodynamics, where one interpretation might be to allow for time to act, perhaps like it has multiple dimensions, which converge, usually, to a single path chosen. Yet, that is not what this post is about. What then is this post about? Well, keep reading.
![]()
I saw the other day how someone got an LLM to run TinyStories260K on a C64 with 2MB of RAM expansion, of course, and that looks interesting, obviously - especially if LLAMA2 can be reduced to just 700 lines of C. So, I think that I am on track as far as eventually doing a better AI based on some of my log entries from Hackaday, among other things. Thus, this log entry, like many others, will eventually, all in due time of course, go into the training file for a small LLM, as it were, or else I should perhaps say, as it will be. So that is part of the method for the madness.
Other than that, I realized something while finally rendering the hexagon. Something quite interesting, that is. Here is a simple question. Is it better to draw five hexagons, according to the vertices of the pentagon, and thereby obtain, hopefully, a set of 30 points that can be further used to construct the 60-minute marks, as well as the hour marks for a clock face? Or is it better to construct one reference hexagon and then construct six pentagons, even though that would obviously be more work computationally? The definition of "better," of course, might depend on such things as the accumulation of roundoff error, for example, and maybe compute time doesn't matter so much, if the calculations, all being done without trig calls of course, only need to be done once, as in the constructor for a master set of points when a module is instantiated.
Then I realized that there might be a third approach. Draw a simple equilateral triangle inside a circle. Then construct at least one pentagon, sharing a vertex, and then, according to the points of the pentagon, construct a couple of hexagons, acting as if kind of random, in effect, just doing whatever, so as to get more points.
This could get messy, since some sets of vertices might get constructed more than once, and maybe some comparisons and sorting operations would need to be performed, even though that would probably involve branches, and it would also really mess with things as far as the meanings of words like "proof" and "rigor" are concerned, especially insofar as trying to prove the equivalence of the results of an analytic construction vs. a real world compass and straight edge construction are concerned.
Fortunately, I don't think that would involve an infinite regression, just some kind of tree search that could include redundancy checking, as a part of a larger equivalence testing regimen.
glgorman





















