Note: The tutorials next week will meet in the PORTAL (Second floor, same end of the building as BMS). We will have a demo of the facilities there, including the 3D printing and scanning area.
Assignments. The continuation of Assignment 4 is described in the previous post. It’s due this Friday Dec. 6. Assignment 5 — creation of a Christmas calendar image — is also described there. It’s due on Dec. 13. December 9: See this update.
03.12.13: Mr. Gunn continued the guided tour of the planar symmetry groups by considering symmetry groups of the plane with 2 independent translations: the wallpaper groups. In contrast to the frieze groups, they can have rotational symmetries of order greater than 2.
Wallpaper group application. You can run a jReality wallpaper group application from your eclipse project by navigating in the Package Explorer to “Referenced Libraries->discretegroupCGG.jar->discreteGroup.wallpaper.WallpaperPluggedIn.class” and then using right-mouse click to choose “Run as … Java application”. (Here is a Java webstart of the same application. But be careful — if you run it under Java 7, which is sometimes difficult to avoid with webstarts, make sure the left hand panel is hidden or it runs v e r y slowly.) This application allows you to experiment with all 17 wallpaper groups — see the “Wallpaper” menu and the left inspection panel. Here’s a picture generated the group 244 with the automatic painting option (choose “Wallpaper->run” option):
Wallpaper group resource: The following chart contains a list of all 17 wallpaper groups including the standard fundamental domains and the generators used in the discretegroup WallpaperGroup class.
More group theory. To obtain a good answer for Assignment 4 it’s useful to understand a bit more about the internal structure of the frieze groups. It turns out the the translation subgroup plans an important role. To understand this, we need to introduce some notation.
Definition: A subgroup
Theorem: The translation subgroup
Proof: A general isometry
Cosets. A subgroup
The quotient group. The cosets of a normal subgroup have an induced group structure. Indeed, let
We write
Connection to Assignment 4. At the conclusion of thursday’s lecture, Mr. Gunn showed how these ideas could be applied to Assignment 4 to generate the desired list of elements of the freize groups. Here’s what the resulting code for updateCopies() looks like:
Matrix[] cosets = null;
Matrix generatingTranslation = null;
int numCosets = 0;
switch(whichGroup) {
case 0:
numCosets = 1;
cosets = new Matrix[1];
cosets[0] = new Matrix();
generatingTranslation = MatrixBuilder.euclidean().translate(1, 0, 0).getMatrix();
break;
case 1:
numCosets = 2;
cosets = new Matrix[numCosets];
cosets[0] = new Matrix(); // identity
cosets[1] = MatrixBuilder.euclidean().reflect(new double[]{1,0,0,0}).getMatrix();
generatingTranslation = MatrixBuilder.euclidean().translate(2, 0, 0).getMatrix();
break;
// implement this group (* infinity infinity ) here as above in case 0
// there are two vertical mirrors a distance 1 apart.
case 3:
generatingTranslation = MatrixBuilder.euclidean().reflect(new double[]{0,1,0,0}).translate(1,0,0).getMatrix();
numCosets = 1;
cosets = new Matrix[1];
cosets[0] = new Matrix();
break;
case 6:
// implement this group (* 2 2 infinity) here as above in case 0
// there are two vertical mirrors a distance 1 apart and a horizontal mirror in the line y = 0.
generatingTranslation = MatrixBuilder.euclidean().translate(2,0,0).getMatrix();
numCosets = 4;
cosets = new Matrix[4];
cosets[0] = new Matrix();
cosets[1] = MatrixBuilder.euclidean().reflect(new double[]{1,0,0,0}).getMatrix();
cosets[2] = MatrixBuilder.euclidean().reflect(new double[]{0,1,0,0}).getMatrix();
cosets[3] = MatrixBuilder.euclidean().rotateZ(Math.PI).getMatrix();
break;
.... // other cases not included here
}
int outerLoopCount = count/numCosets, counter = 0;
// run through the powers of the generating translation ...
for (int j = 0; j <= outerLoopCount; ++j) {
Matrix powerOfTranslation = Matrix.power(generatingTranslation, (j - outerLoopCount/2));
// and multiply it on the right by each of the coset representatives
for (int k = 0; k<numCosets; ++k) { // skip over non-existing scene graph components at end if (counter >= count) continue;
SceneGraphComponent child = translationListSGC.getChildComponent(counter++);
Matrix tmp = new Matrix(cosets[k].getArray().clone());
tmp.multiplyOnLeft(powerOfTranslation);
tmp.assignTo(child);
}
}
}
Pingback: Course Log | Mathematical Visualization