Skip to content

Commit

Permalink
refactor: created cropview() function to manage view sections
Browse files Browse the repository at this point in the history
  • Loading branch information
Gregungory committed Jan 12, 2022
1 parent 0694208 commit 76d1e8c
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 59 deletions.
94 changes: 84 additions & 10 deletions src/common/image.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef lint
static const char RCSid[] = "$Id: image.c,v 2.52 2021/02/12 00:47:08 greg Exp $";
static const char RCSid[] = "$Id: image.c,v 2.53 2022/01/12 21:07:39 greg Exp $";
#endif
/*
* image.c - routines for image generation.
Expand Down Expand Up @@ -63,16 +63,16 @@ VIEW *v
return(ill_horiz);
if (v->vert >= 180.0-FTINY)
return(ill_vert);
v->hn2 = 2.0 * tan(v->horiz*(PI/180.0/2.0));
v->vn2 = 2.0 * tan(v->vert*(PI/180.0/2.0));
v->hn2 = 2.0 * tan(v->horiz*(PI/360.));
v->vn2 = 2.0 * tan(v->vert*(PI/360.));
break;
case VT_CYL: /* cylindrical panorama */
if (v->horiz > 360.0+FTINY)
return(ill_horiz);
if (v->vert >= 180.0-FTINY)
return(ill_vert);
v->hn2 = v->horiz * (PI/180.0);
v->vn2 = 2.0 * tan(v->vert*(PI/180.0/2.0));
v->vn2 = 2.0 * tan(v->vert*(PI/360.));
break;
case VT_ANG: /* angular fisheye */
if (v->horiz > 360.0+FTINY)
Expand All @@ -87,18 +87,18 @@ VIEW *v
return(ill_horiz);
if (v->vert > 180.0+FTINY)
return(ill_vert);
v->hn2 = 2.0 * sin(v->horiz*(PI/180.0/2.0));
v->vn2 = 2.0 * sin(v->vert*(PI/180.0/2.0));
v->hn2 = 2.0 * sin(v->horiz*(PI/360.));
v->vn2 = 2.0 * sin(v->vert*(PI/360.));
break;
case VT_PLS: /* planispheric fisheye */
if (v->horiz >= 360.0-FTINY)
return(ill_horiz);
if (v->vert >= 360.0-FTINY)
return(ill_vert);
v->hn2 = 2.*sin(v->horiz*(PI/180.0/2.0)) /
(1.0 + cos(v->horiz*(PI/180.0/2.0)));
v->vn2 = 2.*sin(v->vert*(PI/180.0/2.0)) /
(1.0 + cos(v->vert*(PI/180.0/2.0)));
v->hn2 = 2.*sin(v->horiz*(PI/360.)) /
(1.0 + cos(v->horiz*(PI/360.)));
v->vn2 = 2.*sin(v->vert*(PI/360.)) /
(1.0 + cos(v->vert*(PI/360.)));
break;
default:
return("unknown view type");
Expand All @@ -120,6 +120,80 @@ VIEW *v
}


char *
cropview( /* crop a view to the indicated bounds */
VIEW *v,
double x0,
double y0,
double x1,
double y1
)
{
static char ill_crop[] = "zero crop area";
static char ill_hemi[] = "illegal crop for hemispherical view";
double d;
/* order crop extrema */
if (x0 > x1) { d=x0; x0=x1; x1=d; }
if (y0 > y1) { d=y0; y0=y1; y1=d; }

d = x1 - x0;
if (d == .0)
return(ill_crop);
if (!FABSEQ(d, 1.)) /* adjust horizontal size? */
switch (v->type) {
case VT_PER:
v->horiz = 360./PI*atan( d*tan(PI/360.*v->horiz) );
break;
case VT_PAR:
case VT_ANG:
case VT_CYL:
v->horiz *= d;
break;
case VT_HEM:
d *= sin(PI/360.*v->horiz);
if (d > 1.)
return(ill_hemi);
v->horiz = 360./PI*asin( d );
break;
case VT_PLS:
d *= sin(PI/360.*v->horiz) /
(1. + cos(PI/360.*v->horiz));
v->horiz = 360./PI*acos( (1. - d*d) / (1. + d*d) );
break;
}
d = y1 - y0;
if (d == .0)
return(ill_crop);
if (!FABSEQ(d, 1.)) /* adjust vertical size? */
switch (v->type) {
case VT_PER:
case VT_CYL:
v->vert = 360./PI*atan( d*tan(PI/360.*v->vert) );
break;
case VT_PAR:
case VT_ANG:
v->vert *= d;
break;
case VT_HEM:
d *= sin(PI/360.*v->vert);
if (d > 1.)
return(ill_hemi);
v->vert = 360./PI*asin( d );
break;
case VT_PLS:
d *= sin(PI/360.*v->vert) /
(1. + cos(PI/360.*v->vert));
v->vert = 360./PI*acos( (1. - d*d) / (1. + d*d) );
break;
}
/* fix offsets */
v->hoff = ((x0 + x1)*.5 - .5 + v->hoff) / (x1 - x0);
v->voff = ((y0 + y1)*.5 - .5 + v->voff) / (y1 - y0);

return(setview(v)); /* final error checks & set-up */
}


void
normaspect( /* fix pixel aspect or resolution */
double va, /* view aspect ratio */
Expand Down
3 changes: 2 additions & 1 deletion src/common/view.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* RCSid $Id: view.h,v 2.21 2021/12/03 18:10:48 greg Exp $ */
/* RCSid $Id: view.h,v 2.22 2022/01/12 21:07:39 greg Exp $ */
/*
* view.h - header file for image generation.
*
Expand Down Expand Up @@ -59,6 +59,7 @@ extern VIEW stdview;
#define VL_BEYOND 0x8 /* point is beyond aft clipping plane */

extern char *setview(VIEW *v);
extern char *cropview(VIEW *v, double x0, double y0, double x1, double y1);
extern void normaspect(double va, double *ap, int *xp, int *yp);
extern double viewray(FVECT orig, FVECT direc, VIEW *v, double x, double y);
extern int jitteraperture(FVECT orig, FVECT direc, VIEW *v, double dia);
Expand Down
60 changes: 12 additions & 48 deletions src/util/rpiece.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef lint
static const char RCSid[] = "$Id: rpiece.c,v 2.58 2020/02/28 05:18:49 greg Exp $";
static const char RCSid[] = "$Id: rpiece.c,v 2.59 2022/01/12 21:07:39 greg Exp $";
#endif
/*
* Generate sections of a picture.
Expand Down Expand Up @@ -298,12 +298,12 @@ init( /* set up output file and start rpict */
fprintf(fp, "SOFTWARE= %s\n", VersionID);
fputs(VIEWSTR, fp);
fprintview(&ourview, fp);
putc('\n', fp);
fputc('\n', fp);
fputnow(fp);
if (pixaspect < .99 || pixaspect > 1.01)
fputaspect(pixaspect, fp);
fputformat(COLRFMT, fp);
putc('\n', fp);
fputc('\n', fp);
fprtresolu(hres*hmult, vres*vmult, fp);
} else if ((outfd = open(outfile, O_RDWR)) >= 0) {
dolock(outfd, F_RDLCK);
Expand Down Expand Up @@ -461,57 +461,21 @@ cleanup( /* close rpict process and clean up */
static void
rpiece(void) /* render picture piece by piece */
{
char *err;
VIEW pview;
int xorg, yorg;
/* compute view parameters */
pview = ourview;
switch (ourview.type) {
case VT_PER:
pview.horiz = (2.*180./PI)*atan(
tan((PI/180./2.)*ourview.horiz)/hmult );
pview.vert = (2.*180./PI)*atan(
tan((PI/180./2.)*ourview.vert)/vmult );
break;
case VT_PAR:
case VT_ANG:
pview.horiz = ourview.horiz / hmult;
pview.vert = ourview.vert / vmult;
break;
case VT_CYL:
pview.horiz = ourview.horiz / hmult;
pview.vert = (2.*180./PI)*atan(
tan((PI/180./2.)*ourview.vert)/vmult );
break;
case VT_HEM:
pview.horiz = (2.*180./PI)*asin(
sin((PI/180./2.)*ourview.horiz)/hmult );
pview.vert = (2.*180./PI)*asin(
sin((PI/180./2.)*ourview.vert)/vmult );
break;
case VT_PLS:
pview.horiz = sin((PI/180./2.)*ourview.horiz) /
(1.0 + cos((PI/180./2.)*ourview.horiz)) / hmult;
pview.horiz *= pview.horiz;
pview.horiz = (2.*180./PI)*acos((1. - pview.horiz) /
(1. + pview.horiz));
pview.vert = sin((PI/180./2.)*ourview.vert) /
(1.0 + cos((PI/180./2.)*ourview.vert)) / vmult;
pview.vert *= pview.vert;
pview.vert = (2.*180./PI)*acos((1. - pview.vert) /
(1. + pview.vert));
break;
default:
fprintf(stderr, "%s: unknown view type '-vt%c'\n",
progname, ourview.type);
exit(cleanup(1));
}
/* render each piece */
while (nextpiece(&xorg, &yorg)) {
pview.hoff = ourview.hoff*hmult + xorg - 0.5*(hmult-1);
pview.voff = ourview.voff*vmult + yorg - 0.5*(vmult-1);
pview = ourview;
err = cropview(&pview, (double)xorg/hmult, (double)yorg/vmult,
(xorg+1.)/hmult, (yorg+1.)/vmult);
if (err != NULL) {
fprintf(stderr, "%s: %s\n", progname, err);
exit(cleanup(1));
}
fputs(VIEWSTR, torp);
fprintview(&pview, torp);
putc('\n', torp);
fputc('\n', torp);
fflush(torp); /* assigns piece to rpict */
putpiece(xorg, yorg); /* place piece in output */
}
Expand Down

0 comments on commit 76d1e8c

Please sign in to comment.