FilteredTransformsTest.cm
Copyright (C) 1984 by Xerox Corporation. All rights reserved.
Last Edited by: Hiller, September 7, 1984 0:18:35 am PDT
Last Edited by: Wyatt, September 7, 1984 4:42:53 pm PDT
-- Setup. attaches a greyscale context and pixelmap to your screen.
&sgf[TransformTest]
SetDevice[$Std8bpp, [0,0,0,0]]
LoadGrey8BitMap[]
-- Creates a context of the specified size, which is not attached to the screen. This returns an integer value which is an index into a context array. You can then hand this context to other procedures by referencing that array. You can have up to 10 contexts of this sort; but don't make them too big or you will have problems.
-- The GetAISFile procedure puts an ais file into the pixelmap for the specified context; the context parameter defaults to the one attached to the screen. PutAISFile and PutFastAISFile do the same thing, only in reverse.
CreateContext[ $Std8bpp, [0, 0, 640, 480]]
GetAISFile[ "[Indigo]<Imager>FilteredTransforms>Curves.ais", contexts[0]]
PutAISFile[ "[]<>Users>Hiller.pa>imager>file.ais"]
PutFastAISFile[ "[]<>Users>Hiller.pa>imager>file.ais"]
-- Sets the window into the pixelmap. This will determine what part of the image will get transformed (If you don't set the window at all, you will get the entire pixelmap for the context you specify). The coordinates are [xMin, yMin, xSize, ySize], in pixels. My coordinate system is right-handed, with the origin at the lower left corner of the image as it would appear on the screen.
SetWindow[ [50, 50, 100, 200]]
SetWindow[ [0, 0, 100, 100], contexts[0]]
-- This is so you can change which pixel model you are using to filter the image. Filter 0 is about twice as fast, but doesn't produce quite as good an image. The initial default filter is filter 0.
SetFilter[0]
SetFilter[1]
-- Transformation commands. The scaling is to some fraction of the original size. Angles are in degrees for rotation. TransformImage assumes you have already built the CurrentMatrix; examples of this process can be found below. Focal length is in pixels. So is translation. The contexts default to the screen. They are in the order input, output; so for example the RotateImage command will start with the image from contexts[0], rotate it 60 degrees, and place it in contexts[1] with its origin at the position (50, 15) relative to the lower left corner of the bounded window of contexts[1].
ScaleImage[.5, .5]
ScaleImage[.3, .3, 0, 0, contexts[0]]
RotateImage[60, 50, 15, contexts[0], contexts[1]]
TransformImage[ 30, 25, 50, CurrentMatrix, contexts[0]]
-- When building a transformation matrix, always start with the identity matrix.
-- This does a combination of a 60 degree rotation and a scaling to 1/2 the original size, in the plane of the screen. Any transformation where the image doesn't move out of the plane of the screen, the focal length should be 1. The origin of this image will appear at the position (30, 25) in the output.
CurrentMatrix ← Matrix3d.Identity[]
CurrentMatrix ← Matrix3d.RotateAboutZAxis[ CurrentMatrix, 60]
CurrentMatrix ← Matrix3d.Scale[ CurrentMatrix, .5, .5, 1]
TransformImage[ 30, 25, 1, CurrentMatrix]
-- This gives you a sort of runway effect; if you have a file that is 100 pixels wide to begin with. It rotates the image onto the horizontal plane, moves it over and down so your eyepoint is centered in the air over it, and looks at it from a focal length of 200 pixels (you are 50 pixels above the surface of the runway).
CurrentMatrix ← Matrix3d.Identity[]
CurrentMatrix ← Matrix3d.RotateAboutXAxis[ CurrentMatrix, -90]
CurrentMatrix ← Matrix3d.Translate[ CurrentMatrix, -50, -50, 0]  -- move over and down to get eyepoint centered over image
TransformImage[ 50, 50, 200, CurrentMatrix, contexts[0]]  -- after perspective transform, move it back to its original position
-- This is the series of commands I used to create "eggsAtParc.ais". You can look at that image and at this series of commands to get an idea of how to put more complex matrices together. Matrix3D.mesa also has more information about transformations and what the format of the matrices is, if you want to build your own transform from scratch.
CreateContext[ $Std8bpp, [0, 0, 215, 215]]

GetAISFile[ "[Indigo]<AIS>NewParc.ais"]

GetAISFile[ "[Indigo]<AIS>EggsStriped.ais", contexts[0]]
CurrentMatrix ← Matrix3d.Identity[]
CurrentMatrix ← Matrix3d.Translate[ CurrentMatrix, 0, -215, 0]
CurrentMatrix ← Matrix3d.RotateAboutXAxis[ CurrentMatrix, 25]
CurrentMatrix ← Matrix3d.LocalRotateAboutYAxis[ CurrentMatrix, -35]
CurrentMatrix ← Matrix3d.LocalTranslate[ CurrentMatrix, -215, 0, 0]

TransformImage[ 250, 250, 400, CurrentMatrix, contexts[0]]

GetAISFile[ "[Indigo]<AIS>EggSpot3.ais", contexts[0]]
CurrentMatrix ← Matrix3d.Identity[]
CurrentMatrix ← Matrix3d.Translate[ CurrentMatrix, 0, -215, 0]
CurrentMatrix ← Matrix3d.RotateAboutXAxis[ CurrentMatrix, 25]
CurrentMatrix ← Matrix3d.LocalRotateAboutYAxis[ CurrentMatrix, 55]

TransformImage[ 250, 250, 400, CurrentMatrix, contexts[0]]

GetAISFile[ "[Indigo]<AIS>EggsChecked.ais", contexts[0]]
CurrentMatrix ← Matrix3d.Identity[]
CurrentMatrix ← Matrix3d.RotateAboutXAxis[ CurrentMatrix, 25]
CurrentMatrix ← Matrix3d.LocalRotateAboutYAxis[ CurrentMatrix, -35]
CurrentMatrix ← Matrix3d.LocalTranslate[ CurrentMatrix, -215, 0, 0]
CurrentMatrix ← Matrix3d.LocalRotateAboutXAxis[ CurrentMatrix, -90]

TransformImage[ 250, 250, 400, CurrentMatrix, contexts[0]]

PutAISFile[ "///Users/Hiller.pa/Imager/eggsAtParc.ais"]
-- These are a few random commands that I found useful.
NameColor["Black"]
FillRectangle[0.0, 0.0, .26, .2]
NameColor["White"]