Time for the Gallery

By
Dave
Project
Published
30 Dec 2010 23:10
Last Modified
13 Jan 2013 18:18

While reminiscing about watching Take Hart, I decided that I needed a gallery. This would serve as an area to store images such as screenshots of the projects I am working on.

I opted for the following URL structure:

  1. http://{domain}/blog/gallery for all galleries
  2. http://{domain}/blog/gallery/{name} for all images in a given gallery
  3. http://{domain}/blog/gallery/{name}/{index} for a particular image in a given gallery

I added a new gallery controller to the blog engine, and added an index view for the galleries, as shown below in Figure 1. Each gallery has a thumbnail image, a title and a description. Image counts are shown for each gallery.

Galleries

Figure 1. Example galleries.

The gallery index view links to an index action of an image controller, and the view for a particular gallery is shown below in Figure 2. Each image is shown as a thumbnail (created manually), along with a title. I opted for a square thumbnail to avoid issues with different aspect ratios, and paging is enabled.

Galleries

Figure 2. An example gallery.

The image index view links to the detail action, and the view for a particular image is shown below in Figure 3. The image is shown along with a description. 'Previous' and 'Next' links are included.

Gallery Image

Figure 3. An example image in a gallery.

In order to add images, I transfer them to them to the web server (e.g. using ftp), then "add" images to a particualr gallery by specifying the location of the thumbnail and image itself, along with the title and description in an edit view. This metadata is stored using a similar repository to the posts (currently XML) though this could be easily changed.

A Matter of Controls Part 3

By
Dave
Project
Published
20 Dec 2010 00:29
Last Modified
13 Jan 2013 17:37

In Part 1 and Part 2 I showed some screenshots of a radial dial for controlling settings. I've made the following changes:

  1. Enabled the control for multi-touch. All buttons now support multi-touch input (per item and per category), and the dial can be "rotated" using multiple contacts.
  2. Changed the dial to rotate the scale and keep the pointer fixed, rather than vice-versa to provide better feedback with multi-touch rotation.
  3. Added inerita for rotation.
  4. Moved the category title back to the centre.
  5. Changed the button action to execute on click (manipulator-up) rather than on a manipulator-down event, with highlighting to provide better visual feedback when touching a button.
  6. Added support for enumrations, in addition to boolean and numeric buttons.
Float dial

Figure 1. Radial control for numeric settings

Bool dial

Figure 2. Radial control for boolean settings

Using a single hue for each of the regular, disabled, and highlighted button states gives the impression of a "heads-up-display" (HUD) rather than a mechanical dial. "LED"-style colors and a Gaussian blur add to the effect, as shown below in Figure 3.

LED HUD

Figure 3. LED coloring for HUD

Vector Fonts

By
Dave
Project
Published
16 Nov 2010 09:23
Last Modified
13 Jan 2013 18:22

I previously mentioned using vector-based fonts, e.g. for deep sky object and star labels. These labels used line-primitives, as shown in Figures 1 and 2.

Roman Font

Figure 1. Line-primitive Roman vector font

Greek Font

Figure 2. Line-primitive Greek vector font

I also wanted to use vector-based fonts with "thick" lines, so needed to expand each line by a given thickness. The steps I used for a basic approach to achieving this are illustrated in Figure 3, using a '>' symbol as an example.

Expanding Line Primitives

Figure 3. Expanding line-primitives to triangle-primitives

The first step is to expand each line-primitive into a pair of triangles of a given thickness. Next, each line is given a semi-circular "cap", with the number of slices defined by a "smoothing" parameter. Rather than using a cap for both the start and end of each line, only a single cap is used at the join between lines. Finally, the number slices drawn for a given cap can be limited by the angle between each line-join, further reducing the vertex and index counts.

Text can now be scaled smoothly, as shown in Figure 4, without the artefacts produced by scaling SpriteBatch raster fonts. One limitation of this approach however, is that text cannot be drawn with transparency since triangles in each character generally overlap.

Vector font scaling

Figure 4. Smooth scaling of vector fonts

Thick Roman Font

Figure 5. Triangle-primitive Roman vector font

Inertia Processing

By
Dave
Project
Published
23 Oct 2010 23:40
Last Modified
13 Jan 2013 17:38

I previously described an approach to implementing inertia processing by averaging positions to extract velocity from manipulation. However, this approach could result in discontinuous velocities when transitioning from manipulation to inertia.

While implementing multitouch manipulation processing for this project, I "smoothed-out" manipulations using a basic dampened-spring algorithm. Rather than extracting velocity from position, this approach conversely relies on calculating velocities to extrapolate positions. This neatly solves the problem of discontinuous velocities since I always know the correct velocity at the point at which manipulation ends, and is also a much simpler approach.

Using "stiff" springs ensures gestures such as flicks lead to rapidly increasing velocity.

IE9 Customisation

By
Dave
Project
Published
13 Oct 2010 23:06
Last Modified
13 Jan 2013 18:18

Internet Explorer 9 Beta enables some specific integration features for Windows 7, such as "site pinning" to the Taskbar, Start Menu, and desktop (effectively Site Specific Browsers), customising the navigation button colours, and providing Jump Lists. I'll discuss how I've supported each of these features for my Blog Engine.

Icons

A site can be "pinned" to the Windows 7 Taskbar, Start Menu, and Desktop, for example by dragging the IE9 tab or the address bar icon to the relevant target. The icons used for pinning are defined in the favicon.ico file in the root of the web site. This file contains a number of images at different resolutions which are used for the address bar, tab, browser "Home" button, Taskbar, Start Menu, and pinning the site by dragging the address bar icon.

The icon file is specified in the site.master View using the following tags:

<link rel="shortcut icon" type="image/x-icon" href="/blog/favicon.ico" />
<link rel="icon" type="image/ico" href="/blog/favicon.ico" />
IE9 Beta Taskbar Site Pinning

Figure 1. IE9 Beta Taskbar Site Pinning

Navigation Buttons

I set the colour of the back and forward navigation buttons (see Figure 2) to match the color of my current site header with the following tag:

<meta name="msapplication-navbutton-color" content="#303030" />
IE9 Beta Header

Figure 2. IE9 Beta header

Jump Lists

I was already passing a ViewModel containing the categories and item counts to the master page, so adding links to each category in a Jump List (see Figure 3) using the following tag structure was trivial.

<meta name="msapplication-task" content="name=Category name (item count);action-uri=/blog/archive/category/Random-Stuff;icon-uri=/blog/favicon.ico" />
IE9 Beta Jump List

Figure 3. IE9 Beta Jump List

Pinning the site to the Start Menu also gives access to the Jump List, as shown below in Figure 4.

IE9 Beta Star Menu Site Pinning with Jump List

Figure 4. IE9 Beta Start Menu Site Pinning with Jump List

Automatic Magnitude

By
Dave
Project
Published
11 Oct 2010 17:18
Last Modified
31 Dec 2010 08:19

In addition to indexing stars and deep sky objects by position, as described in Spatial Indexing Part 1 and Part 2, I added an additional index for magnitude to allow objects to be rendered by brightness.

I wanted to provide a way of automatically adjusting the faintest object visible as the field-of-view is changed, so that a sensible number of objects are drawn, particularly for rendering an appropriate number of labels. In order to consider which algorithm to use, I thought it would be useful to analyse the datasets for stars and deep-sky objects. Figure 1 shows the distribution of magnitude values in the Hipparcos catalog, the majority of which (87%) are in the range from 6-10.

Hipparcos Magnitude Distribution

Figure 1. Hipparcos magnitude histogram

In order to automatically select the magnitude for a given field-of-view, I chose first to calculate its fraction of the maximum field-of-view (1), then square this to give the fraction of area of the maximum field-of-view (2).

fov_fraction = current_fov(1)
                 max_fov
area_fraction = fov_fraction2(2)

I assume that the change in brightness is directly proportional to the change in area (3).

brightness_fraction = area_fraction(3)

Apparent magnitude is a logarithmic scale, with magnitude 6 stars defined as being one hundred times brighter than magnitude 1 stars. Hence each order of magnitude is 5√100 (approximately 2.512, known as Pogson's Ratio) times brighter (4). I then convert this difference in brightness to a difference in magnitude (5).

brightness_fraction = 2.512magnitude_delta(4)
magnitude_delta = log(brightness_fraction)(5)
                        log(2.512)

Finally I subtract the magnitude difference from the magntiude used at the maximum field-of-view (6). The maximum magnitude for labels can be set slightly below this figure (e.g. by some order of magnitude) so that items appear before their labels.

max_magnitude = 5.0 - magnitude_delta(6)

The maximum magnitude calculated in this manner is shown in Figure 2. Note that the graph tends to the magnitude at maximum field-of-view (magntide 5.00 at 100° in this case). For example, at a field-of-view of 10°, the area fraction of the maximum field of view is 0.01, hence the magnitude difference is -5.00, giving a calculated value of 5.00 + 5.00 = 10.00.

Automatic Magnitude

Figure 2. Automatic magnitude by field-of-view

Spatial Indexing Part 2

By
Dave
Project
Published
11 Oct 2010 17:15
Last Modified
13 Jan 2013 17:42

In part 1 I discussed a basic approach to indexing stars and their corresponding labels. I extended this approach further to include deep-sky objects from the NGC catalog. I'll also add the IC catalog, and cross-references to other designations such as Messier number.

In order to cater for orientations of galaxies, I used a textured, indexed quad instead of a point sprite. This enabled me to scale and rotate the texture appropriately. You can see this in Figure 2 with NGC 224 (The Andromeda Galaxy, M31). For the time-being I will use a simple sprite to represent the size, shape and orientation, and will extend this to images in the future.

Spatial Grid

Spatial Grid

Figures 1-2. Spatial indexing of stars and deep-sky objects

Strictly speaking, since the deep-sky objects are not point-sources, I should be using an alternative spatial indexing approach, since it is possible for an object to span cells in my simple grid. However, the maximum object size is relatively small in comparison with the grid size so this shouldn't be a practical issue.

Content Processing

By
Dave
Project
Published
6 Oct 2010 14:37
Last Modified
13 Jan 2013 17:43

I previously described the use of XNA's automatic content deserialization for loading my background stars from the Hipparcos catalog. This catalog contains approximately 120,000 entries, and this step was taking a significant proportion of my start-up time (over 3,000ms on a typical machine).

Shawn Hargreaves recently posted an article on efficiently loading large arrays or lists, which described the use of custom ContentTypeWriter and ContentTypeReader classes to avoid the performance hit caused by reflection.

I implemented these simple classes for my BackgroundStar type, and reduced the load time of this piece of content to approximately 100ms, an improvement of over 95%, which was nice :)

Spatial Indexing

By
Dave
Project
Published
4 Oct 2010 00:11
Last Modified
13 Jan 2013 17:43

As the number of potentially visible items increases, it becomes less feasible to simply draw all items, and more important to select which items are actually drawn.

In order to avoid checking every object to determine if it should be drawn, an O(n) operation, it is necessary to assign each object with some type of spatial index. In this way, it is possible to determine only which indexes should be drawn and therefore eliminate large "buckets" of objects at once.

Many approaches for spatial indexing exist, and I initially set up a simple project to give me a test framework for different methods. The first approach was to use a simple regular grid based on right-asension and declination. I used an established algorithm1 for determining which grid cells are visible in a given field-of-view, and used labels for star names as the objects to index (Bayer and Common names are used, with Hipparcos designations added for other bright stars).

Some initial screenshots are shown below in Figures 1-3. The centered circle indicates the reduced field-of-view which is used to calculate which cells to draw (since using the entire viewport would not demonstrate that surrounding objects are culled). The green area indicates the grid cells which are calculated as overlapping the reduced field-of-view, and only labels within this area are drawn.

Spatial Grid

Spatial Grid

Spatial Grid

Figures 1-3. Spatial indexing using a right-ascension/declination grid

One of the drawbacks of using a regular grid based on right-ascension and declination (or any projection involving a singularity at the poles) is that the number of grid cells increases dramatcally around the poles. Other spatial indexing approaches such as a Hierarchical Triangular Mesh2 give more consistent areas per cell, and will be explored at a later date now that I have a test framework in place.

1 "The Zones Algorithm for Finding Points-Near-a-Point or Cross-Matching Spatial Datasets", Jim Gray, MarĂ­a A. Nieto-Santisteban, Alexander S. Szalay, April 2006
2 "Indexing the Sphere with the Hierarchical Triangular Mesh", Alexander S. Szalay, Jim Gray, George Fekete, Peter Z. Kunszt, Peter Kukol, and Ani Thakar, August 2005

Multitouch Game Loop Inertia Processing

By
Dave
Project
Published
21 Sep 2010 18:11
Last Modified
8 Dec 2012 16:21

In Part 1 I described a lightweight class to process general multitouch manipulations using a game-loop model in XNA.

A key aspect in bringing realism to a multitouch experience is the use of momentum and inertia. The Microsoft.Surface.Core.Manipulations.Affine2DInertiaProcessor provides this support in an event-driven model. In order to continue the approach of using a game-loop model, I needed to add linear and angular velocities, and expansion rates to my manipulation processor.

Changes in manipulator position occur relatively rarely in relation to the game loop frequency, hence calculating rates of change requires averaging these changes over time. The choice of duration and quantity of these time periods is somewhat subjective, and I settled on 5 samples averaged over a maximum of 200ms. Clearly this leads to a small latency between measured and actual velocities, however the smoothing effect is beneficial.

In order to visualise these rates, both for debbugging and to settle on suitable sampling settings, I added visual indicators of direction and magnitude, as shown below in Figure 1.

Multitouch manipulation

Figure 1. Visualising linear and angular velocities and expansion rates during multitouch manipulation.

With the addition of linear and angular velocities and expansion rates, I could now add a simple inertial processing component which uses these properties as input parameters. This inertial processor uses a simple deceleration algorithm, with configurable rates for translation, rotation, and expansion. The solution is demonstrated in the following video.

Video 1. Multitouch game loop inertia processing.

Note that for gestures such as a flick, where velcity increases rapidly, a time-weighted average may be more suitable for calculating the inertia processor's input parameters, and I'll investigate this at a later date.

Page