<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>victorliu.info</title><link href="http://victorliu.info/" rel="alternate"/><link href="http://victorliu.info/feeds/atom.xml" rel="self"/><id>http://victorliu.info/</id><updated>2026-06-02T00:00:00-07:00</updated><entry><title>AI is making me a micromanager</title><link href="http://victorliu.info/micromanaging-ai.html" rel="alternate"/><published>2026-06-02T00:00:00-07:00</published><updated>2026-06-02T00:00:00-07:00</updated><author><name>Victor liu</name></author><id>tag:victorliu.info,2026-06-02:/micromanaging-ai.html</id><summary type="html">&lt;p&gt;I am a manager. I hate being a manager.
Granted, I manage a whopping two people (two and half, if we're being realistic about job tasks), but I still don't enjoy it. I understand it is a necessary evil in a company of size greater than two, and on the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I am a manager. I hate being a manager.
Granted, I manage a whopping two people (two and half, if we're being realistic about job tasks), but I still don't enjoy it. I understand it is a necessary evil in a company of size greater than two, and on the whole it isn't too bad. I am very lucky to work with talented hard working people.&lt;/p&gt;
&lt;p&gt;What I don't enjoy, however, is the AI incursions into my life that make me have to put on my manager hat beyond my regular people-management responsibilities. There are two aspects to this. One is AI nuisances in daily life, such as &lt;a href="https://moddedbear.com/gmail-thinks-im-stupid-so-i-left"&gt;Gmail's persistent suggestions&lt;/a&gt;, or AI search results clogging up what I'm actually looking for. On this front, I am no longer a user of a computer in control of the machine; I have become a parent to a child second guessing everything I'm saying. And as a parent of a 3 month old and a 5 year old, I certainly am not seeking more of this in my life.&lt;/p&gt;
&lt;p&gt;Thirty years ago, the problem used to be formulating my thoughts in a way the computer could parse, and as long as your intentions aligned with what the computer was capable of, you could have your way: a keystroke produced a character in a textbox, a formula entered produced a list of figures, a search query produced a list of results.
You were solely responsible for what you got.&lt;/p&gt;
&lt;p&gt;Today, the situation is scarcely better in terms of end result, but the frustration in getting there is dramatically heightened.
Now I need to plead with the computer that yes, I did mean to type what I did. No don't autocorrect it. And for God's sake stop shoving words into my mouth! Search results are no longer the best guess of what I meant, and instead a full-on re-interpretation of my words in order to fit my query to results that it would like to present to me.
It is the equivalent of interacting with someone who finishes all of your sentences. And as "efficient" as that may be, a paucity of words spoken was never the goal.
I must now manage the over-eager employee all too happy to please, at every turn of my computing life.
AI is a system that wishes to offload the burden of responsibility for taking action without assuming the responsibility of understanding the intended result.&lt;/p&gt;
&lt;p&gt;The second aspect is the use of AI at work. While I have managed (ha!) to avoid it until now, it is seeming more and more like an inevitability, as that is how the world of software engineering is shifting.
I am not a brilliant software engineer or architect.
My only advantages are having thought of combinations or trying them before other have, and most of the time it takes 3 or 4 iterations before I stumble upon the "right" way to build something. AI is supposed to help with this situation, by cutting down the iteration time, or removing it altogether.
But where I previously could understand the failings of iterated designs by having worked through them, how am I to evaluate the output of an AI now?
Claude can draft design documents explaining every decision it made, while I'm not even sure what questions should have been asked.&lt;/p&gt;
&lt;p&gt;People liken AI to junior employees. In the same way I don't particularly enjoy managing, I don't particularly enjoy mentoring either. I have always been a cowboy coder, and working with others does not come easily.
Where AI in daily life second guesses me, I must now second guess the LLM in every interaction.
It is now my problem to break down tasks into small chunks so that the AI can go off independently and not go wild while working on them.
I'm left doing the highest risk and lowest reward part of the job.
This is not why I chose this career.&lt;/p&gt;
&lt;p&gt;I always like to go back to the analogy with home building.
Using an LLM is like having to specify the location of every nail and screw in your blueprints, for fear that the AI will frame your wall with 100 screws per stud.
And while I'm sure the county building department would be happy to see this level of detail (who am I kidding, they'll spite you even harder), this is simply not how people work in practice. In the process of framing a house, you may find a stud interferes with a pipe or a structural member blocks access to fastening, and you adapt. You are a skilled carpenter; you can figure out a workaround on the spot that meets code.
Now, do you trust an LLM to do that, at every encounter where a spec conflicts with design architecture?
This is a level of micromanagement that would make me throw up my hands and do it myself.&lt;/p&gt;
&lt;p&gt;Since the dawn of mankind, we have sought to use technology to automate our lives or make our lives easier in some way. As a programmer, I think of it as the natural tendency to invest in laziness. In the modern age, what more laziness is there to achieve? We can eat food straight out of can while our eyes are glued to screens streaming enough content to fill a hundred lifetimes. The only advocates of AI at this point are corporations, in the demand for ever higher "productivity". This is productivity entirely divorced from the size of the harvest from an acre of land.
This is productivity aimed at extracting more value out of human capital, at engineering more financial instruments to rig markets, and build more addictive engagement platforms.&lt;/p&gt;
&lt;p&gt;And I am being asked to manage it.&lt;/p&gt;</content><category term="blog"/><category term="ai"/></entry><entry><title>The inhumanity of the metric system</title><link href="http://victorliu.info/metric-inhumanity.html" rel="alternate"/><published>2026-05-29T00:00:00-07:00</published><updated>2026-05-29T00:00:00-07:00</updated><author><name>Victor liu</name></author><id>tag:victorliu.info,2026-05-29:/metric-inhumanity.html</id><summary type="html">&lt;p&gt;The metric system is made for computation. I am not a computer.&lt;/p&gt;</summary><content type="html">&lt;p&gt;I despise the metric system. No, that's not quite accurate.
I'm an engineer in the field of computational photonics, so I gladly use the metric system all the time for work.
But in my personal life, I banish the metric system to a footlong ruler in the junk drawer.&lt;/p&gt;
&lt;h2&gt;On metric&lt;/h2&gt;
&lt;p&gt;Proponents of the metric system always cite two main points:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ease of conversion and calculation, since everything is based on a decimal system.&lt;/li&gt;
&lt;li&gt;The rest of the world uses it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To me, these are completely irrelevant. In daily life, quantities are measured, replicated, and rarely involved in calculations. If there are calculations, they involve addition and subtraction, which are as easy in whatever unit system you choose. 93 inches minus 45 inches is no harder to compute than 236 cm minus 114 cm.
If you were foolish enough to use a combination of feet and inches in the initial measurement when you knew you needed to perform arithmetic, that is on you.
Or else they involve multiplication and division by small integers. On this point, the metric system is inferior since unless you want to divide by 2, 5, or 10, you're going to have the same mental gymnastics as in the imperial system. For everything else, you're going to pull out a calculator anyways.&lt;/p&gt;
&lt;p&gt;I agree that the metric system is great for calculation, and avoids many common errors when performing conversions when units are not related by powers of 10.
For these purposes, I wholeheartedly support and even use the metric system. I suppose a fundamental assumption in the discussion on systems of units is that there should only be one. And on that point, &lt;em&gt;I emphatically disagree&lt;/em&gt;. Just as one should use the right tool for the job, so should one use the right units for the task.&lt;/p&gt;
&lt;p&gt;On the argument that the rest of the world uses it: I don't care. I don't live in the rest of the world. America did fine using SAE hardware sizes for decades. We survived on wire gauge and standard pipe threads and two-by-fours. Our cakes and souffles turn out a-ok with teaspoons and tablespoons. Oh, but you say, how will we import nuts and bolts from China then? This, I will reply, presupposes that we should do such a thing. In an age when global supply chains are seen as a risk, and with a growing made-in-America sentiment, I simply don't see why we should cater to international market forces on something as inherently sovreign as a system of units. I would go so far as to mandate SAE sizing for auto components, to encourage American manufacturing. I, too, hate having to stock metric and SAE socket sets in all my toolboxes. Why don't we keep using the one that has served us just fine since forever ago?&lt;/p&gt;
&lt;h2&gt;On definitions&lt;/h2&gt;
&lt;p&gt;Oh, but you say, the definitions of imperial units are based on arbitrary things, like King Henry's armspan.
Well, yes, as they should be, in a way. Units should be human centric, because, well, &lt;em&gt;they are used by humans&lt;/em&gt;.
A foot is great because it is easily relatable to the length of your foot. Sure, there's variation, but you'll have a pretty good sense for how big a foot is. If you need precision, that's why the tape measure was invented.
The precise definitions don't really matter, so long as they are defined. I'm even fine with (nay, fully supportive of) the redefinition of imperial units in terms of metric units.
What matters to me is the magnitude of the units. I like that an inch is as big as it is, so that things you can grasp in your hand measure a couple of inches.
I like that a foot is as long as it is so that things that can fit in your house are a couple of feet.
A yard is about as long as a pacing step, so you can estimate distances by pacing.
That there are multiple units of length, with a small degree of usage domain overlap, is ideal to me. More on this later.&lt;/p&gt;
&lt;h2&gt;On numbers&lt;/h2&gt;
&lt;p&gt;I hate numbers; I'm terrible with them.
I know, it's a funny thing for me to say, as a scientist or engineer, but I just can't stand numbers.
Maybe that's why I made a career out of making computers deal with them for me.
But the fewer and simpler the numbers I have to deal with, the better.
I imagine I am not alone in this sentiment.&lt;/p&gt;
&lt;p&gt;I cannot remember a number like 463.23. If you tell it to me, I'll forget in a matter of seconds.
It's simply too many digits, and jeez, there's even a decimal point!
4, 6, did the decimal point go here? One digit occured twice I think... you get the point.
To metric proponents, unit conversion is something to be avoided, because you may make a mistake in the conversion calculation.
Well, what about the mental tax of dealing with longer digit strings and decimal points, and the attendant transcription errors?
This merely shifts the errors to a different sort.&lt;/p&gt;
&lt;p&gt;As an engineer, numbers are half, nay, less than half the battle. The devil is in the tolerances, or sigfigs.
One rarely, in daily life, ever has to deal with anything tighter than 1% tolerance. If you do, you're doing it wrong.
Of course, you can't measure a board to greater than 1% tolerance and expect to build a house.
But, &lt;em&gt;why are you measuring such a dimension to replicate it&lt;/em&gt;? For all things like this that matter, the goal is almost always &lt;em&gt;replication&lt;/em&gt;, and for that, measuring is an unnecessary (and error-prone) detour. Cut to a template, use a jig, make marks, whatever you need to do. Just &lt;em&gt;don't use a tape measure&lt;/em&gt;.
In cooking, even that most precision-demanding discipline of baking does not require 1% accuracy. To specify 175 mL of an ingredient is a sigfig and a half too many. Why am I even looking at a 3 digit number?&lt;/p&gt;
&lt;p&gt;I see that I have been focusing on units of length, so let's look at weight.
The difference between a pound and a kilogram is about a factor of 2, so they are, for all intents and purposes, equivalent in their domains of application.
I would happily use kilograms in lieu of pounds.
The issue now, is what happens if you need a smaller unit. In imperial units, you go down to the ounce, a factor of 16 down.
In the metric system, one does not use the hectogram, or the decagram. No, one must go down by a factor of 1000 to the gram.
So if I want to express a quarter of a kilogram, now all of a sudden I have to deal with 250 of something.
Fuck. that. shit.
I don't want to deal with 250 of anything. That is simply too big a number to be juggling.
How heavy is a gram anyways? Do you know? I guarantee unless you're a drug dealer, it is unlikely you will be able to estimate a gram to within a factor of 5.
This, to me, is the true issue with metric units.
It is a decimal system, sure.
But it does not deal in factors of 10. The units, for all practical purposes, are set apart by factors of 1000.
And 1000 is waaay too big.&lt;/p&gt;
&lt;p&gt;I mentioned earlier that I like my units to have some small overlap in domains of application. That is, for small numbers of pounds, I could use ounces without ending up with huge numbers. Same goes for feet and inches, yards and feet, etc. The point is, I want there to be commonly used units that are set apart by about an order of magnitude. And I plan on using all of them. And there's nothing you can do about it.&lt;/p&gt;
&lt;h2&gt;On graduation&lt;/h2&gt;
&lt;p&gt;Let's talk temperature for a moment; this reliable starter of flame wars.
People love to say that Celsius is so logical because zero is freezing and 100 is boiling.
I'm sorry, &lt;em&gt;boiling&lt;/em&gt;? You were dead half the scale ago.
Also, I live at a half mile of elevation, so whose boiling are you talking about?
I do not concern myself with boiling temperatures except when cooking, and at that point, I'm dealing with a menagerie of high temperatures, like having to remember that the chicken needs to reach 165 F.
No. I can feel a 1 F temperature difference, and dammit, I want my scale to reflect that.
A scale where 0 is intolerably cold and 100 is intolerably hot and a change by 1 can be felt, is perfect.
The funny thing is, one end of the scale is not arbitrary. There is an absolute zero. But fuck if I want that to impact my daily measurements.
Let's accept that the scale is inherently arbitrary and pick the one that is human-relevant.&lt;/p&gt;
&lt;h2&gt;On humanity&lt;/h2&gt;
&lt;p&gt;This gets at the central issue I have with the metric system: it is not human centric. It is computation centric.
I am not a computer, nor do I strive to be.
When you tell me someone is 6' 3", at no point am I trying to add the quantities together to form a total.
I know my height, 5' 10", which is close to 6', so 6' 3" is like half a head taller.
That's it. End of computation. Most measurements are used for comparison, and if that is not enough, an intuitive feel for how much it is is all that is required.
The doctrinarian approach of accepting only the metric system is a denial of the world we live in, of the fact that we are humans.
"Oh haha, those silly people used stones as a weight measure! How primitive!" Well, yes, when you eat a staple grain everyday, it's nice to have a unit that is divisible by seven so you can easily figure out how much to buy on market day.
"But the pint isn't even standardized! It's different in different countries!" Look, if you're serious about drinking, it won't even matter. And if you're not, you're not ordering a pint.&lt;/p&gt;
&lt;p&gt;Metric absolutists are basically a bunch of pedants that like the theoretical ideal of measurement without understanding what it means to have to do it for 8 hours a day. Why don't we all speak Esperanto, while we're at it.
I for one am glad that imperial units are still in widespread use, and I will resist metrification at every opportunity I get.
I hope I don't live to see the day that metric becomes the only unit system allowed.
Until then, I'm going to keep buying 1/4-20 bolts, and all the M6 I find are going straight in the trash.&lt;/p&gt;</content><category term="essays"/><category term="units"/><category term="rant"/></entry><entry><title>Email letter to CUSD board and superintendents, 2026-05-28</title><link href="http://victorliu.info/20260528-letter-to-cusd.html" rel="alternate"/><published>2026-05-28T00:00:00-07:00</published><updated>2026-05-29T00:00:00-07:00</updated><author><name>Victor liu</name></author><id>tag:victorliu.info,2026-05-28:/20260528-letter-to-cusd.html</id><summary type="html">&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; See below for a summary of responses.&lt;/p&gt;
&lt;p&gt;To whom it may concern,&lt;/p&gt;
&lt;p&gt;You heard from me tonight during public comments at the board meeting. I am writing to better understand the process by which the list of improvements to West Point Elementary was assembled, and voice my concerns. For …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; See below for a summary of responses.&lt;/p&gt;
&lt;p&gt;To whom it may concern,&lt;/p&gt;
&lt;p&gt;You heard from me tonight during public comments at the board meeting. I am writing to better understand the process by which the list of improvements to West Point Elementary was assembled, and voice my concerns. For reference, I will repeat the list from the &lt;a href="https://docs.google.com/document/d/1hJ0AY5GSoRHH9SXSrRrtsx73UXBgDfpn/edit"&gt;Draft Bond Res&lt;/a&gt; as it currently stands here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Renovate, construct and modernize classrooms, multi-purpose rooms, and other school facilities including flooring, windows, window coverings, doors, lighting, interior and exterior finishes, fixtures, furniture and paint&lt;/li&gt;
&lt;li&gt;Repair/replace heating, ventilation &amp;amp; air conditioning (HVAC) systems&lt;/li&gt;
&lt;li&gt;Install door and window hardware, locks and/or safety treatments&lt;/li&gt;
&lt;li&gt;Repair, replace and or/upgrade paved surfaces and hardscape, including walkways, stairways and parking lots&lt;/li&gt;
&lt;li&gt;Renovate, repair and modernize restrooms&lt;/li&gt;
&lt;li&gt;Repair or replace leaky roofs&lt;/li&gt;
&lt;li&gt;Upgrade and expand campus-wide wireless systems and telecommunications, internet, and network connections. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Having attended PTG meetings and interacted with the school staff, it is clear to me that there is an over-reliance on over-worked (and at this point, disillusioned) maintenance staff to provide suggestions for renovations and improvements, staff who have no time to go out of their way to evaluate the severity of issues. I would like to provide some of my own observations, having volunteered my time and resources into making a number of repairs at the school with the support of the PTG:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The siding on the buildings is in severe disrepair. I know this falls under the first bullet point above, but I worry that there will not be a focus on this issue. In fact, the siding is so severely rotted in many places that the underlying framing is called into question. Previous attempts to "repair" the siding have simply slapped new siding on top of old, concealing the ever-growing problem. I hope this mistake will not be repeated.&lt;/li&gt;
&lt;li&gt;A number of sheds and storage buildings have broken windows and leaking roofs. Please call this out specifically, since many parents know about these problems.&lt;/li&gt;
&lt;li&gt;The bell tower that stands above the preschool room is severely damaged by rot and woodpeckers. It may not be at the point of structural compromise, but to a casual observer, it does not inspire confidence in the rest of the facilities. It is particularly visible and so I think it is best to address it, if for no reason other than the optics.&lt;/li&gt;
&lt;li&gt;Regarding the HVAC, I would hope that repair and re-engineering is prioritized over replacement, since the system was replaced 4 years ago. It would be good to call out the fact that the recently installed system actually does not currently work as intended.&lt;/li&gt;
&lt;li&gt;I have been told that there are idiosyncracies with the phone or internet system where all traffic is routed through the district office, so that when power is out at the district office, WP loses phone service even if we have power. I hope this is being addressed.&lt;/li&gt;
&lt;li&gt;The irrigation system is broken or not adjusted right; there are puddles in the middle of the track and in front of the office for days or weeks at a time, even during the driest parts of the year. I keep hearing insistence that it is working fine.&lt;/li&gt;
&lt;li&gt;I do not want to re-hash the issue of the library, but if you could find funds to place another modular on the campus for SHEC or the library, that would go a long way to restoring ties with the West Point community. I believe in books, and I believe in technology. I work in high tech myself. But there is a place for physical books, and it is at a school and its library. Maybe make this a stretch goal.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These are merely the things that I have noticed, as an observant parent that picks up my daughter from school. Undoubtedly, other parents have noticed other things.&lt;/p&gt;
&lt;p&gt;I also hope that someone has actually talked to Mrs. Hood in person, not just asked for a list and play the game of telephone.&lt;/p&gt;
&lt;p&gt;And here is my main point:&lt;/p&gt;
&lt;p&gt;I cannot emphasize enough that the bullet points above need to be incredibly specific, so that an interested parent can read something that they themselves have noticed or recognize as a problem, and see that the district also understands it to be a problem. Or else, what you want is for someone to read the list, and be able to go to the school and verify for themselves that it is a problem. Right now, the vagueness of the bullet points just makes CUSD seem out of touch and blind to the problems on the ground.&lt;/p&gt;
&lt;p&gt;Finally, why is Railroad Flat Elementary even on the list? I thought that campus was sold off. I think a lot of locals would question why funds are being spent on a campus that is no longer operating.&lt;/p&gt;
&lt;p&gt;Signed,&lt;/p&gt;
&lt;p&gt;Victor Liu&lt;/p&gt;
&lt;p&gt;A concerned parent and ardent supporter of public education&lt;/p&gt;
&lt;p&gt;Sent to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ron Estes&lt;/li&gt;
&lt;li&gt;Kassie Meeks&lt;/li&gt;
&lt;li&gt;Scott Crisp&lt;/li&gt;
&lt;li&gt;Matt Brock&lt;/li&gt;
&lt;li&gt;Lorraine Angel&lt;/li&gt;
&lt;li&gt;Bryan Porath&lt;/li&gt;
&lt;li&gt;Monica Remus&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Update 2026-05-29&lt;/strong&gt; I received a thoughtful and detailed response from Kassie Meeks, the incoming superintendent, and an acknowledgement from Noreen Puisis, maintenance and operations supervisor that the siding issues are included in the 5-year deferred maintenance plan.&lt;/p&gt;</content><category term="letters"/><category term="letter calaverasusd westpointelementary"/></entry><entry><title>A legible home computer</title><link href="http://victorliu.info/legible-home-computer.html" rel="alternate"/><published>2026-05-26T00:00:00-07:00</published><updated>2026-05-26T00:00:00-07:00</updated><author><name>Victor liu</name></author><id>tag:victorliu.info,2026-05-26:/legible-home-computer.html</id><summary type="html">&lt;p&gt;TL;DR: Modern computing sucks. Let's go back to the 90s, but redesign things more sensibly.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://techtrenches.dev/p/the-great-software-quality-collapse"&gt;Many&lt;/a&gt;
&lt;a href="https://danluu.com/nothing-works/"&gt;articles&lt;/a&gt;
&lt;a href="https://www.versobooks.com/products/3341-enshittification"&gt;have&lt;/a&gt;
&lt;a href="https://wiki.xxiivv.com/site/permacomputing.html"&gt;been&lt;/a&gt;
&lt;a href="https://collapseos.org/why.html"&gt;written&lt;/a&gt;
on the
&lt;a href="https://josephg.com/blog/electron-is-flash-for-the-desktop/"&gt;deplorable&lt;/a&gt;
&lt;a href="https://boingboing.net/2012/08/23/civilwar.html"&gt;state&lt;/a&gt;
of modern computing and the world in general.
The fact that somehow 8 GB of RAM in 2026 is considered "insufficient" is mindboggling,
considering I …&lt;/p&gt;</summary><content type="html">&lt;p&gt;TL;DR: Modern computing sucks. Let's go back to the 90s, but redesign things more sensibly.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://techtrenches.dev/p/the-great-software-quality-collapse"&gt;Many&lt;/a&gt;
&lt;a href="https://danluu.com/nothing-works/"&gt;articles&lt;/a&gt;
&lt;a href="https://www.versobooks.com/products/3341-enshittification"&gt;have&lt;/a&gt;
&lt;a href="https://wiki.xxiivv.com/site/permacomputing.html"&gt;been&lt;/a&gt;
&lt;a href="https://collapseos.org/why.html"&gt;written&lt;/a&gt;
on the
&lt;a href="https://josephg.com/blog/electron-is-flash-for-the-desktop/"&gt;deplorable&lt;/a&gt;
&lt;a href="https://boingboing.net/2012/08/23/civilwar.html"&gt;state&lt;/a&gt;
of modern computing and the world in general.
The fact that somehow 8 GB of RAM in 2026 is considered "insufficient" is mindboggling,
considering I was able to accomplish almost everything I needed of a computer on a Mac IIsi with mere megabytes of RAM.
More troubling, however, is the utter inscrutability of modern computers.
Not only has the software grown to inordinate complexity, so has the hardware.
It is no longer possible to maintain a working mental model of how a CPU works,
given branch prediction and the myriad levels of caching.
I want to go back to a time when &lt;a href="https://www.vintagecomputing.com/index.php/archives/3292/the-pc-is-dead-its-time-to-make-computing-personal-again"&gt;computing was personal&lt;/a&gt;, and computers were legible.
Legible in the sense used in &lt;a href="https://en.wikipedia.org/wiki/Seeing_Like_a_State"&gt;Seeing Like a State&lt;/a&gt; by James C. Scott, where it used to mean, roughly: observable, comprehensible, and controllable.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://github.com/slu4coder/Minimal-64x4-Home-Computer"&gt;Minimal 64x4 Home Computer&lt;/a&gt; is an example of a legible computing system.
It is defined entirely using readily available ICs (7400 logic and a handful of memory chips).
Its system architecture and microcode are easily describable.
To me, this system nearly achieves perfect legibility.
The least ideal aspect is its VGA subsystem; it uses non-standard VGA timing which many modern displays refuse to handle.&lt;/p&gt;
&lt;p&gt;I am setting about a years long project to build legible personal computing systems for myself. As a start, in this article, I will outline the basic requirements. Then, I will move on to design and implementation. Note that I say "systems": there will likely be multiple incarnations of varying complexity or sophistication as I explore and understand what I actually need out of computing.&lt;/p&gt;
&lt;p&gt;To begin with, I would like to list out some basic tasks that I expect to be able to perform:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Numeric calculations: Support for basic functions of a scientific calculator using floating point. Ideally, using BCD so that financial calculations are performed exactly.&lt;/li&gt;
&lt;li&gt;Text editing and word processing: editing text documents, and possibly limited formatting support.&lt;/li&gt;
&lt;li&gt;Spreadsheets: functionality similar to Visicalc or Lotus 123.&lt;/li&gt;
&lt;li&gt;Bitmap drawing editor: A basic Macpaint-like capability.&lt;/li&gt;
&lt;li&gt;Vector drawing editor: The ability to make diagrams. and possibly some architectural CAD or circuit schematic drawings.&lt;/li&gt;
&lt;li&gt;Data export: Saving files and data to a micro SD card to interface with modern computing. Also: the ability to print to a serial or network printer.&lt;/li&gt;
&lt;li&gt;Input methods: PS/2 keyboard and mouse support, possibly other HCI methods such as rotary encoders.&lt;/li&gt;
&lt;li&gt;Backups and bootstrappability: Must have two "disk drives" so that "disks" can be duplicated.&lt;/li&gt;
&lt;li&gt;Internet access: Possibly TCP/IP support to access rudimentary internet pages or alternative protocols like gopher.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This list is not meant to be exhaustive; additional functionality that interpolates these capabilities should be possible.&lt;/p&gt;
&lt;p&gt;I think I should also be clear what is &lt;em&gt;not&lt;/em&gt; required:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Multimedia: I am uninterested in video, sound, and games in general.&lt;/li&gt;
&lt;li&gt;Color: I would much prefer a higher resolution bitmapped display if that means sacrificing color depth. I am perfectly fine with 1-bit graphics. I would also rather have color planes, such as is used in e-paper displays, rather than deal with the complexity of sub-8-bit pixel data.&lt;/li&gt;
&lt;li&gt;Software compatibility: I fully expect to need to rewrite great swaths of the entire software stack in order to achieve my desired hardware architecture. Virtual machines such as &lt;a href="https://100r.co/site/uxn.html"&gt;uxn&lt;/a&gt; may alleviate some of the pains.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There are some high level architectural considerations that must be decided first. I think one aspect that is immediately fixed by this list is the need for fully bitmapped graphics; text mode a la the C64 will not suffice. Something more akin to the Macintosh is required. This requirement means that a full resolution framebuffer is also required, pigeon-holing us into a Macintosh-like architecture in which the graphics subsystem drives the clock and timing of the CPU and everything else.&lt;/p&gt;
&lt;p&gt;The next major decision is the CPU to use, or more importantly, the bit width of the CPU. For the type of general purpose computing I am imagining, an 8-bit CPU with a 16-bit address space means a 64kb address space. The framebuffer will occupy approximately half of that unless banking is used, which does not leave much for actual computing use. Thus, 8-bit computing is largely out the window if we want to cover the entire list above.&lt;/p&gt;
&lt;p&gt;However, since discovering the Minimal 64x4, I am somewhat wedded to its simplicity, and so I would like to continue exploring the limits of such an 8-bit platform lacking interrupts. At this point, the plan bifurcates; one path will use the Minimal 64x4 as a base and explore expansion cards and possibly hardware variations, while the other will use an integrated CPU.&lt;/p&gt;
&lt;p&gt;The choice of &amp;gt;8-bit CPU that is well-understood and simple enough is fairly limited. The choices are going to be circa 80s era parts such as the 8086, 80286, 65C816, Z8000, 68000. Of this list, I am only really interested in the 68000. Partly due to its use in the original Macintosh, partly due to a long time personal interest in learning m68k assembly, and partly because of my past experience dealing with the memory segmentation of the '86 family.&lt;/p&gt;
&lt;p&gt;Thus, it is decided:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Using the Minimal 64x4 CPU as a base platform, explore peripheral expansion to support items 1-6 in the requirements list. Possibly explore modifying the VGA section to support standard VGA timing with a 512x480 framebuffer (more on this later).&lt;/li&gt;
&lt;li&gt;Design a Mac-like computer based on the 68000 (or 68010) with a modern peripheral set.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The next posts will expand on this, while a project page will track the conclusions.&lt;/p&gt;</content><category term="blog"/><category term="computing"/></entry><entry><title>First yard mowing of 2026</title><link href="http://victorliu.info/mowing-2026.html" rel="alternate"/><published>2026-05-25T00:00:00-07:00</published><updated>2026-05-25T00:00:00-07:00</updated><author><name>Victor liu</name></author><id>tag:victorliu.info,2026-05-25:/mowing-2026.html</id><summary type="html">&lt;p&gt;I mowed the yard today. Well, actually, it was with a weedeater, but the effect
is the same. I am writing this note to remember for next year that this is too
late by about two weeks. The last rain was about two weeks ago, and that was
when the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I mowed the yard today. Well, actually, it was with a weedeater, but the effect
is the same. I am writing this note to remember for next year that this is too
late by about two weeks. The last rain was about two weeks ago, and that was
when the velcro ball weeds (hedge parsley, aka sock destroyer) were still tender
and pre-flowering. This year, the mowing is just spreading the seeds, so next
year will be a real doozy.&lt;/p&gt;
&lt;p&gt;There is apparently a chance of rain tomorrow morning. Highly unusual that we
should get rain so far into May.&lt;/p&gt;</content><category term="blog"/><category term="update"/></entry><entry><title>Starting again</title><link href="http://victorliu.info/starting-again.html" rel="alternate"/><published>2026-05-24T00:00:00-07:00</published><updated>2026-05-24T00:00:00-07:00</updated><author><name>Victor liu</name></author><id>tag:victorliu.info,2026-05-24:/starting-again.html</id><summary type="html">&lt;p&gt;Redesign of this site, and another attempt to keep up blogging.&lt;/p&gt;</summary><content type="html">&lt;p&gt;It's time for a refresh of this site, and a new attempt at blogging.
I have since lost the sources of the previous pages, but it's fairly trivial to figure it all out.
The &lt;a href="http://victorliu.info/pages/construction.html"&gt;construction&lt;/a&gt; page isn't completely working yet; I'll need to figure out how to get the Pelican templating to work on javascript code.&lt;/p&gt;
&lt;p&gt;The plan for the next set of content is my work towards a legible home computing system, starting from the &lt;a href="https://github.com/slu4coder/Minimal-64x4-Home-Computer"&gt;Minimal 64x4&lt;/a&gt;.&lt;/p&gt;</content><category term="blog"/><category term="update"/></entry><entry><title>Circular arcs 4 - extrema</title><link href="http://victorliu.info/arc4-extrema.html" rel="alternate"/><published>2018-12-27T00:00:00-08:00</published><updated>2025-05-24T00:00:00-07:00</updated><author><name>Victor liu</name></author><id>tag:victorliu.info,2018-12-27:/arc4-extrema.html</id><summary type="html">&lt;p&gt;One basic operation upon shapes is to compute bounding regions.
For a shape made up of pieces of simple curves, this amounts to computing directional extrema on the curve.
In other words, given a curve and a direction vector &lt;span class="math"&gt;\(d\)&lt;/span&gt; (without loss of generality we assume it is normalized),
determine …&lt;/p&gt;</summary><content type="html">&lt;p&gt;One basic operation upon shapes is to compute bounding regions.
For a shape made up of pieces of simple curves, this amounts to computing directional extrema on the curve.
In other words, given a curve and a direction vector &lt;span class="math"&gt;\(d\)&lt;/span&gt; (without loss of generality we assume it is normalized),
determine the point that maximizes the dot product of &lt;span class="math"&gt;\(d\)&lt;/span&gt; and the vector from the origin to the point.
In addition to the point, we typically would also like to know the parameter value of the extremal point.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="http://victorliu.info/images/figures/arc/extremum.svg"&gt;
&lt;figcaption&gt;The point E is the extremum of the arc in the direction d.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;For a circular arc, there are two cases: the extremum may be an endpoint, or it may be interior to the arc.
For any parameter value &lt;span class="math"&gt;\(s\)&lt;/span&gt;, we shall call the aforementioned dot product &lt;span class="math"&gt;\(P(s) = \left[p(s)-0\right]\cdot d\)&lt;/span&gt;,
where &lt;span class="math"&gt;\(0\)&lt;/span&gt; is the origin.
Clearly, it is trivial to compute &lt;span class="math"&gt;\(P(0)\)&lt;/span&gt; and &lt;span class="math"&gt;\(P(1)\)&lt;/span&gt; and we shall compare the value at
any other interior points against the extremal point.&lt;/p&gt;
&lt;p&gt;For &lt;span class="math"&gt;\(g\)&lt;/span&gt; sufficiently far from zero, one may compute the center of the circle &lt;span class="math"&gt;\(C\)&lt;/span&gt; and its radius &lt;span class="math"&gt;\(r\)&lt;/span&gt;,
and any interior extremum must be at &lt;span class="math"&gt;\(E = C+rd\)&lt;/span&gt;.
The only task is determining if &lt;span class="math"&gt;\(E\)&lt;/span&gt; lies on the arc.
For the smaller half of a circle when &lt;span class="math"&gt;\(g&amp;lt;1\)&lt;/span&gt;, &lt;span class="math"&gt;\(E\)&lt;/span&gt; lies on the arc if &lt;span class="math"&gt;\((A-C)\times(E-C) &amp;gt; 0\)&lt;/span&gt; and &lt;span class="math"&gt;\((E-C)\times(B-C)&amp;gt; 0\)&lt;/span&gt;.
Otherwise for &lt;span class="math"&gt;\(g&amp;gt;1\)&lt;/span&gt;, then we require that then "and" is replaced by "or".
The parameter value can be obtained by any parameterization method discussed in the &lt;a href="http://victorliu.info/arc3-parameterization.html"&gt;previous article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For &lt;span class="math"&gt;\(g\)&lt;/span&gt; near zero, the situation is slightly trickier.
From the algorithm for evaluation, differentiation provides a method to compute the tangents to the arc,
particularly at the endpoints.
Therefore, the outward normals to the arc are readily computable, and let us denote them by &lt;span class="math"&gt;\(n_A\)&lt;/span&gt; and &lt;span class="math"&gt;\(n_B\)&lt;/span&gt;.
Since &lt;span class="math"&gt;\(g\)&lt;/span&gt; is small in magnitude, we can determine inclusion of the extremum within the arc again using cross products.
We simply require than &lt;span class="math"&gt;\(n_A \times d &amp;gt; 0\)&lt;/span&gt; and &lt;span class="math"&gt;\(d \times n_B &amp;gt; 0\)&lt;/span&gt;.
The harder task is determining the point itself, and it is perhaps easiest to compute the parameter value directly through trigonometry:&lt;/p&gt;
&lt;div class="math"&gt;$$ s = \frac{\tan^{-1}\frac{n_A\times d}{n_A\cdot d}}{2\theta} = \frac{\tan^{-1}\frac{n_A\times d}{n_A\cdot d}}{4\tan^{-1}g} \in [0,1] $$&lt;/div&gt;
&lt;p&gt;In implementation, there are a few additional annoying details,
such as correctly handling the sign of &lt;span class="math"&gt;\(g\)&lt;/span&gt;, and ensuring that the arctangents are computed on the right branch, &amp;amp;c.&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="exposition"/><category term="math geometry computational-geometry"/></entry><entry><title>Circular arcs 3 - parameterization</title><link href="http://victorliu.info/arc3-parameterization.html" rel="alternate"/><published>2018-12-02T00:00:00-08:00</published><updated>2025-05-24T00:00:00-07:00</updated><author><name>Victor liu</name></author><id>tag:victorliu.info,2018-12-02:/arc3-parameterization.html</id><summary type="html">&lt;p&gt;In the last article, we discussed how to compute a point on the arc given a parameter value.
In this article, we explore the inverse problem of computing the parameter value given a point (approximately) on the arc.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="http://victorliu.info/images/figures/arc/eval_fig.svg"&gt;
&lt;figcaption&gt;Parameters used for arc evaluation and parameterization.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;To recap, we obtained the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In the last article, we discussed how to compute a point on the arc given a parameter value.
In this article, we explore the inverse problem of computing the parameter value given a point (approximately) on the arc.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="http://victorliu.info/images/figures/arc/eval_fig.svg"&gt;
&lt;figcaption&gt;Parameters used for arc evaluation and parameterization.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;To recap, we obtained the following results for evaluation:&lt;/p&gt;
&lt;div class="math"&gt;$$ X(s) - M = \begin{bmatrix} g\left(\chi_s^2 - \chi_c^2\right) &amp;amp; \left(1+g^2\right) \chi_s\chi_c \\ -\left(1+g^2\right) \chi_s\chi_c &amp;amp; g\left(\chi_s^2 - \chi_c^2\right) \end{bmatrix} h^\perp $$&lt;/div&gt;
&lt;div class="math"&gt;$$ \chi_c = \cos\frac{\sigma\theta}{2} \qquad \chi_s = \frac{1}{g}\sin\frac{\sigma\theta}{2} $$&lt;/div&gt;
&lt;p&gt;We will now define the matrix elements to be&lt;/p&gt;
&lt;div class="math"&gt;$$ p = g\left(\chi_s^2 - \chi_c^2\right) \qquad q = \left(1+g^2\right) \chi_s\chi_c $$&lt;/div&gt;
&lt;p&gt;The first step to invert this is to reformulate the linear system to make &lt;span class="math"&gt;\(p\)&lt;/span&gt; and &lt;span class="math"&gt;\(q\)&lt;/span&gt; the variables and solve for them:&lt;/p&gt;
&lt;div class="math"&gt;$$ \begin{bmatrix} p\\q \end{bmatrix} = \begin{bmatrix} h^\perp &amp;amp; h \end{bmatrix}^{-1} \left(X-M\right) = \frac{1}{\left\lVert h \right\rVert^2} \begin{bmatrix} h^\perp &amp;amp; h \end{bmatrix} \left(X-M\right) $$&lt;/div&gt;
&lt;figure&gt;
&lt;img src="http://victorliu.info/images/figures/arc/arc_parameterization1.svg" width="256"&gt;
&lt;figcaption&gt;Parameter value (in [-1,1]) in the neighborhood of an arc with g = 0.6, assuming constant bulge factor.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Next, note that from the definitions of &lt;span class="math"&gt;\(\chi_c\)&lt;/span&gt; and &lt;span class="math"&gt;\(\chi_s\)&lt;/span&gt;, we seek&lt;/p&gt;
&lt;div class="math"&gt;$$ \sigma = \frac{\tan^{-1} g\chi_s/\chi_c}{\tan^{-1} g} = \frac{\tan^{-1} rg}{\tan^{-1} g} $$&lt;/div&gt;
&lt;p&gt;Therefore, &lt;span class="math"&gt;\(\sigma\)&lt;/span&gt; depends only on the ratio &lt;span class="math"&gt;\(r = \chi_s/\chi_c\)&lt;/span&gt;.
From the definitions of &lt;span class="math"&gt;\(p\)&lt;/span&gt; and &lt;span class="math"&gt;\(q\)&lt;/span&gt;, we can form &lt;span class="math"&gt;\(p = g\left(r^2 - 1\right)\chi_c^2\)&lt;/span&gt; and &lt;span class="math"&gt;\(q = \left(1+g^2\right)r\chi_c^2\)&lt;/span&gt;. Eliminating &lt;span class="math"&gt;\(\chi_c^2\)&lt;/span&gt; from both results in the quadratic equation in &lt;span class="math"&gt;\(r\)&lt;/span&gt;:&lt;/p&gt;
&lt;div class="math"&gt;$$ gqr^2 - p\left(1+g^2\right) r - gq = 0 $$&lt;/div&gt;
&lt;p&gt;The desired root is the one of smaller magnitude (not greater than 1), resulting in a value of &lt;span class="math"&gt;\(\sigma\)&lt;/span&gt; that is also in the same range.
A plot of the parameter &lt;span class="math"&gt;\(\sigma\)&lt;/span&gt; in the neighborhood of an arc with &lt;span class="math"&gt;\(g=0.6\)&lt;/span&gt; is shown in the figure on the right.
Notice that sectors divide the arc into sections of equal arc length.&lt;/p&gt;
&lt;p&gt;For points exactly on the arc, this method should exactly recover the parameter value (since it is a direct inversion of the forward evaluation method).
However for points off the arc, this method produces results that deviate in a rather unintuitive way since the contours of constant parameter emanate as straight lines from the chord midpoint.
One may derive a better parameterization method by treating the problem as assigning a parameter value to each point on the plane, rather than just the restriction to points on the arc.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="http://victorliu.info/images/figures/arc/arc_parameterization2.svg" width="256"&gt;
&lt;figcaption&gt;Parameter value (in [-1,1]) in the neighborhood of an arc with g = 0.6, assuming g is computed for an arc passing through each point.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;One simple method is to compute the arc with the same endpoints, but passing through each given point, and computing the parameter on this new arc.
Phrased differently, we are modifying the lines of constant parameter value to instead trace the points with same parameter value through all arcs with the given endpoints.
This corresponds to solving for &lt;span class="math"&gt;\(g\)&lt;/span&gt; first, and substituting that into the preceeding calculations.
The value of &lt;span class="math"&gt;\(g\)&lt;/span&gt; that corresponds to an arc with endpoints &lt;span class="math"&gt;\(A\)&lt;/span&gt; and &lt;span class="math"&gt;\(B\)&lt;/span&gt;, and passing through a point &lt;span class="math"&gt;\(X\)&lt;/span&gt; can be computed by first decomposing &lt;span class="math"&gt;\(X-M\)&lt;/span&gt; into components parallel and perpendicular to the chord.
We may define&lt;/p&gt;
&lt;div class="math"&gt;$$ \alpha = \frac{\left(X-M\right)\cdot\left(M-A\right)}{\left\lVert M-A\right\rVert^2} \qquad \beta = \frac{\left(X-M\right)\times\left(M-A\right)}{\left\lVert M-A\right\rVert^2} $$&lt;/div&gt;
&lt;p&gt;Applying the Pythagorean theorem results in a palindromic quadratic equation in &lt;span class="math"&gt;\(g\)&lt;/span&gt;:&lt;/p&gt;
&lt;div class="math"&gt;$$ \beta g^2 + g\left(1-\alpha^2-\beta^2\right)-\beta = 0 $$&lt;/div&gt;
&lt;p&gt;In this case if &lt;span class="math"&gt;\(g\)&lt;/span&gt; is a root, then &lt;span class="math"&gt;\(-1/g\)&lt;/span&gt; is the other root. The root chosen should match the sign of &lt;span class="math"&gt;\(\beta\)&lt;/span&gt;.
A plot of this new parameterization is shown on the right.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="http://victorliu.info/images/figures/arc/arc_parameterization3.svg" width="256"&gt;
&lt;figcaption&gt;Parameter value (in [-1,1]) in the neighborhood of an arc with g = 0.6, using a parameterization insensitive to deviations in the radial direction.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Finally, one desirable property for a parameterization would be that it is insensitive to errors in the direction normal to the arc (along the radial direction of the parent circle).
This is equivalent to selecting lines of constant parameter to intersect the arc orthogonally.
This is a fairly loose requirement, and there are an infinite set of possible parameterizations of the entire plane that respect this constraint.
We shall select one that is algorithmically simple.
The most straightforward selection is to choose the constant parameter lines that radiate linearly from the center of the circle defining the arc.
Of course, we do not want to compute the center explicitly.
However, using the previous definition of &lt;span class="math"&gt;\(\alpha\)&lt;/span&gt; and &lt;span class="math"&gt;\(\beta\)&lt;/span&gt; and again applying the Pythagorean theorem, we see that the angle relative to &lt;span class="math"&gt;\(-h^\perp\)&lt;/span&gt; is
&lt;/p&gt;
&lt;div class="math"&gt;$$ -\tan^{-1} \frac{2g\alpha}{2g\beta+1-g^2} $$&lt;/div&gt;
&lt;p&gt;
Therefore, perhaps the simplest and most desirable parameterization is computed by&lt;/p&gt;
&lt;div class="math"&gt;$$ \sigma = -\frac{1}{2} \frac{\tan^{-1} \frac{2g\alpha}{2g\beta+1-g^2}}{\tan^{-1} g} $$&lt;/div&gt;
&lt;p&gt;with &lt;span class="math"&gt;\(\alpha\)&lt;/span&gt; and &lt;span class="math"&gt;\(\beta\)&lt;/span&gt; defined above.
A plot of this parameterization is shown on the right.&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="exposition"/><category term="math geometry computational-geometry"/></entry><entry><title>Circular arcs 2 - evaluation</title><link href="http://victorliu.info/arc2-evaluation.html" rel="alternate"/><published>2018-11-29T00:00:00-08:00</published><updated>2025-05-24T00:00:00-07:00</updated><author><name>Victor liu</name></author><id>tag:victorliu.info,2018-11-29:/arc2-evaluation.html</id><summary type="html">&lt;p&gt;Continuing the series on circular arc representations, we next discuss the most fundamental operation of curve representation: evaluation at an arbitrary parameter value.&lt;/p&gt;
&lt;p&gt;The typically most desirable parameterization is arc length parameterization.
We will use instead a parameter &lt;span class="math"&gt;\(s\in[0,1]\)&lt;/span&gt; that is proportional to the arc length parameterization …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Continuing the series on circular arc representations, we next discuss the most fundamental operation of curve representation: evaluation at an arbitrary parameter value.&lt;/p&gt;
&lt;p&gt;The typically most desirable parameterization is arc length parameterization.
We will use instead a parameter &lt;span class="math"&gt;\(s\in[0,1]\)&lt;/span&gt; that is proportional to the arc length parameterization.
The scale factor is simply the arc's length, equal to &lt;span class="math"&gt;\(2 r \theta\)&lt;/span&gt;, where &lt;span class="math"&gt;\(r = \frac{2g}{1+g^2}t\)&lt;/span&gt; and &lt;span class="math"&gt;\(g = \tan \frac{\theta}{2}\)&lt;/span&gt;.
Computation of the arc's length will be discussed in detail in a later article.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="http://victorliu.info/images/figures/arc/eval_fig.svg"&gt;
&lt;figcaption&gt;Parameters used for arc evaluation.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The naive thing to do would be to compute the center of the circle, and rotate the radius vector along the arc.
However, as discussed in the previous article, the circle center and radius are ill-defined for nearly-straight arcs.
In other words, we would like our parameterization to be valid and robust for straight line segments.&lt;/p&gt;
&lt;p&gt;All is not lost, however.
We will begin with this approach and shore it up into something robust.
To begin with, the circle center is:&lt;/p&gt;
&lt;div class="math"&gt;$$ C = \frac{A+B}{2} + \frac{1-g^2}{2g} \frac{(B-A)^\perp}{2} $$&lt;/div&gt;

&lt;p&gt;The radius is:&lt;/p&gt;
&lt;div class="math"&gt;$$ r = \frac{1+g^2}{2g} \left\lVert \frac{B-A}{2} \right\rVert $$&lt;/div&gt;

&lt;p&gt;Our desired operation now is to apply a rotation matrix to obtain the point on the arc.
Let &lt;span class="math"&gt;\(X(s)\)&lt;/span&gt; be the desired point:&lt;/p&gt;
&lt;div class="math"&gt;$$ X(s) = C - \begin{bmatrix} \cos \sigma \theta &amp;amp; -\sin\sigma\theta \\ \sin\sigma\theta &amp;amp; \cos\sigma\theta \end{bmatrix} \frac{1+g^2}{2g} \frac{(B-A)^\perp}{2} = C - \frac{1+g^2}{2g} R(\sigma\theta) h^\perp $$&lt;/div&gt;

&lt;p&gt;where &lt;span class="math"&gt;\(\sigma = 2s-1 \in [-1,1]\)&lt;/span&gt;. We change notation slightly from last time and let &lt;span class="math"&gt;\(h=\frac{B-A}{2}\)&lt;/span&gt; be the half-chord &lt;em&gt;vector&lt;/em&gt;.
Since the chord midpoint is a well defined point, we let &lt;span class="math"&gt;\(M=\frac{A+B}{2}\)&lt;/span&gt;.
We can expand the equation above to obtain:&lt;/p&gt;
&lt;div class="math"&gt;$$ X(s) - M = \left[ \frac{1-g^2}{2g} + \frac{1+g^2}{2g} R(\sigma \theta) \right] h^\perp $$&lt;/div&gt;

&lt;p&gt;The off-diagonal element of the matrix in brackets is&lt;/p&gt;
&lt;div class="math"&gt;$$ -\frac{1+g^2}{2g} \sin \sigma\theta = -\frac{1+g^2}{g} \sin\frac{\sigma\theta}{2}\cos\frac{\sigma\theta}{2}$$&lt;/div&gt;

&lt;p&gt;The diagonal element is&lt;/p&gt;
&lt;div class="math"&gt;$$ \frac{1-g^2}{2g} - \frac{1+g^2}{2g}\cos\sigma\theta = \frac{1}{g}\sin^2 \frac{\sigma\theta}{2} - g\cos^2\frac{\sigma\theta}{2} $$&lt;/div&gt;

&lt;p&gt;Both of these expression depend on two quantities that are bounded:&lt;/p&gt;
&lt;div class="math"&gt;$$ \chi_c = \cos\frac{\sigma\theta}{2} \qquad \chi_s = \frac{1}{g}\sin\frac{\sigma\theta}{2} $$&lt;/div&gt;

&lt;p&gt;The final expression is then&lt;/p&gt;
&lt;div class="math"&gt;$$ X(s) - M = \begin{bmatrix} g\left(\chi_s^2 - \chi_c^2\right) &amp;amp; \left(1+g^2\right) \chi_s\chi_c \\ -\left(1+g^2\right) \chi_s\chi_c &amp;amp; g\left(\chi_s^2 - \chi_c^2\right) \end{bmatrix} h^\perp $$&lt;/div&gt;

&lt;p&gt;All that remains is to compute the required quantities stably.
The angle can be computed simply by &lt;span class="math"&gt;\(\frac{\theta}{2} = \tan^{-1} g\)&lt;/span&gt;.
The quantity &lt;span class="math"&gt;\(\chi_s\)&lt;/span&gt; can be expanded about &lt;span class="math"&gt;\(g = 0\)&lt;/span&gt; as:&lt;/p&gt;
&lt;div class="math"&gt;$$ \chi_s(g) = s\left[ 1 - \frac{g}{6}\left(s^2+2\right) + O(g^2) \right] $$&lt;/div&gt;

&lt;p&gt;One may wonder if this is the "best" way to perform the evaluation.
Due to the uniqueness of the parameterization, any other method that correctly computes the parameterized point must, in some sense, be equivalent to this one.
The principal argument, to me, that this is a good algorithm, is that it respects affine geometry (coordinate free) and applies a transformation matrix to the chord half-vector. In the perfectly conditioned semicircular case of &lt;span class="math"&gt;\(g=\pm1\)&lt;/span&gt;, the matrix reduces to a simple orthogonal rotation matrix. For &lt;span class="math"&gt;\(\left|g\right| &amp;lt; 1\)&lt;/span&gt;, the point is effectively computed as an affine combination of the endpoints and &lt;span class="math"&gt;\(M-h^\perp\)&lt;/span&gt;, all of which are well-defined points.&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="exposition"/><category term="math geometry computational-geometry"/></entry><entry><title>Circular arcs 1 - representation</title><link href="http://victorliu.info/arc1-representation.html" rel="alternate"/><published>2018-11-27T00:00:00-08:00</published><updated>2025-05-24T00:00:00-07:00</updated><author><name>Victor liu</name></author><id>tag:victorliu.info,2018-11-27:/arc1-representation.html</id><summary type="html">&lt;p&gt;I have written a &lt;a href="http://victorliu.info/pdfs/arc_spline.pdf"&gt;short note&lt;/a&gt; on circular arcs, but I feel it would be a good idea to revisit much of that material and explain some of the rationale and derivations. We will begin this series with this article on arc representation.&lt;/p&gt;
&lt;p&gt;The goal is to represent an arc …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have written a &lt;a href="http://victorliu.info/pdfs/arc_spline.pdf"&gt;short note&lt;/a&gt; on circular arcs, but I feel it would be a good idea to revisit much of that material and explain some of the rationale and derivations. We will begin this series with this article on arc representation.&lt;/p&gt;
&lt;p&gt;The goal is to represent an arc: a portion of a circle.
In geometric design, an arc may be represented by a circle (center and radius), and starting and ending angles.
This is a 5 number representation and is used frequently in 2D geometry engines such as Cairo or Postscript.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="http://victorliu.info/images/figures/arc/rep_circle.svg"&gt;
&lt;figcaption&gt;Circle-based arc representation&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Though quite intuitive from a human standpoint, this representation poses a number of problems.
First, often one would like to be able to represent a straight line segment, or support continuous variation of an arc through a configuration in which it is a line segment.
A circle-based representation is unable to handle this case since the center of the circle would be at infinity with correspondingly infinite radius, and the representation becomes more ill-conditioned the lower the curvature becomes.
Second, angles do not provide a unique representation since they are equivalent modulo 360 degrees.
And finally, the orientation of the arc (in the sense of a particle travelling along it) must be defined using the ordering of the angles, which makes it clumsy to specify e.g. the smaller or larger part of a circle, given the same angular extents.&lt;/p&gt;
&lt;p&gt;Another representation uses three points: two define the endpoints, and the third is a point through which the arc passes, which for non-degenerate cases uniquely defines the arc.
This representation does not suffer any of the problems of the circle-based representation, but introduces two new problems.
First, 3 points is 6 real numbers: one more than we need.
Second, this extra real degree of freedom manifests itself in the form of degeneracies, in whch a straight line segment may be represented an infinite number of ways depending on where the 3rd point lines on the segment.
Another ambiguous case is if the 3rd point is collinear but not between the endpoints.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="http://victorliu.info/images/figures/arc/rep_deviation.svg"&gt;
&lt;figcaption&gt;Chord deviation arc representation&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The final representation is one involving the two endpoints and another parameter the determines how much the arc bulges from its chord.
There are a few possible reasonable choices for the parameter.
First, and most direct, is storing the signed distance of the midpoint of the arc from the chord.
This is a poor representation because it is not scale invariant: scaling the underlying space &lt;span class="math"&gt;\(e.g. doubling the coordinates of the points\)&lt;/span&gt; requires doubling the distance parameter to represent the same arc. While not a showstopper in any sense, we can do better by representing the "bulginess" using a ratio rather than a distance.&lt;/p&gt;
&lt;p&gt;Another choice is to take the ratio of the deviation to the chord length.
The parameter takes a value of 0 for a straight line segment, and as it approaches positive and negative infinity, the arc becomes nearly a complete circle.
Notably, semicircles have parameter &lt;span class="math"&gt;\(\pm \frac{1}{2}\)&lt;/span&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="http://victorliu.info/images/figures/arc/rep_g.svg"&gt;
&lt;figcaption&gt;Preferred arc representation&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;We can improve this ever so slightly by instead use the ratio of the deviation to the &lt;em&gt;half&lt;/em&gt; chord length.
This representation rescales the parameter space so that semicircles have parameter &lt;span class="math"&gt;\(\pm 1\)&lt;/span&gt;.
The great advantage of this rescaling is in its elegance and symmetries with respect to arc complements.
We will denote this bulge parameter by &lt;span class="math"&gt;\(g\)&lt;/span&gt;, as is done in my note.
The half-chord length is &lt;span class="math"&gt;\(t\)&lt;/span&gt;, and the height of the deviation is &lt;span class="math"&gt;\(h\)&lt;/span&gt;, so that &lt;span class="math"&gt;\(h=gt\)&lt;/span&gt;.
An arc is then represented by the tuple &lt;/p&gt;
&lt;div class="math"&gt;$$A, B, g$$&lt;/div&gt;
&lt;p&gt; where &lt;span class="math"&gt;\(A\)&lt;/span&gt; and &lt;span class="math"&gt;\(B\)&lt;/span&gt; are the endpoints of the arc.
Notice that the complementary portion of the circle on which &lt;/p&gt;
&lt;div class="math"&gt;$$A, B, g$$&lt;/div&gt;
&lt;p&gt; lies is &lt;/p&gt;
&lt;div class="math"&gt;$$A, B, -1/g$$&lt;/div&gt;
&lt;p&gt;.
This simple fact bears tremendous computational advantages that we will explore in subsequent articles.&lt;/p&gt;
&lt;p&gt;It turns out that Autocad uses this exact representation in the &lt;code&gt;LWPOLYLINE&lt;/code&gt; entity. An &lt;a href="https://www.afralisp.net/archive/lisp/Bulges1.htm"&gt;exploration in Lisp&lt;/a&gt; has been written by Stig Madsen, but we will hopefully delve wider and deeper.&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="exposition"/><category term="math geometry computational-geometry"/></entry></feed>