Archive for the ‘Lisp’ Category

Keyboard fun

Sunday, March 20th, 2011

One can have hours of fun with xmodmap. Especially if one has a Symbolics keyboard.

For a start, I get a “real” Meta key (not Alt) and a couple of extra modifier keys that emacs knows about: Hyper and Super. I mapped these to mod2 and mod3. Staying away from mod4 is a good idea because that defaults to the Windows key (on modern keyboards) and there are some Gnome shortcuts that would clash, e.g. show desktop (Windows-d). Modifier 5 is known by xmodmap as Mode_switch, normally mapped to “Alt Gr”.

I learned that a keypress can do 4 things according to the mode it’s in:

  • normal press – type the glyph
  • shift + press – type the shifted glyph
  • mode_switch + press
  • shift + mode_switch + press

The last two of these are outside of normal use, which basically means that you are free to map them to whatever. On the Symbolics keyboard I mapped mode_switch to the Symbol key. Then I had fun making the modmap to make the keys do various things like type Greek letters and mathematical symbols.

I think there’s a reasonably natural mapping between Greek and English letters thus:

  • A – alpha (α)
  • B – beta (β)
  • C – chi (χ)
  • D – delta (δ)
  • E – epsilon (ε)
  • F – phi (φ)
  • G – gamma (γ)
  • H – theta (θ)
  • I – iota (ι)
  • K – kappa (κ)
  • L – lambda (λ)
  • M – mu (μ)
  • N – eta (η)
  • O – omicron (ο)
  • P – pi (π)
  • R – rho (ρ)
  • S – sigma (σ)
  • T – tau (τ)
  • U – upsilon (υ)
  • V – nu (ν)
  • W – omega (ω)
  • X – xi (ξ)
  • Y – psi (ψ)
  • Z – zeta (ζ)

That leaves Q and J free with no obvious Greek letter equivalents. For the number keys, I added some mathematical symbols, and for the punctuation keys I added further punctuation (e.g. left and right guillemots) and things like copyright and trademark symbols.

But that’s not all… I have plans to alter the keyboard firmware (it’s just programmed using C and Teensy – I’ve already made some mods) to use the “Mode Lock” key more extensively. So Mode Lock basically is a hardware shift key, and when it’s on, I can make the entire keyboard send different key codes. Since there are a total of 255 possible keycodes recognisable by xmodmap, I should have room to fit in another complete set (again, 4 per key) and be able to type all sorts of weird and wonderful glyphs.

The only issue I have at the moment is around the keycodes that are in the “numpad zone” on a regular keyboard. The mode_switch doesn’t seem to work with them yet. I still have to figure that out.

Cult of the Keyboard

Friday, October 15th, 2010

We’ve got a bit of a keyboard cult going on at work. Of course, I’ve been a fan of decent keyboards for years and a strong believer that keyboards (and mice) generally get too little thought when buying a computer. Ergonomics are important: everyone recognises the value of a decent chair and a decent monitor (or two). If your job involves typing, it behooves you to get a decent keyboard too.

At home I use a black Unicomp model similar to this but with a UK keymap and no Windows keys. At work I use an old IBM Model M (also a UK keymap) that must be 20 years old if it’s a day, and still going strong. I wouldn’t trade it for anything.

Recently a couple of my colleagues have been exploring their keyboard options. One got hold of a black Filco model with blank keys. Another recently bought an Alps keyboard for use with his Mac.

Today (after a long wait) I finally received this:

Symbolics keyboard

Back before I went to the UK in September, I contacted Peter Paine and made a deal with him for this Symbolics keyboard. Unfortunately there was a mixup in delivery timing so I didn’t get it while I was in the UK and my Dad had to send it on to me. But today it finally arrived. As you can see, it has some interesting keys and I’m going to have some fun hooking it up (need to do some hardware hacking with Teensy) and trying it out.

Functional Rainbow

Monday, December 29th, 2008

Functional Rainbow

Vecto get!

Tuesday, April 8th, 2008

Xach has released version 1.2.1 of Vecto, featuring circle arc paths, and I’m sure a whole lot more on the drawing board.

(asdf-install:install :vecto)

Curve and Vector

Sunday, March 30th, 2008

Curve (com.elbeno.curve) is my common lisp package for doing cool things with two-dimensional curves. In particular, modulating cubic Bézier curves and splines, but also approximating arbitrary elliptical and circular arc segments with cubic Bézier curves.

It depends on Vector (com.elbeno.vector), a cobbled together set of functionality for representing and manipulating points on the 2D Cartesian plane. It also depends on Zach Beane’s excellent Vecto, for ease of drawing. Both Curve and Vector are available under the GPLv3 license.

Download Curve
Download Vector

Currently both Curve and Vector are at v0.1.

Approximating elliptical arcs with Bézier curves

Saturday, March 29th, 2008

In doing my modulation work with curves and ellipses, I extended the vecto function for drawing an ellipse to enable an oriented ellipse. Lately it occurred to me that this didn’t go far enough in terms of functionality, and I began wondering about how to draw part of an elliptical arc.

Vecto’s ellipse drawing function works by drawing the ellipse in quarters, with four cubic Bézier curves. Each curve’s control points are calculated according to the radii and kappa, the constant that is 4(√2 – 1)/3, as explained by G. Adam Stanislav. This works fine if you are drawing quarters, halves, or complete ellipses (or circles of course), but what I wanted was a function like this:

(defun approximate-elliptical-arc (cx cy a b theta eta1 eta2)
…)

With (cx, cy) being the centre, a and b being the radii, theta being the orientation, and eta1 and eta2 being the start and end angles specifying the arc. The return value would be a Bézier curve, or a list of curves, depending on the required accuracy.

So I did some research and found an interesting paper by Luc Maisonobe on approximating such elliptical arcs with lines, quadratic and cubic Bézier curves. The maths is straightforward, if rather heavy on the constants, and it was less than an hour’s work to code up the function. I now have functionality to draw arbitrary elliptical (or circular) arc segments.

The interesting thing is that this method of approximating ellipses is not the same as G. Adam Stanislav’s method: to put it another way, when I compute a quarter-circle arc with a single Bézier curve, the control points are not quite coincident with the kappa-method control points. The error in the circle approximation is still undetectable to the eye, but careful comparison of two large circles shows that the kappa-method one is slightly larger: the curves are slightly more “pushed out”.

G. Adam writes: “It is my contention that we get the closest to a real circle if we draw the one curve with properties already discussed, and with the center point of the curve lying at the same point the center point of the circumference of a true quadrant of a circle would lie.” I would be interested to know if he has a proof behind this contention, and/or an expression for the error in such a curve. The derivation of kappa is based around this idea that the midpoint of the curve should be coincident with the midpoint of the arc.

G. Adam’s method seems accurate. But the Maisonobe method can be used to subdivide the arc, obtaining successively closer approximations to the true arc by using multiple Bézier curves, and includes a method for calculating an upper bound on the error. This, together with the fact that it easily handles start and end angle specification of the arc, leads me to favour it.

Functional Fills with Vecto

Tuesday, March 25th, 2008

I’ve been wanting to do exclusive-or functional fill in vecto for a while, so tonight I delved in. I added a pixel function to the graphics state and kept the default as the normal alpha-blending it was already doing. The pixel function signature is a bit clumsy, but it was easy to knock up a couple of functional fill demos. Programmer art alert!

XOR pixel function

This is a cyan background, and a circle drawn with an XOR function, white fill, and green stroke. From this you can see that the fill happened before the stroke, since the stroke is half-and-half.

OR pixel function

And this demonstrates an inclusive-OR fill: the standard additive colour chart.

Even more on ellipses and splines

Saturday, March 15th, 2008

Honestly, they’re incredibly interesting. Anyway, I’ll skip straight to the pièce de résistance:

Ellipse Modulation VI

This is a 4-curve cubic Bézier spline modulated onto an ellipse. The ellipse [a=4, b=3] is at an angle of π/4. C1 continuity of the complete curve is preserved. The flickr set tells the story of how I got here.

This is around 450 lines of my naive lisp, including class definitions and test code. So Gary, this is your g-code challenge!

The lisp code is object oriented (oh, and so much nicer than C++’s so-called object orientation). I rewrote the earlier code now that I knew what I was doing, and I added lines and polylines to the mix too (see the flickr set) so I can easily modulate whatever edge I want. You’ll notice if you look closely at the earlier attempts that they had a bit of a problem with c1 continuity, which is now fixed with the new code.

In closing, thanks, Zach!

Ellipses & Splines again

Monday, March 10th, 2008

After some code cleanup and generalisation, I can now modulate whole splines onto ellipses and onto splines themselves. Here is my simple 4-bezier spline modulated onto an ellipse:
spline_on_ellipse
And onto itself:
spline_on_spline
Repeatedly modulating a spline onto itself while varying the frequency parameter leads to some interesting and fractal patterns. Nice.

Splines and modulation

Sunday, March 2nd, 2008

My efforts to equally subdivide a curve along its length have, in part, been leading to this. First, I extended the sampling to work with splines (made up of cubic Bézier curves with c1 continuity). This shot shows 4 curves put together to form a spline:
spline
Next, I wrote some code to modulate a curve onto another curve. Here’s a curve, and the same curve with another curve modulated onto it.

plain modulated