File: SVPredefSweepsImpl.mesa
Last edited by Eric Bier on July 22, 1987 4:45:03 pm PDT
Copyright © 1984 by Xerox Corporation. All rights reserved.
Contents: A cube, a cylinder, a cone, a sphere and a torus are created at load time and made available
DIRECTORY
SVPredefSweeps, RealFns, SV2d, SVPolygon2d, SVSweepGeometry;
SVPredefSweepsImpl: CEDAR PROGRAM
IMPORTS RealFns, SVPolygon2d, SVSweepGeometry
EXPORTS SVPredefSweeps =
BEGIN
RevoluteMesh: TYPE = REF RevoluteMeshRecord;
RevoluteMeshRecord: TYPE = SVSweepGeometry.RevoluteMeshRecord;
LinearMesh: TYPE = REF LinearMeshRecord;
LinearMeshRecord: TYPE = SVSweepGeometry.LinearMeshRecord;
ToroidalMesh: TYPE = REF ToroidalMeshRecord;
ToroidalMeshRecord: TYPE = SVSweepGeometry.ToroidalMeshRecord;
Polygon: TYPE = SV2d.Polygon;
Path: TYPE = SV2d.Path;
linesOfLatitude: NAT ← 5;
linesOfLongitude: NAT ← 8;
SetLinesOfLatitude: PUBLIC PROC [lat: NAT] = {
linesOfLatitude ← lat;
};
SetLinesOfLongitude: PUBLIC PROC [long: NAT] = {
linesOfLongitude ← long;
};
GetLinesOfLatitude: PUBLIC PROC [] RETURNS [lat: NAT] = {
lat ← linesOfLatitude;
};
GetLinesOfLongitude: PUBLIC PROC [] RETURNS [long: NAT] = {
long ← linesOfLongitude;
};
CreateSphere: PUBLIC PROC [r: REAL] RETURNS [RevoluteMesh] = {
Generate a semi-circle in the x-y plane with 10 points where the end two points are on the y axis
x, y: REAL;
path: Path ← SVPolygon2d.CreatePath[linesOfLatitude];
theta, deltaTheta: REAL;
SVPolygon2d.PutPathPoint[path, 0, [0,r]];
theta ← 90.0;
deltaTheta ← 180.0/(linesOfLatitude - 1); -- Nat to float?
FOR i: NAT IN [2..linesOfLatitude-1] DO
theta ← theta - deltaTheta;
x ← r*RealFns.CosDeg[theta];
y ← r*RealFns.SinDeg[theta];
SVPolygon2d.PutPathPoint[path, i-1, [x,y]];
ENDLOOP;
SVPolygon2d.PutPathPoint[path, linesOfLatitude-1, [0,-r]];
RETURN[SVSweepGeometry.RevoluteSweep[path, linesOfLongitude]];
};
CreateCube: PUBLIC PROC [side: REAL] RETURNS [LinearMesh] = {
pos, neg: REAL;
lin: LinearMesh;
poly: Polygon ← SVPolygon2d.CreatePoly[4];
pos ← side*(0.5);
neg ← side*(-0.5);
poly ← SVPolygon2d.PutPolyPoint[poly, 0, [neg,pos]];
poly ← SVPolygon2d.PutPolyPoint[poly, 1, [pos,pos]];
poly ← SVPolygon2d.PutPolyPoint[poly, 2, [pos,neg]];
poly ← SVPolygon2d.PutPolyPoint[poly, 3, [neg,neg]];
lin ← SVSweepGeometry.LinearSweep[poly, pos, neg];
RETURN[lin];
};
CreateFullCylinder: PUBLIC PROC [r, h: REAL] RETURNS [RevoluteMesh] = {
path: Path ← SVPolygon2d.CreatePath[linesOfLatitude];
height, deltaH: REAL;
height ← h/2.0;
deltaH ← h/(linesOfLatitude - 1);
SVPolygon2d.PutPathPoint[path, 0, [r,height]];
Make sure the endpoints are as accurate as possible
SVPolygon2d.PutPathPoint[path, linesOfLatitude-1, [r,-height]];
FOR i: NAT IN [2..linesOfLatitude-1] DO
height ← height - deltaH;
SVPolygon2d.PutPathPoint[path, i-1, [r,height]];
ENDLOOP;
RETURN[SVSweepGeometry.RevoluteSweep[path, linesOfLongitude]];
};
CreateCylinder: PUBLIC PROC [r, h: REAL] RETURNS [RevoluteMesh] = {
path: Path ← SVPolygon2d.CreatePath[2];
height: REAL ← h/2.0;
SVPolygon2d.PutPathPoint[path, 0, [r,height]];
SVPolygon2d.PutPathPoint[path, 1, [r,-height]];
RETURN[SVSweepGeometry.RevoluteSweep[path, linesOfLongitude]];
};
CreateCone: PUBLIC PROC [r, h: REAL] RETURNS [RevoluteMesh] = {
path: Path ← SVPolygon2d.CreatePath[linesOfLatitude];
height, deltaH, x, deltaX: REAL;
height ← h;
deltaH ← h/(linesOfLatitude - 1);
x ← 0;
deltaX ← r/(linesOfLatitude - 1);
Generate a cone pointing up with the center of its circular base at the origin of the local cs
SVPolygon2d.PutPathPoint[path, 0, [0,h]];-- top is on the y axis;
SVPolygon2d.PutPathPoint[path, linesOfLatitude-1, [r,0]];-- base is on the xz plane
FOR i: NAT IN [2..linesOfLatitude-1] DO
height ← height - deltaH;
x ← x + deltaX;
SVPolygon2d.PutPathPoint[path, i-1, [x,height]];
ENDLOOP;
RETURN[SVSweepGeometry.RevoluteSweep[path, linesOfLongitude]];
};
CreateTorus: PUBLIC PROC [rBig, rCross: REAL] RETURNS [ToroidalMesh] = {
poly: Polygon ← SVPolygon2d.CreatePoly[linesOfLatitude];
Just define the translated circle which is the torus's cross section (see full cylinder for help)
alpha, deltaAlpha, sin, cos, x, y: REAL; -- the cross section circle
alpha ← 0;
deltaAlpha ← -360/linesOfLatitude; -- negative because ToroidalSweep assumes clockwise
poly ← SVPolygon2d.PutPolyPoint[poly, 0, [rBig+rCross,0]];
FOR i: NAT IN[2..linesOfLatitude] DO
alpha ← alpha + deltaAlpha;
sin ← RealFns.SinDeg[alpha];
cos ← RealFns.CosDeg[alpha];
x ← rBig + rCross*cos;
y ← rCross*sin;
poly ← SVPolygon2d.PutPolyPoint[poly, i-1, [x,y]];
ENDLOOP;
RETURN[SVSweepGeometry.ToroidalSweep[poly, linesOfLongitude]];
};
GetUnitSphere: PUBLIC PROC RETURNS [RevoluteMesh] = {
RETURN[CreateSphere[1.0]]
};
GetUnitCube: PUBLIC PROC RETURNS [LinearMesh] = {
RETURN[CreateCube[2.0]]
};
GetUnitCylinder: PUBLIC PROC RETURNS [RevoluteMesh] = {
RETURN[CreateFullCylinder[1.0, 2.0]]
};
GetUnitCone: PUBLIC PROC RETURNS [RevoluteMesh] = {
RETURN[CreateCone[1.0, 1.0]]
};
END.