File:  [CSRG BSD Unix] / 41BSD / cmd / cifplot / transforms.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:12:53 2018 UTC (8 years, 1 month ago) by root
Branches: MAIN, BSD
CVS tags: HEAD, BSD41
BSD 4.1

/*******************************************************************
*                                                                  *
*    File: CIFPLOT/transforms.c                                    *
*    Written by Dan Fitzpatrick                                    *
*    copyright 1980 -- Regents of the University of California     *
*                                                                  *
********************************************************************/

#include <stdio.h>
#include <math.h>
#include "defs.h"
#include "globals.h"
#include "parser_defs.h"
#include "structs.h"
#include "alloc.h"

IMPORT alloc();
IMPORT point *MakePoint();
IMPORT char *Concat();

transform *CurTransform;
struct TCell *TransStack;

transform *
MatrixMult(t1,t2)
register transform *t1,*t2;
/* Return a pointer to a transform that is the product of 't1' & 't2' */
{
    register transform *out;
    /*
    int i,j,k;
    */
    out = GetTransform();
    out->refs = 0;
    if(output == NOPLOT)
    	out->TransString = Concat(t1->TransString,t2->TransString,0);
    /*
    for(i=0; i<3; i++)
	for(j=0; j<3; j++)
	    out->t[i][j] = 0;
     for(i=0; i<3; i++)
	for(j=0; j<3; j++)
	    for(k=0; k<3; k++)
		out->t[i][j] = out->t[i][j] + t1->t[i][k]*t2->t[k][j];
		*/
     out->t[0][0] = t1->t[0][0]*t2->t[0][0] + t1->t[0][1]*t2->t[1][0];
     out->t[0][1] = t1->t[0][0]*t2->t[0][1] + t1->t[0][1]*t2->t[1][1];
     out->t[1][0] = t1->t[1][0]*t2->t[0][0] + t1->t[1][1]*t2->t[1][0];
     out->t[1][1] = t1->t[1][0]*t2->t[0][1] + t1->t[1][1]*t2->t[1][1];
     out->t[2][0] = t1->t[2][0]*t2->t[0][0] + t1->t[2][1]*t2->t[1][0] + t2->t[2][0];
     out->t[2][1] = t1->t[2][0]*t2->t[0][1] + t1->t[2][1]*t2->t[1][1] + t2->t[2][1];
     return(out);
     }

transform *
MakeTransform()
/* Return a pointer to an identity transform */
{
    transform *trans;
    int i,j;
    trans = GetTransform();
    if(output == NOPLOT)
    	trans->TransString = Concat("",0);
    trans->refs = 0;
    for(i=0; i<3; i++)
	for(j=0; j<3; j++)
	    if (i==j) trans->t[i][i]=1;
		  else trans->t[i][j]=0;
    return(trans);
    }

transform *
CopyTransform(t)
transform *t;
{
    transform *temp;
    int i,j;
    temp = MakeTransform();
    for(i=0; i<3; i++)
	for(j=0; j<3; j++)
		temp->t[i][j] = t->t[i][j];
    return(temp);
    }

transform *
Mirror(ch,trans)
char ch;
transform *trans;
/* Return a pointer to a transform that does a mirroring about the
 * axis specified in 'ch' combined with the effect of 'trans' */
{
    transform *temp,*temp2;
    temp = MakeTransform();
    if(output == NOPLOT)
    	Free(temp->TransString);
    if(ch == 'y' || ch == 'Y') {
	temp->t[1][1] = -1;
        if(output == NOPLOT)
		temp->TransString = Concat(" MY",0);
	}
    else if(ch == 'x' || ch == 'X') {
	temp->t[0][0] = -1;
        if(output == NOPLOT)
		temp->TransString = Concat(" MX",0);
	}
      else {
	Error("Mirror call about unknown axis",INTERNAL);
        if(output == NOPLOT)
		temp->TransString = Concat(" XX",0);
	}
    temp2 = MatrixMult(temp,trans);
    if(output == NOPLOT)
    	Free(temp->TransString);
    FreeTransform(temp);
    return(temp2);
    }

transform *
Rotate(pt,trans)
point *pt;
transform *trans;
/* Return a pointer to a transform that does a rotation to a vector
 * specified by 'pt' combined with the effect of trans. */
{
    transform *temp,*temp2;
    real c;
    char s[128];

    temp = MakeTransform();
    if(output == NOPLOT) {
	Free(temp->TransString);
    	sprintf(s," R %d %d",TRUNC(pt->x), TRUNC(pt->y));
    	temp->TransString = Concat(s,0);
	}
    c = (real) sqrt((double) ((pt->x)*(pt->x) + (pt->y)*(pt->y)));
    /* Watch out for divide by 0 */
    if( -0.00001 <= c && c <= 0.00001 ) Error("Attempted to divide by zero",INTERNAL);
    temp->t[0][0] = (pt->x)/c;	temp->t[0][1] = (pt->y)/c;
    temp->t[1][0] = -(pt->y)/c;	temp->t[1][1] = (pt->x)/c;
    temp2 = MatrixMult(temp,trans);
    if(output == NOPLOT)
       Free(temp->TransString);
    FreeTransform(temp);
    return(temp2);
    }

transform *
Translate(pt,trans)
point *pt;
transform *trans;
/* Return a pointer to a transform that translates points by the vector
 * 'pt' combined with the effects of 'trans'. */
{
    transform *temp,*temp2;
    char s[128];

    temp = MakeTransform();
    if(output == NOPLOT) {
    	Free(temp->TransString);
    	sprintf(s," T %d %d",TRUNC(pt->x), TRUNC(pt->y));
    	temp->TransString = Concat(s,0);
	}
    temp->t[2][0] = pt->x;
    temp->t[2][1] = pt->y;
    temp2 = MatrixMult(temp,trans);
    if(output == NOPLOT) 
	Free(temp->TransString);
    FreeTransform(temp);
    return(temp2);
    }

transform *
Scale(a,b,trans)
int a,b;
transform *trans;
/* Return a pointer to a transform that scales points by a/b
 * combined with the effects of 'trans'. */
{
    transform *temp,*temp2;
    char s[128];

    temp = MakeTransform();
    if(output == NOPLOT) {
    	Free(temp->TransString);
    	sprintf(s," S %d %d",a,b);
    	temp->TransString = Concat(s,0);
	}
    temp->t[0][0] = ((real) a)/((real) b);
    temp->t[1][1] = ((real) a)/((real) b);
    temp2 = MatrixMult(temp,trans);
    if(output == NOPLOT) 
	Free(temp->TransString);
    FreeTransform(temp);
    return(temp2);
    }

/*
real
MakeFloat(a,b)
int a,b;
{
    real f,d;
    int rem;
    f = 0.0;
    d = 1.0;

    while(b>0) {
	rem = b%10;
	d = d*0.1;
	f = f + ((real) rem)*d;
	b = TRUNC(b/10);
	}
    return(a>=0 ? ((real) a) + f: ((real) a) - f);
    }
    */

/*
transform *
ReadTransform(a,b,c,d,e,f,g,h,i,j,k,l,t)
int a,b,c,d,e,f;
int g,h,i,j,k,l;
transform *t;
{
    transform *temp,*temp2;
    temp = MakeTransform();
    temp->t[0][0] = MakeFloat(a,b);
    temp->t[0][1] = MakeFloat(c,d);
    temp->t[1][0] = MakeFloat(e,f);
    temp->t[1][1] = MakeFloat(g,h);
    temp->t[2][0] = MakeFloat(i,j);
    temp->t[2][1] = MakeFloat(k,l);
    temp2 = MatrixMult(temp,t);
    FreeTransform(temp);
    return(temp2);
    }
    */

/*
float MakeFlt(i,d)
int i;
float d;
{
    float f;

    f = (i < 0) ? i - d : i + d;
    return(f);
    }

float Float(ch,f)
char ch;
float f;
{
    float d;

    d = 0.1*((float) ((ch -'0') + f));
    return(d);
    }
    */

point *
TransPt(pt,trans)
point *pt;
transform *trans;
/* Transform point */
{
    real x,y;

    x = pt->x*trans->t[0][0] + pt->y*trans->t[1][0] + trans->t[2][0];
    y = pt->x*trans->t[0][1] + pt->y*trans->t[1][1] + trans->t[2][1];
    return(MakePoint(x,y));
    }

Trans(x,y,trans)
register real *x,*y;
register transform *trans;
{
    register real z;

    z = *x;
    *x = z*trans->t[0][0] + (*y)*trans->t[1][0] + trans->t[2][0];
    *y = z*trans->t[0][1] + (*y)*trans->t[1][1] + trans->t[2][1];
    }

/*
InitTransform()
{
    TransStack = NIL;
    CurTransform = MakeTransform();
    }

PushTransform(trans)
transform *trans;
/* Push the Current Transform on the transform stack. Multiply
 * 'trans' by old Current Transform and make the product the
 * Current Traansform.	*/
 /*
{
    struct TCell *p;

    p = (struct TCell *) alloc(sizeof(struct TCell));
    p->TPtr = CurTransform;
    p->TLink = TransStack;
    TransStack = p;
    CurTransform = MatrixMult(CurTransform,trans);
    return;
    }

transform *
PopTransform()
/* Replace the Current Transform by the top of the transform stack
 * and pop the transform stack */
 /*
{
    struct TCell *t;

    if(TransStack == NIL)
	Error("Attempted to Pop empty Transform Stack",INTERNAL);
    CurTransform = TransStack->TPtr;
    t = TransStack;
    TransStack = TransStack->TLink;
    FreeTransform(t);
    return(CurTransform);
    }
    */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.