home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
gdead.berkeley.edu
/
gdead.berkeley.edu.tar
/
gdead.berkeley.edu
/
pub
/
cad-tools
/
ciftomann.tar
/
CD
/
xforms.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-01-28
|
8KB
|
306 lines
/*
* xforms.c
*
* Copyright -C- 1981 Kenneth H. Keller, Giles C. Billingsley
* sccsid "%W% %G%"
*
* KIC is a graphics editor that was developed by the integrated
* circuits group of the Electronics Research Laboratory and the
* Department of Electrical Engineering and Computer Sciences at
* the University of California, Berkeley, California. The program
* KIC is available free of charge to any interested party.
* The sale, resale, or use of this program for profit without the
* express written consent of the Department of Electrical Engineering
* and Computer Sciences, University of California, Berkeley, California,
* is forbidden.
*/
/*
* Transforms package.
*
*/
#include "cd.h"
static struct tt TTransforms;
TInit(){
TTransforms.ttSP = 0;
TIdentity();
}
TEmpty(){
if(TTransforms.ttSP == 0)
return(True);
else
return(False);
}
TFull(){
if(TTransforms.ttSP == XFORMSTACKSIZE)
return(True);
else
return(False);
}
TPush(){
int Int1,Int2;
for(Int1 = 0;Int1 < 3;++Int1)
for(Int2 = 0;Int2 < 2;++Int2)
TTransforms.ttStack[TTransforms.ttSP][Int1][Int2] =
TTransforms.ttCurrent[Int1][Int2];
++TTransforms.ttSP;
}
TPop(){
int Int1,Int2;
--TTransforms.ttSP;
for(Int1 = 0;Int1 < 3;++Int1){
for(Int2 = 0;Int2 < 2;++Int2){
TTransforms.ttCurrent[Int1][Int2]
= TTransforms.ttStack[TTransforms.ttSP][Int1][Int2];
}
}
}
TCurrent(TFP)
int *TFP;
{
int i,j;
for(i=0; i<3; ++i){
for(j=0; j<3; ++j){
TFP[(3 * i) + j] = TTransforms.ttCurrent[i][j];
}
}
}
TTranslate(X,Y)
int X,Y;
{
TTransforms.ttCurrent[2][0] = TTransforms.ttCurrent[2][0]+X;
TTransforms.ttCurrent[2][1] = TTransforms.ttCurrent[2][1]+Y;
}
TMY(){
TTransforms.ttCurrent[0][1] = -TTransforms.ttCurrent[0][1];
TTransforms.ttCurrent[1][1] = -TTransforms.ttCurrent[1][1];
TTransforms.ttCurrent[2][1] = -TTransforms.ttCurrent[2][1];
}
TMX(){
TTransforms.ttCurrent[0][0] = -TTransforms.ttCurrent[0][0];
TTransforms.ttCurrent[1][0] = -TTransforms.ttCurrent[1][0];
TTransforms.ttCurrent[2][0] = -TTransforms.ttCurrent[2][0];
}
TRotate(XDirection,YDirection)
int XDirection,YDirection;
/*
Rotation angle is expressed as a CIF-style direction vector.
*/
{
int Int1;
if(XDirection == 0){
if(abs(YDirection) > 1)
if(YDirection < 0)
YDirection = -1;
else
YDirection = 1;
}
elif(YDirection == 0){
if(abs(XDirection) > 1)
if(XDirection < 0)
XDirection = -1;
else
XDirection = 1;
}
if(XDirection == 1 And YDirection == 0)
/*
Don't rotate at all.
*/
return;
elif(XDirection == 0 And YDirection == -1){
/*
Rotate ccw by 270 degrees.
*/
Int1 = TTransforms.ttCurrent[0][0];
TTransforms.ttCurrent[0][0] = TTransforms.ttCurrent[0][1];
TTransforms.ttCurrent[0][1] = -Int1;
Int1 = TTransforms.ttCurrent[1][0];
TTransforms.ttCurrent[1][0] = TTransforms.ttCurrent[1][1];
TTransforms.ttCurrent[1][1] = -Int1;
Int1 = TTransforms.ttCurrent[2][0];
TTransforms.ttCurrent[2][0] = TTransforms.ttCurrent[2][1];
TTransforms.ttCurrent[2][1] = -Int1;
}
elif(XDirection == 0 And YDirection == 1){
/*
Rotate ccw by 90 degrees.
*/
Int1 = TTransforms.ttCurrent[0][0];
TTransforms.ttCurrent[0][0] = -TTransforms.ttCurrent[0][1];
TTransforms.ttCurrent[0][1] = Int1;
Int1 = TTransforms.ttCurrent[1][0];
TTransforms.ttCurrent[1][0] = -TTransforms.ttCurrent[1][1];
TTransforms.ttCurrent[1][1] = Int1;
Int1 = TTransforms.ttCurrent[2][0];
TTransforms.ttCurrent[2][0] = -TTransforms.ttCurrent[2][1];
TTransforms.ttCurrent[2][1] = Int1;
}
elif(XDirection == -1 And YDirection == 0){
/*
Rotate ccw by 180 degrees.
*/
int Int1,Int2;
for(Int1 = 0;Int1 < 3;++Int1){
for(Int2 = 0;Int2 < 2;++Int2){
TTransforms.ttCurrent[Int1][Int2]
= -TTransforms.ttCurrent[Int1][Int2];
}
}
}
}
TIdentity(){
TTransforms.ttCurrent[0][0] = TTransforms.ttCurrent[1][1] =
TTransforms.ttCurrent[2][2] = 1;
TTransforms.ttCurrent[0][1] = TTransforms.ttCurrent[1][0] =
TTransforms.ttCurrent[0][2] = TTransforms.ttCurrent[1][2] =
TTransforms.ttCurrent[2][0] = TTransforms.ttCurrent[2][1] = 0;
}
TPoint(X,Y)
int *X,*Y;
/*
Transform the point.
*/
{
int Int1;
Int1 = *X*TTransforms.ttCurrent[0][0]+*Y*TTransforms.ttCurrent[1][0]+
TTransforms.ttCurrent[2][0];
*Y = *X*TTransforms.ttCurrent[0][1]+*Y*TTransforms.ttCurrent[1][1]+
TTransforms.ttCurrent[2][1];
*X = Int1;
}
TPremultiply(){
/*
Form the instance transform.
This is done by computing TTransforms.ttCurrent*TTransforms.ttStack[
TTransforms.ttSP-1] and
placing the product in TTransforms.ttCurrent.
So, the scenario for transforming the coordinates of a master follows.
TPush();
TIdentity();
Invoke TMX, TTranslate, etc. to build instance transform.
Form the instance transform.
TPremultiply();
Invoke TPoint to transform master points to instance points.
TPop();
*/
int Int1,Int2,Int3,Int4,Int5,Int6;
int SP;
SP = TTransforms.ttSP-1;
Int1 = TTransforms.ttCurrent[0][0]*TTransforms.ttStack[SP][0][0]+
TTransforms.ttCurrent[0][1]*TTransforms.ttStack[SP][1][0];
Int2 = TTransforms.ttCurrent[0][0]*TTransforms.ttStack[SP][0][1]+
TTransforms.ttCurrent[0][1]*TTransforms.ttStack[SP][1][1];
Int3 = TTransforms.ttCurrent[1][0]*TTransforms.ttStack[SP][0][0]+
TTransforms.ttCurrent[1][1]*TTransforms.ttStack[SP][1][0];
Int4 = TTransforms.ttCurrent[1][0]*TTransforms.ttStack[SP][0][1]+
TTransforms.ttCurrent[1][1]*TTransforms.ttStack[SP][1][1];
Int5 = TTransforms.ttCurrent[2][0]*TTransforms.ttStack[SP][0][0]+
TTransforms.ttCurrent[2][1]*TTransforms.ttStack[SP][1][0]+
TTransforms.ttStack[SP][2][0];
Int6 = TTransforms.ttCurrent[2][0]*TTransforms.ttStack[SP][0][1]+
TTransforms.ttCurrent[2][1]*TTransforms.ttStack[SP][1][1]+
TTransforms.ttStack[SP][2][1];
TTransforms.ttCurrent[0][0] = Int1;
TTransforms.ttCurrent[0][1] = Int2;
TTransforms.ttCurrent[1][0] = Int3;
TTransforms.ttCurrent[1][1] = Int4;
TTransforms.ttCurrent[2][0] = Int5;
TTransforms.ttCurrent[2][1] = Int6;
}
TInverse()
/*
Compute the inverse transform of the current transform.
Because all transformations are Manhattan, the
det of the current transform matrix is always -1 or +1.
*/
{
int detCurrent;
detCurrent =
TTransforms.ttCurrent[0][0]*
TTransforms.ttCurrent[1][1]-
TTransforms.ttCurrent[1][0]*
TTransforms.ttCurrent[0][1];
if(detCurrent == 1)
{
TTransforms.ttInverseCurrent[0][0] = TTransforms.ttCurrent[1][1];
TTransforms.ttInverseCurrent[0][1] = -TTransforms.ttCurrent[0][1];
TTransforms.ttInverseCurrent[1][0] = -TTransforms.ttCurrent[1][0];
TTransforms.ttInverseCurrent[1][1] = TTransforms.ttCurrent[0][0];
TTransforms.ttInverseCurrent[2][0] =
TTransforms.ttCurrent[1][0]*
TTransforms.ttCurrent[2][1]-
TTransforms.ttCurrent[2][0]*
TTransforms.ttCurrent[1][1];
TTransforms.ttInverseCurrent[2][1] =
-TTransforms.ttCurrent[0][0]*
TTransforms.ttCurrent[2][1]+
TTransforms.ttCurrent[0][1]*
TTransforms.ttCurrent[2][0];
}
else
{
TTransforms.ttInverseCurrent[0][0] = -TTransforms.ttCurrent[1][1];
TTransforms.ttInverseCurrent[0][1] = TTransforms.ttCurrent[0][1];
TTransforms.ttInverseCurrent[1][0] = TTransforms.ttCurrent[1][0];
TTransforms.ttInverseCurrent[1][1] = -TTransforms.ttCurrent[0][0];
TTransforms.ttInverseCurrent[2][0] =
-TTransforms.ttCurrent[1][0]*
TTransforms.ttCurrent[2][1]+
TTransforms.ttCurrent[2][0]*
TTransforms.ttCurrent[1][1];
TTransforms.ttInverseCurrent[2][1] =
TTransforms.ttCurrent[0][0]*
TTransforms.ttCurrent[2][1]-
TTransforms.ttCurrent[0][1]*
TTransforms.ttCurrent[2][0];
}
TTransforms.ttInverseCurrent[0][2] =
0;
TTransforms.ttInverseCurrent[1][2] =
0;
TTransforms.ttInverseCurrent[2][2] =
1;
}
TInversePoint(X,Y)
int *X,*Y;
/*
Transform the point.
*/
{
int Int1;
Int1 = *X * TTransforms.ttInverseCurrent[0][0]
+ *Y * TTransforms.ttInverseCurrent[1][0]
+ TTransforms.ttInverseCurrent[2][0];
*Y = *X * TTransforms.ttInverseCurrent[0][1]
+ *Y * TTransforms.ttInverseCurrent[1][1]
+ TTransforms.ttInverseCurrent[2][1];
*X = Int1;
}