#!/bin/sh # This is a shar archive. # The rest of this file is a shell script which will extract: # # 7_4a.c 7_4e.eqn main.c makefile tst.cmp # # To extract the files from this shell archive file simply # create a directory for this file, move the archive file # to it and enter the command # # sh filename # # The files will be extracted automatically. # Note: Do not use csh. # # Archive created: Mon Jul 30 23:10:31 EDT 1990 # echo x - 7_4a.c sed 's/^X//' > 7_4a.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // exercise 7.4 // connect two shapes #include // return the square of the // distance between two points inline int dist(point a, point b) { int deltax = a.x - b.x; int deltay = a.y - b.y; return deltax * deltax + deltay * deltay; } // find the closest contact-points between // two shapes and draw a line between them void connectshapes(const shape *a, const shape *b) { // save each of the 8 points relevant to each shape point apts[8], bpts[8]; point *ptptr = apts; const shape *shptr = a; for (int i = 0; i < 2; i++, shptr = b, ptptr = bpts) { *ptptr++ = shptr->north(); *ptptr++ = shptr->neast(); *ptptr++ = shptr->east(); *ptptr++ = shptr->seast(); *ptptr++ = shptr->south(); *ptptr++ = shptr->swest(); *ptptr++ = shptr->west(); *ptptr++ = shptr->nwest(); } // save one set of points and their distance point pta = apts[0], ptb = bpts[0]; int mindist = dist(pta, ptb); // find closest point on shape b to pta int ndist; for (i = 1; i < 8; i++) if ((ndist = dist(pta, bpts[i])) < mindist) { ptb = bpts[i]; mindist = ndist; } // look for a set of points even closer for (i = 1; i < 8; i++) for (int j = 0; j < 8; j++) if ((ndist = dist(apts[i], bpts[j])) < mindist) { pta = apts[i]; ptb = bpts[j]; mindist = ndist; } // draw a line between the two points put_line(pta, ptb); } !EOF! ls -l 7_4a.c echo x - 7_4e.eqn sed 's/^X//' > 7_4e.eqn << '!EOF!' X.EQ delim $$ X.EN The distance between two points is given by the formula $sqrt { DELTA x sup 2 + DELTA y sup 2 }$. $DELTA x$ is the difference between the $x$ values of the two points; similarly for $DELTA y$. After gathering the 8 contact points, it is straightforward to loop through all of the combinations of points to find which pair of points is closest together. Once the two closest points are found, the X.CW put_line () function can be called to draw the line between them. !EOF! ls -l 7_4e.eqn echo x - main.c sed 's/^X//' > main.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include extern void connectshapes(const shape *a, const shape *b); main() { screen_init(); shape* p1 = new rectangle(point(12,10),point(20,20)); shape* p2 = new line(point(2,2),point(8,4)); shape_refresh(); connectshapes(p1, p2); screen_refresh(); screen_end(); return 0; } !EOF! ls -l main.c echo x - makefile sed 's/^X//' > makefile << '!EOF!' CC= CC -I. -I../shape -I../../CC CFLAGS= +i -g SHP= ../shape all: tst OBJ= 7_4a.o main.o $(SHP)/shape.a tst: $(OBJ) $(SHP)/shape.a $(CC) $(OBJ) -o tst $(SHP)/shape.a 7_4a.o: 7_4a.c $(SHP)/shape.h $(CC) $(CFLAGS) -c 7_4a.c main.o: main.c $(SHP)/shape.h $(CC) $(CFLAGS) -c main.c CMP= tst.cmp OUT= tst.out tst.out: tst ; tst > tst.out test: all $(CMP) $(OUT) cmp tst.out tst.cmp @echo test done !EOF! ls -l makefile echo x - tst.cmp sed 's/^X//' > tst.cmp << '!EOF!' ********* * * * * * * * * * * * * * * * * * * ********* ** *** ** ********* * * * * * * * * * * * * * * * * * * ********* * * * * * ** *** ** !EOF! ls -l tst.cmp # The following exit is to ensure that extra garbage # after the end of the shar file will be ignored. exit 0