Tuesday, June 30, 2009

stream-calculus

Copperbox revision 657.

I've been playing with the Hinze-Streams library, which got me interested in the stream calculus of Jan Rutten. Hinze-Streams have a different multiplication to Rutten's stream calculus, so I though I'd have a go at writing the stream calculus in Haskell.

I'm not sure whether this will develop into a proper implementation. The definitions in Rutten's work are so compact that there's ample room for errors in translation; I imagine a test suite will be more work than the operators themselves.

Monday, June 29, 2009

Wumpus

Copperbox revision 656.

Some more work on beziers - another formula for circle segments / wedges.

Sunday, June 28, 2009

Wumpus

Copperbox revision 655.

Some work on plotting curves. I can draw a sine curve with bezier curves - currently I can draw curves for functions paired with their derivative, but I haven't worked out how to add numerical approximation. The presentations I've read move too quickly at the point when they add numerical integration, so I haven't yet been able to extract the steps into an algorithm.

Saturday, June 27, 2009

Wumpus

Copperbox revision 654.

I've added an algorithm to draw circle segments, the algorithm appears due to Gernot Hoffmann and is presented here (section 3.7.1):

http://www.fho-emden.de/~hoffmann/bezier18122002.pdf

Wumpus

Copperbox revision 653.

I've added more Pointwise instances and removed a couple of hacks where I was using fmap (+d) explicitly on points rather than using a translation.

Friday, June 26, 2009

Wumpus

Copperbox revision 652.

I've extracted Pointwise into its own module and put the MatrixMult type class into the Matrix module (previously it was in Instances). Now instances can do its proper job - hold the necessary orphan instances for multi-parameter type classes.

Wumpus

Copperbox revision 651.

Far out! - I've lifted Pointwise to work on functions and (I surprise myself...) it works. This means I can transform Point -> Something functions. This is old news of course, going back pretty much a decade at least to Jerzy Karczmarczuk's Clastic where he overloaded the numeric classes for functions, but having this in Wumpus is exciting new stuff for me.

The function to make calendar grids is now is half the size, I'll have to look a being more systematic with Pointwise in Wumpus.

Wumpus

Copperbox revision 650.

Some more work on grids, particularly making a calendar grid.

Wumpus

Copperbox revision 648.

Some more work on module signatures and Haddock topics.

Wumpus

Copperbox revision 648.

More work on labels and drawing in the coordinate-free style.

Thursday, June 25, 2009

Wumpus

Copperbox revision 647.

Grid drawing in a more coordinate-free style. Also some experiments towards a more "functions from Point to something style".

Wumpus

Copperbox revision 646.

Initial work to add text labels.

Labels are going to be problematic as I can't see how to establish their size or bounding box. PostScript has the stringwidth command but I don't want to have PostScript variables within Wumpus, that's do say I don't want a reflection mechanism between Wumpus and PostScript. I think I will augment labels with a clipping path to draw the text inside at some point. Then Wumpus can access the geometry of the clipping path, though drawings will need visually checking after they have been created to ensure all the label text is within clipping path.

Wumpus

Copperbox revision 645.

The LineSegment datatype wasn't very good, it was parametric on the numeric type, but it fixed the point type to Point2 - so it would only allow lines in 2D. At the expense of making the type signature more complicated I've made it more general - it's now parametric on point type as well (it's more complicated because the point type has to be a type constructor).

Wednesday, June 24, 2009

Wumpus

Copperbox revision 644.

I've added a function inFrame* to the Frame module that translates coordinate frames. It works correctly according to the examples I derived it from (the implementation is simple providing you have a matrix inverse function), but I'm still rather mystified by Frames and what operations they should support.


* As soon as I'd committed the revision I realized inFrame is a bad name as it sounds like a predicate.

Wumpus

Copperbox revision 643.

I've added inversion functions for 2x2 and 3x3 matrices. Now I can get back to frames...

Wumpus

Copperbox revision 642.

More work on matrices - added access by index and building elementary matrices. My matrix types aren't very compelling so it's lucky that I probably can manage with just 2x2 and 3x3 square matrices.

Tuesday, June 23, 2009

Wumpus

Copperbox revision 641.

I've added module signature to a few of the Wumpus.Core modules, this is so I can track what is defined in them more easily in Haddock. Also, I've extended the Matrix module a bit as I'm working towards a matrix inversion operation.

Wumpus

Copperbox revision 640.

I've added a 3D point type. While I don't really intend moving into three dimensions (two barely work), having two different point types should stop me making the types of functions that act on points too specific.

I've also done a little bit more on frames as I'm starting to work out a valid set of operations on them.

Monday, June 22, 2009

Wumpus

Copperbox revision 639.

I've added cabal files to Wumpus so I can make Haddock docs easily. Also a bit of work on a frame transforming function.

Sunday, June 21, 2009

Wumpus

Copperbox revision 638.

I've added a placeholder module for grids.

Grids are easy to draw, but I'm going to have to put some thought into how they're used. Obviously grids are related to coordinate systems and frames, but the frame system I added to Wumpus.Core is one of the things stuck on.

Wumpus

Copperbox revision 637.

I've corrected all the current compiler warnings.

Saturday, June 20, 2009

I `heart` TypeFamilies! (Wumpus)

Copperbox revision 636.

(New typeclass for Wumpus Pointwise, with an associated type).

With HNotate and then Mullein, I had a long standing problem where my data types where parametric on 'note' (usually this would really be 'pitch', sometimes drum pitch - notes themselves are actually one level up in the hierarchy). In Haskell the nice traversal type classes (Functor, Foldable, Traversable) work on the parametric tip, implementations of these type classes are just scaffolding to focus the traversal on the tip.

Unfortunately in HNotate I mostly wanted to traverse the layer above, where the syntax tree represents notes, chords, rests etc. But it wasn't useful to make this the parametric tip - I'd have to implement notes, chords and rests for all note types when they are common (I don't suppose drummers call simultaneous drum notes chords but LilyPond groups them as chords).

I had a similar problem with Wumpus - drawables (polygons, polylines etc.) are commonly built from collections of points which can be operated on with affine transformations. But Point is parametric on its number type (so they can be represented by doubles, rationals etc), this meant Wumpus had the same problem as HNotate / Mullein - the parametric tip wasn't the focus I commonly wanted to operate on.

Wumpus has simpler needs than Mullein (no Traversable, or Foldable), and I think I've solved the problem with a type class and associated type. Drawables can implement the Pointwise class which is similar to Functor except the associated type specifies the tip to operate on and needn't be the functorial parameter. Type families have won a new convert.

Wumpus

Copperbox revision 635.

Replaced the monadic command-style arrow head drawing code.

Wumpus

Copperbox revision 634.

I've now got a passable arrowhead coded in coordinate-free style. I've had no insights into how to add frames to the affine transformations, to get a workable rotation function I defined a rotateAbout function that is just the common TRT^-1 transformation and takes the rotation origin as a parameter.

Getting the arrowhead to work has reinforced a particular clumsiness in Wumpus where I can't translate all the points in a figure (polygon, etc.). Using fmap doesn't work because polygons are parametric on the numeric inside (Point a) rather than the point itself. Looks like I need a Pointwise typeclass.

Friday, June 19, 2009

Wumpus

Copperbox revision 633.

Start of a module for coordinate frames.

Working on arrowheads, I realized that I was doing all rotations within world coordinates. Clearly this was wrong and the obvious solution is to add frames (with origin and ortho vectors). I've done this but I'm stuck on how to integrate them. With homogeneous coordinates there is an immediate relation between t1 t2 and the frame within the transformation matrix:

1 0 t1
1 -1 t2
0 0 1

But I'm not sure what the relation actually is and I don't know what operations a frame should support. The presentations I've seen quickly move from frames to homogeneous coordinates and I'm failing to deduce the connection.

Wednesday, June 17, 2009

Wumpus

Copperbox revision 632.

As the writer monad PostScript is no longer really the essence of Wumpus (i.e. Wumpus is now more about geometry and generating PostScript is relegated to a display technique) I've renamed the Wumpus module to PostScript in Wumpus.Core. I've also prefixed all the PostScript commands with ps_ to emphasis their imperative nature - they do actions to change the graphics context (state) rather than manipulate geometric objects.

Tuesday, June 16, 2009

Wumpus

Copperbox revision 631.

Improvements to the implementation of Shemanarev's polygon smoothing algorithm. Visually the results look good, but in the example the leftmost point seems to have a problem with one of the control points seemingly missing or far too close to the endpoint.

Wumpus

Copperbox revision 630.

Some work on Maxim Shemanarev's polygon smoothing algorithm. I'm losing some control points which means that the smoothed polygon is not closed, so there's clearly a problem with how I traverse/interpolate the points in the initial polygon.

Wumpus

Copperbox revision 629.

A minor tidying up.

I've added a new implementation of the midpoint function that just uses types and operations from the VectorSpace library (it doesn't depend on Wumpus's Point2 type). I've changed the de Casteljau algorithm to use it.

Monday, June 15, 2009

Wumpus

Copperbox revision 628.

Added a prototype implementation of de Casteljau's curve subdivision algorithm.

It's implemented with just affine space operations and points and vectors. While this isn't news to someone well versed in geometry it was revealing to me that I didn't need extra objects (line segments) or new operations. I had a lot of trouble studying presentations of de Casteljau's algorithm as I thought the presentations were doing point addition which is of course a geometric no-no, it turns out they weren't of course.

Friday, June 12, 2009

Wumpus

Copperbox revision 627.

Initial work on curve drawing. The mathematics of curves quickly gets the better of me, so I predict slow progress in this department, but here's the start. I've implemented a direct translation of the hyperbola drawing routines from Bill Casselman's 'Mathematical Illustrations'. While currently the code is rather ungainly due to some unfortunate direct recursion, at least the drawing looks correct.

Thursday, June 11, 2009

Wumpus

Copperbox revision 626.

I've removed the drawing context code from Basic.hs. This was supposed to allow access to drawing properties (line colour, fill or stroke etc.), but it didn't work very well. At the moment it seems better to have no mechanism access to drawing context than an inadequate one.

Wumpus

Copperbox revision 625.

More basic shapes for dots (diamond, cross, pentagon). The construction of these dots is also more geometric than it was for previous basic shapes - that's to say they are built from translations, rotations, etc. rather than calculating the location of points.

Wednesday, June 10, 2009

Wumpus

Copperbox revision 624.

I've added a transformations module that wraps up the affine / matrix transformations.

This makes Wumpus feel somewhat more functional, for instance this function draws an asterisk dot:

asterisk (P2 x y) = zipWith fn (replicate 5 ls1) [0..4]
where
ls1 = vline origin 2
fn ln theta = translate x y $ rotate ((2*theta*pi)/5) ln


Of course, there is still some golfing to be done.

Wumpus

Copperbox revision 623.

I've added a datatype for line segments.

Wumpus

Copperbox revision 622.

Some refactoring of the basic graphic objects (polygons, circles) before I have another go redefining them.

Scan Golf!

I don't often use the list functionals scanl and scanr but here are two nice uses that I found yesterday:

List function tails with scanr:

scanrTails = scanr (:) []


Unfortunately inits is harder as it needs to snoc the list, it has a slow definition with (++):

scanlInits = scanl snoc [] where
snoc xs x = xs++[x]


Or a more efficient one with Hughes lists (see diff list on Hackage):

type H a = [a] -> [a]

out :: H a -> [a]
out f = f []

snoc :: H a -> a -> H a
snoc f a = f . (a:)

scanlInits' :: [a] -> [[a]]
scanlInits' = map out . scanl snoc id


I had defined tails as a paramorphism which lead me to see it as a scan:

paraTails = para phi [[]] where
phi e (fwd,acc) = (e:fwd):acc


Para's definition is:


-- paramorphism (generalizes cata)
para :: (a -> ([a], b) -> b) -> b -> [a] -> b
para phi b = step
where step [] = b
step (e:es) = phi e (es, step es)

Wumpus

Copperbox revision 621.

More changes to the Colour module - RGB and HSB colours now have distinct types.

Monday, June 8, 2009

Wumpus

Copperbox revision 620.

I've made Colour3 a proper type rather than a type synonym. Otherwise, I'm rather stuck with Wumpus. I'm struggling to work out a convenient set of datatypes (for lines, polygons, curves, etc...) that feel functional to work with. That's why there have been so few commits recently.

Monday, June 1, 2009

Clastic


I've got Jerzy Karczmarczuk's Clastic working with the latest Clean. Here are the diffs, which are unfortunately horribly confusing as most of the changes were single character edits to change uniqueness attributes. I'm not sure that all the changes are correct, particularly the ones for CTWindow, but Example0 compiles and runs.

http://copperbox.googlecode.com/svn-history/r619/trunk/dist/clastic22.diff

Blog Archive

About Me

My photo
Disambiguating biog as there are a few Stephen Tetley's in the world. I'm neither a cage fighter or yachtsman. I studied Fine Art in the nineties (foundation Bradford 1992, degree Cheltenham 1992 - 95) then Computing part-time at Leeds Met graduating in 2003. I'm the Stephen Tetley on Haskell Cafe and Stackoverflow.