/*@z34.c:Rotation Service:Declarations@***************************************/ /* */ /* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.41) */ /* COPYRIGHT (C) 1991, 2023 Jeffrey H. Kingston */ /* */ /* Jeffrey H. Kingston (jeff@it.usyd.edu.au) */ /* School of Information Technologies */ /* The University of Sydney 2006 */ /* AUSTRALIA */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either Version 3, or (at your option) */ /* any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA */ /* */ /* FILE: z34.c */ /* MODULE: Rotation Service */ /* EXTERNS: RotateSize() */ /* */ /*****************************************************************************/ #include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #include "externs.h" typedef struct { double x, y; } rect_coord; typedef struct { double angle, radius; } polar_coord; #define rect_to_polar(rect, polar) \ polar.angle = atan2(rect.y, rect.x), \ polar.radius = sqrt(rect.x*rect.x + rect.y*rect.y) #define polar_to_rect(polar, rect) \ rect.x = polar.radius * cos(polar.angle), \ rect.y = polar.radius * sin(polar.angle) /*@::RotateSize()@************************************************************/ /* */ /* RotateSize(xcb, xcf, xrb, xrf, y, theta) */ /* */ /* Calculate the size of x, assuming that it is y rotated by theta degrees. */ /* */ /*****************************************************************************/ void RotateSize(FULL_LENGTH *xcb, FULL_LENGTH *xcf, FULL_LENGTH *xrb, FULL_LENGTH *xrf, OBJECT y, FULL_LENGTH theta) { rect_coord ycorners[4], xcorner; polar_coord pol; double maxx, maxy, minx, miny, ang; int i; #if DEBUG_ON char buff1[20], buff2[20]; #endif /* calculate theta in radians */ ang = (double) theta * 2 * M_PI / (double) (DG * 360); ifdebug(DRS, D, sprintf(buff2, "%.1f", ang)); debug2(DRS, D, "RotateSize( %s, %s )", EchoObject(y), buff2); debug4(DRS, DD, " ycb %s, ycf %s, yrb %s, yrf %s", EchoLength(back(y, COLM)), EchoLength(fwd(y, COLM)), EchoLength(back(y, ROWM)), EchoLength(fwd(y, ROWM))); /* set up coordinates of the four corners of y */ ycorners[0].x = (float) fwd(y, COLM); ycorners[0].y = (float) back(y, ROWM); ycorners[1].x = - (float) back(y, COLM); ycorners[1].y = (float) back(y, ROWM); ycorners[2].x = - (float) back(y, COLM); ycorners[2].y = - (float) fwd(y, ROWM); ycorners[3].x = (float) fwd(y, COLM); ycorners[3].y = - (float) fwd(y, ROWM); /* rotate these four corners by theta and store their extremes */ maxx = maxy = (float) - MAX_FULL_LENGTH; minx = miny = (float) MAX_FULL_LENGTH; for( i = 0; i < 4; i++ ) { if( ycorners[i].x == 0 && ycorners[i].y == 0 ) { pol.radius = 0; pol.angle = 0; } else rect_to_polar(ycorners[i], pol); ifdebug(DRS, DD, sprintf(buff1, "%.1f", pol.angle)); ifdebug(DRS, DD, sprintf(buff2, "%.1f", ang)); debug5(DRS, DD, " transforming (%s, %s) -> (%s, %s) + %s", EchoLength( (int) ycorners[i].x), EchoLength( (int) ycorners[i].y), EchoLength( (int) pol.radius), buff1, buff2); pol.angle += ang; polar_to_rect(pol, xcorner); ifdebug(DRS, DD, sprintf(buff1, "%.1f", pol.angle)); debug4(DRS, DD, " transforming (%s, %s) -> (%s, %s)", EchoLength( (int) pol.radius), buff1, EchoLength( (int) xcorner.x), EchoLength( (int) xcorner.y) ); maxx = find_max(maxx, xcorner.x); minx = find_min(minx, xcorner.x); maxy = find_max(maxy, xcorner.y); miny = find_min(miny, xcorner.y); } /* store sizes back into x and return */ *xcb = - (int) minx; *xcf = (int) maxx; *xrb = (int) maxy; *xrf = - (int) miny; debug0(DRS, D, "RotateSize returning."); debug4(DRS, DD, " xcb %s, xcf %s, xrb %s, xrf %s", EchoLength(*xcb), EchoLength(*xcf), EchoLength(*xrb), EchoLength(*xrf)); } /* end RotateSize */