SVMappings.mesa
Last Edited by Bier on December 19, 1982 2:04 am
Author: Eric Bier on October 19, 1982 1:09 pm
Contents: A set of bidirectional mappings between 3d surfaces and a 2d image plane
DIRECTORY
Graphics,
Matrix3d,
Rope,
SV2d,
SVArtwork,
SVPolygon2d,
SVVector3d;

SVMappings: DEFINITIONS =
BEGIN
Point2d: TYPE = SV2d.Point2d;
Point3d: TYPE = Matrix3d.Point3d;
Polygon: TYPE = SVPolygon2d.Polygon;
Vector: TYPE = SVVector3d.Vector;
Artwork: TYPE = REF ArtworkObj;
ArtworkObj: TYPE = SVArtwork.Artwork;
PRect: TYPE = REF PRectObj;
PRectObj: TYPE = RECORD [xmin, ymin, xmax, ymax: REAL];
PDisk: TYPE = REF PDiskObj;
PDiskObj: TYPE = RECORD [r: REAL, origin: Point2d];
Tube: TYPE = REF TubeObj;
TubeObj: TYPE = RECORD [R: REAL, H: REAL, tubePoly: Polygon];
Disk: TYPE = REF DiskObj;
DiskObj: TYPE = RECORD [R: REAL, halfH: REAL];

When you map a straight line in image space onto the surface of a cylinder, you are taking an equation of the form cy -sx -d = 0 and applying the transform:
(x,y) <==> (R*theta, h) giving an equation of the form:
c*h - s*R*theta -d = 0. which is of the same form. Given two points on the cylinder surface, we can find the line that goes through them in a normal fashion and can map this back to the plane by either mapping the endpoints or converting the equation.
Box: TYPE = REF BoxObj;
BoxObj: TYPE = RECORD [x, halfX, y, halfY, threeHalvesY, z, halfZ: REAL, faces: ARRAY [1..6] OF Polygon];
TubeLine: TYPE = REF TubeLineObj;
TubeLineObj: TYPE = RECORD [
p1, p2: Point2d];
(theta, h) pairs. Theta in degrees.
CartesianToPolar: PROC [x, y: REAL] RETURNS [r, theta: REAL];
PolarToCartesian: PROC [r, theta: REAL] RETURNS [x, y: REAL];
CreatePDisk: PROC [r: REAL, origin: Point2d] RETURNS [pdisk: PDisk];
DrawPDisk: PROC [dc: Graphics.Context, pdisk: PDisk];
The Tube Simple Surface
CreateTube: PROC [R: REAL, H: REAL] RETURNS [tube: Tube];
Point3dToTubePoint: PROC [point3d: Point3d] RETURNS [tubePoint: Point2d];
TubePointToPoint3d: PROC [tubePoint: Point2d, assembly: REF ANY] RETURNS [point3d: Point3d];
ImageToTube: PROC [imagePoint: Point2d, data: REF ANY] RETURNS [surfacePoint: Point2d, onSurf: BOOL];
data will be a Tube. It is a ref any so we can use this mapping in ImagePolyToSurfacePoly below. surfacePoint is a [theta, h] pair.
TubeToImage: PROC [surfacePoint: Point2d, data: REF ANY] RETURNS [imagePoint: Point2d, onSurf: BOOL];
 data will be a Tube. It is a ref any so we can use this mapping in SurfacePolyToImagePoly below. surfacePoint is a [theta, h] pair.
The Cylinder Simple Surface
Point3dToDiskPoint: PROC [point3d: Point3d] RETURNS [r, theta: REAL];
DiskPointToPoint3d: PROC [r, theta: REAL, assembly: REF ANY] RETURNS [point3d: Point3d];
ImageToTopDisk: PROC [u,v: REAL, disk: Disk] RETURNS [r, theta: REAL];
TopDiskToImage: PROC [r, theta: REAL, disk: Disk] RETURNS [u,v: REAL];
ImageDiskToTopDiskBoundary: PROC [pdisk: PDisk, disk: Disk] RETURNS [R, halfH: REAL];
TopDiskBoundaryToImageDisk: PROC [R, halfH: REAL, disk: Disk] RETURNS [pdisk: PDisk];
ImageToBottomDisk: PROC [u,v: REAL, disk: Disk] RETURNS [r, theta: REAL];
BottomDiskToImage: PROC [r, theta: REAL, disk: Disk] RETURNS [u,v: REAL];
ImageDiskToBottomDiskBoundary: PROC [pdisk: PDisk, disk: Disk] RETURNS [R, halfH: REAL];
BottomDiskBoundaryToImageDisk: PROC [R, halfH: REAL, disk: Disk]
RETURNS [pdisk: PDisk];
The Box Simple Surface
Box Mapping
Imagine an unfolded box as follows:
There are four rectangles numbered left to right as 1..4.
Two more rectangles numbered 5 and 6 are above and below rectangle 2 respectively.
Rectangle 2 maps to the front (pos z) side of the box. Square 6 maps to the bottom (neg y) side. All other rectangles map accordingly.
An [x,y] pair maps to a surface point as follows:
If a box has height sy, width sx, and depth sz then the correspondences are:
IF -sy/2 <= y <= sy/2 AND
 -(sz+sx) <= x < -sx THEN Rectangle 1.
 -sx <= x <= 0 THEN Rectangle 2.
 0 < x <= sz THEN Rectangle 3.
 sz < x <= sz + sx THEN Rectangle 4.
IF -(sy/2+sz) < y < -sy/2 AND -sx <= x <= 0 THEN Rectangle 6.
IF sy/2 < y < sy/2 + sz AND -sx <= x <= 0 THEN Rectangle 5.
Otherwise, out of box.
CreateBox: PROC [x, y, z: REAL] RETURNS [box: Box];
BoxOrthogonalOInverse: PROC [point3d: Point3d, normal: Vector, box: Box] RETURNS [boxPoint: Point2d, hit: BOOL];
BoxOrthogonalO: PROC [boxPoint: Point2d, box: Box] RETURNS [point3d: Point3d, hit: BOOL];
BoxRadialOInverse: PROC [point3d: Point3d, normal: Vector, box: Box] RETURNS [boxPoint: Point2d, hit: BOOL];
BoxRadialO: PROC [boxPoint: Point2d, box: Box] RETURNS [point3d: Point3d, hit: BOOL];
ImageToBox: PROC [imagePoint: Point2d, data: REF ANY] RETURNS [surfacePoint: Point2d, onSurf: BOOL];
 data will be a Box. It is a ref any so we can use this mapping in ImagePolyToSurfacePoly below. surfacePoint is a [x, y] pair (See comment on Box Mapping above).
BoxToImage: PROC [surfacePoint: Point2d, data: REF ANY] RETURNS [imagePoint: Point2d, onSurf: BOOL];
 data will be a Box. It is a ref any so we can use this mapping in SurfacePolyToImagePoly below. surfacePoint is a [x, y] pair (See comment on Box Mapping above).
2d Surface Projections
ImagePolyToSurfacePoly: PROC [imagePoly: Polygon, map: PROC [imagePoint: Point2d, data: REF ANY] RETURNS [surfacePoint: Point2d, onSurf: BOOL], data: REF ANY] RETURNS [surfacePoly: Polygon];
 data will probably be a REF <Surface> for some type of 3d surface.
SurfacePolyToImagePoly: PROC [surfacePoly: Polygon, map: PROC [surfacePoint: Point2d, data: REF ANY] RETURNS [imagePoint: Point2d, onSurf: BOOL], data: REF ANY] RETURNS [imagePoly: Polygon];
 data will probably be a REF <Surface> for some type of 3d surface.

END.