Box3<Real> GaussPointsFit3 (int numPoints, const Vector3<Real>* points) { Box3<Real> box(Vector3<Real>::ZERO,Vector3<Real>::UNIT_X, Vector3<Real>::UNIT_Y,Vector3<Real>::UNIT_Z,(Real)1.0,(Real)1.0, (Real)1.0); // Compute the mean of the points. box.Center = points[0]; int i; for (i = 1; i < numPoints; ++i) { box.Center += points[i]; } Real invNumPoints = ((Real)1.0)/numPoints; box.Center *= invNumPoints; // Compute the covariance matrix of the points. Real sumXX = (Real)0, sumXY = (Real)0, sumXZ = (Real)0; Real sumYY = (Real)0, sumYZ = (Real)0, sumZZ = (Real)0; for (i = 0; i < numPoints; ++i) { Vector3<Real> diff = points[i] - box.Center; sumXX += diff[0]*diff[0]; sumXY += diff[0]*diff[1]; sumXZ += diff[0]*diff[2]; sumYY += diff[1]*diff[1]; sumYZ += diff[1]*diff[2]; sumZZ += diff[2]*diff[2]; } sumXX *= invNumPoints; sumXY *= invNumPoints; sumXZ *= invNumPoints; sumYY *= invNumPoints; sumYZ *= invNumPoints; sumZZ *= invNumPoints; // Setup the eigensolver. EigenDecomposition<Real> esystem(3); esystem(0,0) = sumXX; esystem(0,1) = sumXY; esystem(0,2) = sumXZ; esystem(1,0) = sumXY; esystem(1,1) = sumYY; esystem(1,2) = sumYZ; esystem(2,0) = sumXZ; esystem(2,1) = sumYZ; esystem(2,2) = sumZZ; esystem.Solve(true); for (i = 0; i < 3; ++i) { box.Extent[i] = esystem.GetEigenvalue(i); box.Axis[i] = esystem.GetEigenvector3(i); } return box; }
Plane3<Real> OrthogonalPlaneFit3 (int numPoints, const Vector3<Real>* points) { // Compute the mean of the points. Vector3<Real> origin = Vector3<Real>::ZERO; int i; for (i = 0; i < numPoints; i++) { origin += points[i]; } Real invNumPoints = ((Real)1)/numPoints; origin *= invNumPoints; // compute sums of products Real sumXX = (Real)0, sumXY = (Real)0, sumXZ = (Real)0; Real sumYY = (Real)0, sumYZ = (Real)0, sumZZ = (Real)0; for (i = 0; i < numPoints; ++i) { Vector3<Real> diff = points[i] - origin; sumXX += diff[0]*diff[0]; sumXY += diff[0]*diff[1]; sumXZ += diff[0]*diff[2]; sumYY += diff[1]*diff[1]; sumYZ += diff[1]*diff[2]; sumZZ += diff[2]*diff[2]; } sumXX *= invNumPoints; sumXY *= invNumPoints; sumXZ *= invNumPoints; sumYY *= invNumPoints; sumYZ *= invNumPoints; sumZZ *= invNumPoints; // Setup the eigensolver. EigenDecomposition<Real> esystem(3); esystem(0,0) = sumXX; esystem(0,1) = sumXY; esystem(0,2) = sumXZ; esystem(1,0) = sumXY; esystem(1,1) = sumYY; esystem(1,2) = sumYZ; esystem(2,0) = sumXZ; esystem(2,1) = sumYZ; esystem(2,2) = sumZZ; // Compute eigenstuff, smallest eigenvalue is in last position. esystem.Solve(false); // Get plane normal. Vector3<Real> normal = esystem.GetEigenvector3(2); // The minimum energy. return Plane3<Real>(normal, origin); }
static void cleanup(void) { static bool cleaning_up = FALSE; char cmd[1024]; int rc; if (!Option.cleanup || cleaning_up) return; stacktrace_err(); cleaning_up = TRUE; rc = snprintf(cmd, sizeof(cmd), "rm -fr %s", Option.dir); if (rc >= sizeof(cmd)) { eprintf("counldn't cleanup %s", cmd); } esystem(cmd); }
static int wdsheader(struct dm_buf *hdr, char *src, char *device, char **pkg, PKCS7 *sig) { FILE *fp; char path[PATH_MAX], tmp_entry[ENTRY_MAX], tmp_file[L_tmpnam+1]; char srcpath[PATH_MAX]; int i, n; int list_fd; int block_cnt; int len; char cwd[MAXPATHLEN + 1]; boolean_t making_sig = B_FALSE; making_sig = (sig != NULL) ? B_TRUE : B_FALSE; (void) ds_close(0); if (dstdev.pathname) ds_fd = creat(device, 0644); else ds_fd = open(device, 1); if (ds_fd < 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_OPEN), device, errno); return (1); } if (ds_ginit(device) < 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_OPEN), device, errno); (void) ds_close(0); return (1); } /* * The loop below assures compatibility with tapes that don't * have a block size (e.g.: Exabyte) by forcing EOR at the end * of each 512 bytes. */ for (block_cnt = 0; block_cnt < hdr->allocation; block_cnt += BLK_SIZE) { (void) write(ds_fd, (hdr->text_buffer + block_cnt), BLK_SIZE); } /* * write the first cpio() archive to the datastream * which should contain the pkginfo & pkgmap files * for all packages */ (void) tmpnam(tmp_file); /* temporary file name */ if ((list_fd = open(tmp_file, O_RDWR | O_CREAT, 0644)) == -1) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); return (1); } /* * Create a cpio-compatible list of the requisite files in * the temporary file. */ if (!making_sig) { for (i = 0; pkg[i]; i++) { register ssize_t entry_size; /* * Copy pkginfo and pkgmap filenames into the * temporary string allowing for the first line * as a special case. */ entry_size = sprintf(tmp_entry, (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s", pkg[i], PKGINFO, pkg[i], PKGMAP); if (write(list_fd, tmp_entry, entry_size) != entry_size) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); (void) close(list_fd); ecleanup(); return (1); } } } else { register ssize_t entry_size; /* * if we're making a signature, we must make a * temporary area full of symlinks to the requisite * files, plus an extra entry for the signature, so * that cpio will put all files and signature in the * same archive in a single invocation of cpio. */ tmpsymdir = xstrdup(tmpnam(NULL)); if (mkdir(tmpsymdir, S_IRWXU)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_MKDIR), tmpsymdir); return (1); } /* generate the signature */ if (((len = snprintf(path, PATH_MAX, "%s/%s", tmpsymdir, SIGNATURE_FILENAME)) >= PATH_MAX) || len < 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_NOTMPFIL), tmpsymdir); cleanup(); return (1); } if ((fp = fopen(path, "w")) == NULL) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_NOTMPFIL), path); cleanup(); return (1); } (void) PEM_write_PKCS7(fp, sig); (void) fclose(fp); for (i = 0; pkg[i]; i++) { (void) snprintf(path, sizeof (path), "%s/%s", tmpsymdir, pkg[i]); if (mkdir(path, 0755)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_MKDIR), path); cleanup(); return (1); } (void) snprintf(path, sizeof (path), "%s/%s/%s", tmpsymdir, pkg[i], PKGINFO); (void) snprintf(srcpath, sizeof (srcpath), "%s/%s/%s", src, pkg[i], PKGINFO); if (symlink(srcpath, path) != 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_SYMLINK), path, srcpath); cleanup(); return (1); } (void) snprintf(path, sizeof (path), "%s/%s/%s", tmpsymdir, pkg[i], PKGMAP); (void) snprintf(srcpath, sizeof (srcpath), "%s/%s/%s", src, pkg[i], PKGMAP); if (symlink(srcpath, path) != 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_SYMLINK), path, srcpath); cleanup(); return (1); } /* * Copy pkginfo and pkgmap filenames into the * temporary string allowing for the first line * as a special case. */ entry_size = snprintf(tmp_entry, sizeof (tmp_entry), (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s", pkg[i], PKGINFO, pkg[i], PKGMAP); if (write(list_fd, tmp_entry, entry_size) != entry_size) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); (void) close(list_fd); ecleanup(); cleanup(); return (1); } } /* add signature to list of files */ entry_size = snprintf(tmp_entry, sizeof (tmp_entry), "\n%s", SIGNATURE_FILENAME); if (write(list_fd, tmp_entry, entry_size) != entry_size) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); (void) close(list_fd); ecleanup(); cleanup(); return (1); } } (void) lseek(list_fd, 0, SEEK_SET); if (!making_sig) { (void) snprintf(tmp_entry, sizeof (tmp_entry), "%s -ocD -C %d", CPIOPROC, (int)BLK_SIZE); } else { /* * when making a signature, we must make sure to follow * symlinks during the cpio so that we don't archive * the links themselves */ (void) snprintf(tmp_entry, sizeof (tmp_entry), "%s -ocDL -C %d", CPIOPROC, (int)BLK_SIZE); } if (making_sig) { /* save cwd and change to symlink dir for cpio invocation */ if (getcwd(cwd, MAXPATHLEN + 1) == NULL) { logerr(pkg_gt(ERR_GETWD)); progerr(pkg_gt(ERR_TRANSFER)); cleanup(); return (1); } if (chdir(tmpsymdir)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_CHDIR), tmpsymdir); cleanup(); return (1); } } if (n = esystem(tmp_entry, list_fd, ds_fd)) { rpterr(); progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_CMDFAIL), tmp_entry, n); (void) close(list_fd); (void) unlink(tmp_file); cleanup(); return (1); } (void) close(list_fd); (void) unlink(tmp_file); if (making_sig) { /* change to back to src dir for subsequent operations */ if (chdir(cwd)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_CHDIR), cwd); cleanup(); return (1); } } return (0); }
static int pkgxfer(char *srcinst, int options) { int r; struct pkginfo info; FILE *fp, *pp; char *pt, *src, *dst; char dstdir[PATH_MAX], temp[PATH_MAX], srcdir[PATH_MAX], cmd[CMDSIZE], pkgname[NON_ABI_NAMELNGTH]; int i, n, part, nparts, maxpartsize, curpartcnt, iscomp; char volnos[128], tmpvol[128]; struct statvfs64 svfsb; longlong_t free_blocks; struct stat srcstat; info.pkginst = NULL; /* required initialization */ /* * when this routine is entered, the first part of * the package to transfer is already available in * the directory indicated by 'src' --- unless the * source device is a datstream, in which case only * the pkginfo and pkgmap files are available in 'src' */ src = srcdev.dirname; dst = dstdev.dirname; if (!(options & PT_SILENT)) (void) fprintf(stderr, pkg_gt(MSG_TRANSFER), srcinst); (void) strlcpy(dstinst, srcinst, sizeof (dstinst)); if (!(options & PT_ODTSTREAM)) { /* destination is a (possibly mounted) directory */ (void) snprintf(dstdir, sizeof (dstdir), "%s/%s", dst, dstinst); /* * need to check destination directory to assure * that we will not be duplicating a package which * already resides there (though we are allowed to * overwrite the same version) */ pkgdir = src; if (fpkginfo(&info, srcinst)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_NOEXISTS), srcinst); (void) fpkginfo(&info, NULL); return (1); } pkgdir = dst; (void) strlcpy(temp, srcinst, sizeof (temp)); if (pt = strchr(temp, '.')) *pt = '\0'; (void) strlcat(temp, ".*", sizeof (temp)); if (pt = fpkginst(temp, info.arch, info.version)) { /* * the same instance already exists, although * its pkgid might be different */ if (options & PT_OVERWRITE) { (void) strlcpy(dstinst, pt, sizeof (dstinst)); (void) snprintf(dstdir, sizeof (dstdir), "%s/%s", dst, dstinst); } else { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_DUPVERS), srcinst); (void) fpkginfo(&info, NULL); (void) fpkginst(NULL); return (2); } } else if (options & PT_RENAME) { /* * find next available instance by appending numbers * to the package abbreviation until the instance * does not exist in the destination directory */ if (pt = strchr(temp, '.')) *pt = '\0'; for (i = 2; (access(dstdir, 0) == 0); i++) { (void) snprintf(dstinst, sizeof (dstinst), "%s.%d", temp, i); (void) snprintf(dstdir, sizeof (dstdir), "%s/%s", dst, dstinst); } } else if (options & PT_OVERWRITE) { /* * we're allowed to overwrite, but there seems * to be no valid package to overwrite, and we are * not allowed to rename the destination, so act * as if we weren't given permission to overwrite * --- this keeps us from removing a destination * instance which is named the same as the source * instance, but really reflects a different pkg! */ options &= (~PT_OVERWRITE); } (void) fpkginfo(&info, NULL); (void) fpkginst(NULL); if (ckoverwrite(dst, dstinst, options)) return (2); if (isdir(dstdir) && mkdir(dstdir, 0755)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_MKDIR), dstdir); return (1); } (void) snprintf(srcdir, sizeof (srcdir), "%s/%s", src, srcinst); if (stat(srcdir, &srcstat) != -1) { if (chmod(dstdir, (srcstat.st_mode & S_IAMB)) == -1) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_CHMODDIR), dstdir); return (1); } } else { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_STATDIR), srcdir); return (1); } } if (!(options & PT_SILENT) && strcmp(dstinst, srcinst)) (void) fprintf(stderr, pkg_gt(MSG_RENAME), dstinst); (void) snprintf(srcdir, sizeof (srcdir), "%s/%s", src, srcinst); if (chdir(srcdir)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_CHDIR), srcdir); return (1); } if (ids_name) { /* unpack the datatstream into a directory */ /* * transfer pkginfo & pkgmap first */ (void) snprintf(cmd, sizeof (cmd), "%s -pudm %s", CPIOPROC, dstdir); if ((pp = epopen(cmd, "w")) == NULL) { rpterr(); progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_POPEN), cmd, errno); return (1); } (void) fprintf(pp, "%s\n%s\n", PKGINFO, PKGMAP); (void) sighold(SIGINT); (void) sighold(SIGHUP); r = epclose(pp); (void) sigrelse(SIGINT); (void) sigrelse(SIGHUP); if (r != 0) { rpterr(); progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_PCLOSE), cmd, errno); return (1); } if (options & PT_INFO_ONLY) return (0); /* don't transfer objects */ if (chdir(dstdir)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_CHDIR), dstdir); return (1); } /* * for each part of the package, use cpio() to * unpack the archive into the destination directory */ nparts = ds_findpkg(srcdev.cdevice, srcinst); if (nparts < 0) { progerr(pkg_gt(ERR_TRANSFER)); return (1); } for (part = 1; part <= nparts; /* void */) { if (ds_getpkg(srcdev.cdevice, part, dstdir)) { progerr(pkg_gt(ERR_TRANSFER)); return (1); } part++; if (dstdev.mount) { (void) chdir("/"); if (pkgumount(&dstdev)) return (1); if (part <= nparts) { if (n = pkgmount(&dstdev, NULL, part+1, nparts, 1)) return (n); if (ckoverwrite(dst, dstinst, options)) return (1); if (isdir(dstdir) && mkdir(dstdir, 0755)) { progerr( pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_MKDIR), dstdir); return (1); } /* * since volume is removable, each part * must contain a duplicate of the * pkginfo file to properly identify the * volume */ if (chdir(srcdir)) { progerr( pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_CHDIR), srcdir); return (1); } if ((pp = epopen(cmd, "w")) == NULL) { rpterr(); progerr( pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_POPEN), cmd, errno); return (1); } (void) fprintf(pp, "pkginfo"); (void) sighold(SIGINT); (void) sighold(SIGHUP); r = epclose(pp); (void) sigrelse(SIGINT); (void) sigrelse(SIGHUP); if (r != 0) { rpterr(); progerr( pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_PCLOSE), cmd, errno); return (1); } if (chdir(dstdir)) { progerr( pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_CHDIR), dstdir); return (1); } } } } return (0); } if ((fp = fopen(PKGMAP, "r")) == NULL) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_NOPKGMAP), srcinst); return (1); } nparts = 1; if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize)) return (1); else (void) fclose(fp); if (srcdev.mount) { if (ckvolseq(srcdir, 1, nparts)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_SEQUENCE)); return (1); } } /* write each part of this package */ if (options & PT_ODTSTREAM) { char line[128]; (void) mgets(line, 128); curpartcnt = -1; /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ if (sscanf(line, "%s %d %d %[ 0-9]", pkgname, &nparts, &maxpartsize, volnos) == 4) { (void) sscanf(volnos, "%d %[ 0-9]", &curpartcnt, tmpvol); (void) strlcpy(volnos, tmpvol, sizeof (volnos)); } } for (part = 1; part <= nparts; /* void */) { if (curpartcnt == 0 && (options & PT_ODTSTREAM)) { char prompt[128]; int index; ds_volno++; (void) ds_close(0); (void) sprintf(prompt, pkg_gt("Insert %%v %d of %d into %%p"), ds_volno, ds_volcnt); if (n = getvol(ods_name, NULL, DM_FORMAT, prompt)) return (n); if ((ds_fd = open(dstdev.cdevice, O_WRONLY)) < 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_OPEN), dstdev.cdevice, errno); return (1); } if (ds_ginit(dstdev.cdevice) < 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_OPEN), dstdev.cdevice, errno); (void) ds_close(0); return (1); } (void) sscanf(volnos, "%d %[ 0-9]", &index, tmpvol); (void) strlcpy(volnos, tmpvol, sizeof (volnos)); curpartcnt += index; } if (options & PT_INFO_ONLY) nparts = 0; if (part == 1) { (void) snprintf(cmd, sizeof (cmd), "find %s %s", PKGINFO, PKGMAP); if (nparts && (isdir(INSTALL) == 0)) { (void) strlcat(cmd, " ", sizeof (cmd)); (void) strlcat(cmd, INSTALL, sizeof (cmd)); } } else (void) snprintf(cmd, sizeof (cmd), "find %s", PKGINFO); if (nparts > 1) { (void) snprintf(temp, sizeof (temp), "%s.%d", RELOC, part); if (iscpio(temp, &iscomp) || isdir(temp) == 0) { (void) strlcat(cmd, " ", sizeof (cmd)); (void) strlcat(cmd, temp, sizeof (cmd)); } (void) snprintf(temp, sizeof (temp), "%s.%d", ROOT, part); if (iscpio(temp, &iscomp) || isdir(temp) == 0) { (void) strlcat(cmd, " ", sizeof (cmd)); (void) strlcat(cmd, temp, sizeof (cmd)); } (void) snprintf(temp, sizeof (temp), "%s.%d", ARCHIVE, part); if (isdir(temp) == 0) { (void) strlcat(cmd, " ", sizeof (cmd)); (void) strlcat(cmd, temp, sizeof (cmd)); } } else if (nparts) { for (i = 0; reloc_names[i] != NULL; i++) { if (iscpio(reloc_names[i], &iscomp) || isdir(reloc_names[i]) == 0) { (void) strlcat(cmd, " ", sizeof (cmd)); (void) strlcat(cmd, reloc_names[i], sizeof (cmd)); } } for (i = 0; root_names[i] != NULL; i++) { if (iscpio(root_names[i], &iscomp) || isdir(root_names[i]) == 0) { (void) strlcat(cmd, " ", sizeof (cmd)); (void) strlcat(cmd, root_names[i], sizeof (cmd)); } } if (isdir(ARCHIVE) == 0) { (void) strlcat(cmd, " ", sizeof (cmd)); (void) strlcat(cmd, ARCHIVE, sizeof (cmd)); } } if (options & PT_ODTSTREAM) { (void) snprintf(cmd + strlen(cmd), sizeof (cmd) - strlen(cmd), " -print | %s -ocD -C %d", CPIOPROC, (int)BLK_SIZE); } else { if (statvfs64(dstdir, &svfsb) == -1) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_STATVFS), dstdir, errno); return (1); } free_blocks = (((long)svfsb.f_frsize > 0) ? howmany(svfsb.f_frsize, DEV_BSIZE) : howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bavail; if ((has_comp_size ? compressedsize : maxpartsize) > free_blocks) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_NOSPACE), has_comp_size ? (long)compressedsize : (long)maxpartsize, free_blocks); return (1); } (void) snprintf(cmd + strlen(cmd), sizeof (cmd) - strlen(cmd), " -print | %s -pdum %s", CPIOPROC, dstdir); } n = esystem(cmd, -1, (options & PT_ODTSTREAM) ? ds_fd : -1); if (n) { rpterr(); progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_CMDFAIL), cmd, n); return (1); } part++; if (srcdev.mount && (nparts > 1)) { /* unmount current source volume */ (void) chdir("/"); if (pkgumount(&srcdev)) return (1); /* loop until volume is mounted successfully */ while (part <= nparts) { /* read only */ n = pkgmount(&srcdev, NULL, part, nparts, 1); if (n) return (n); if (chdir(srcdir)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_CORRUPT)); (void) chdir("/"); (void) pkgumount(&srcdev); continue; } if (ckvolseq(srcdir, part, nparts)) { (void) chdir("/"); (void) pkgumount(&srcdev); continue; } break; } } if (!(options & PT_ODTSTREAM) && dstdev.mount) { /* unmount current volume */ if (pkgumount(&dstdev)) return (1); /* loop until next volume is mounted successfully */ while (part <= nparts) { /* writable */ n = pkgmount(&dstdev, NULL, part, nparts, 1); if (n) return (n); if (ckoverwrite(dst, dstinst, options)) continue; if (isdir(dstdir) && mkdir(dstdir, 0755)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_MKDIR), dstdir); continue; } break; } } if ((options & PT_ODTSTREAM) && part <= nparts) { if (curpartcnt >= 0 && part > curpartcnt) { char prompt[128]; int index; ds_volno++; if (ds_close(0)) return (1); (void) sprintf(prompt, pkg_gt("Insert %%v %d of %d into %%p"), ds_volno, ds_volcnt); if (n = getvol(ods_name, NULL, DM_FORMAT, prompt)) return (n); if ((ds_fd = open(dstdev.cdevice, 1)) < 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_OPEN), dstdev.cdevice, errno); return (1); } if (ds_ginit(dstdev.cdevice) < 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_OPEN), dstdev.cdevice, errno); (void) ds_close(0); return (1); } (void) sscanf(volnos, "%d %[ 0-9]", &index, tmpvol); (void) strlcpy(volnos, tmpvol, sizeof (volnos)); curpartcnt += index; } } } return (0); }
Vector3<Real> GreatCircleFit3 (int numPoints, const Vector3<Real>* points) { // Compute the covariance matrix of the vectors. Real sumXX = (Real)0, sumXY = (Real)0, sumXZ = (Real)0; Real sumYY = (Real)0, sumYZ = (Real)0, sumZZ = (Real)0; for (int i = 0; i < numPoints; i++) { Vector3<Real> diff = points[i]; sumXX += diff[0]*diff[0]; sumXY += diff[0]*diff[1]; sumXZ += diff[0]*diff[2]; sumYY += diff[1]*diff[1]; sumYZ += diff[1]*diff[2]; sumZZ += diff[2]*diff[2]; } Real invNumPoints = ((Real)1)/numPoints; sumXX *= invNumPoints; sumXY *= invNumPoints; sumXZ *= invNumPoints; sumYY *= invNumPoints; sumYZ *= invNumPoints; sumZZ *= invNumPoints; // Set up the eigensolver. EigenDecomposition<Real> esystem(3); esystem(0,0) = sumXX; esystem(0,1) = sumXY; esystem(0,2) = sumXZ; esystem(1,0) = esystem(0,1); esystem(1,1) = sumYY; esystem(1,2) = sumYZ; esystem(2,0) = esystem(0,2); esystem(2,1) = esystem(1,2); esystem(2,2) = sumZZ; // Compute eigenstuff; the smallest eigenvalue is in last position. esystem.Solve(false); // Unit-length direction for best-fit great circle. Vector3<Real> normal = esystem.GetEigenvector3(2); return normal; }
Real QuadraticFit3 (int numPoints, const Vector3<Real>* points, Real coeff[10]) { EigenDecomposition<Real> esystem(10); int row, col; for (row = 0; row < 10; ++row) { for (col = 0; col < 10; ++col) { esystem(row,col) = (Real)0; } } for (int i = 0; i < numPoints; ++i) { Real x = points[i].X(); Real y = points[i].Y(); Real z = points[i].Z(); Real x2 = x*x; Real y2 = y*y; Real z2 = z*z; Real xy = x*y; Real xz = x*z; Real yz = y*z; Real x3 = x*x2; Real xy2 = x*y2; Real xz2 = x*z2; Real x2y = x*xy; Real x2z = x*xz; Real xyz = x*y*z; Real y3 = y*y2; Real yz2 = y*z2; Real y2z = y*yz; Real z3 = z*z2; Real fX4 = x*x3; Real x2y2 = x*xy2; Real x2z2 = x*xz2; Real x3y = x*x2y; Real x3z = x*x2z; Real x2yz = x*xyz; Real y4 = y*y3; Real y2z2 = y*yz2; Real xy3 = x*y3; Real xy2z = x*y2z; Real y3z = y*y2z; Real fZ4 = z*z3; Real xyz2 = x*yz2; Real xz3 = x*z3; Real yz3 = y*z3; esystem(0,1) += x; esystem(0,2) += y; esystem(0,3) += z; esystem(0,4) += x2; esystem(0,5) += y2; esystem(0,6) += z2; esystem(0,7) += xy; esystem(0,8) += xz; esystem(0,9) += yz; esystem(1,4) += x3; esystem(1,5) += xy2; esystem(1,6) += xz2; esystem(1,7) += x2y; esystem(1,8) += x2z; esystem(1,9) += xyz; esystem(2,5) += y3; esystem(2,6) += yz2; esystem(2,9) += y2z; esystem(3,6) += z3; esystem(4,4) += fX4; esystem(4,5) += x2y2; esystem(4,6) += x2z2; esystem(4,7) += x3y; esystem(4,8) += x3z; esystem(4,9) += x2yz; esystem(5,5) += y4; esystem(5,6) += y2z2; esystem(5,7) += xy3; esystem(5,8) += xy2z; esystem(5,9) += y3z; esystem(6,6) += fZ4; esystem(6,7) += xyz2; esystem(6,8) += xz3; esystem(6,9) += yz3; esystem(9,9) += y2z2; } esystem(0,0) = (Real)numPoints; esystem(1,1) = esystem(0,4); esystem(1,2) = esystem(0,7); esystem(1,3) = esystem(0,8); esystem(2,2) = esystem(0,5); esystem(2,3) = esystem(0,9); esystem(2,4) = esystem(1,7); esystem(2,7) = esystem(1,5); esystem(2,8) = esystem(1,9); esystem(3,3) = esystem(0,6); esystem(3,4) = esystem(1,8); esystem(3,5) = esystem(2,9); esystem(3,7) = esystem(1,9); esystem(3,8) = esystem(1,6); esystem(3,9) = esystem(2,6); esystem(7,7) = esystem(4,5); esystem(7,8) = esystem(4,9); esystem(7,9) = esystem(5,8); esystem(8,8) = esystem(4,6); esystem(8,9) = esystem(6,7); esystem(9,9) = esystem(5,6); for (row = 0; row < 10; ++row) { for (col = 0; col < row; ++col) { esystem(row,col) = esystem(col,row); } } Real invNumPoints = ((Real)1)/(Real)numPoints; for (row = 0; row < 10; ++row) { for (col = 0; col < 10; ++col) { esystem(row,col) *= invNumPoints; } } esystem.Solve(true); GVector<Real> evector = esystem.GetEigenvector(0); memcpy(coeff, (Real*)evector, 10*sizeof(Real)); // For an exact fit, numeric round-off errors might make the minimum // eigenvalue just slightly negative. Return the absolute value since // the application might rely on the return value being nonnegative. return Math<Real>::FAbs(esystem.GetEigenvalue(0)); }
Real QuadraticSphereFit3 (int numPoints, const Vector3<Real>* points, Vector3<Real>& center, Real& radius) { EigenDecomposition<Real> esystem(5); int row, col; for (row = 0; row < 5; ++row) { for (col = 0; col < 5; ++col) { esystem(row,col) = (Real)0; } } for (int i = 0; i < numPoints; ++i) { Real x = points[i].X(); Real y = points[i].Y(); Real z = points[i].Z(); Real x2 = x*x; Real y2 = y*y; Real z2 = z*z; Real xy = x*y; Real xz = x*z; Real yz = y*z; Real r2 = x2+y2+z2; Real xr2 = x*r2; Real yr2 = y*r2; Real zr2 = z*r2; Real r4 = r2*r2; esystem(0,1) += x; esystem(0,2) += y; esystem(0,3) += z; esystem(0,4) += r2; esystem(1,1) += x2; esystem(1,2) += xy; esystem(1,3) += xz; esystem(1,4) += xr2; esystem(2,2) += y2; esystem(2,3) += yz; esystem(2,4) += yr2; esystem(3,3) += z2; esystem(3,4) += zr2; esystem(4,4) += r4; } esystem(0,0) = (Real)numPoints; for (row = 0; row < 5; ++row) { for (col = 0; col < row; ++col) { esystem(row,col) = esystem(col,row); } } Real invNumPoints = ((Real)1)/(Real)numPoints; for (row = 0; row < 5; ++row) { for (col = 0; col < 5; ++col) { esystem(row,col) *= invNumPoints; } } esystem.Solve(true); GVector<Real> evector = esystem.GetEigenvector(0); Real inv = ((Real)1)/evector[4]; // beware zero divide Real coeff[4]; for (row = 0; row < 4; ++row) { coeff[row] = inv*evector[row]; } center[0] = -((Real)0.5)*coeff[1]; center[1] = -((Real)0.5)*coeff[2]; center[2] = -((Real)0.5)*coeff[3]; radius = Math<Real>::Sqrt(Math<Real>::FAbs(center[0]*center[0] + center[1]*center[1] + center[2]*center[2] - coeff[0])); // For an exact fit, numeric round-off errors might make the minimum // eigenvalue just slightly negative. Return the absolute value since // the application might rely on the return value being nonnegative. return Math<Real>::FAbs(esystem.GetEigenvalue(0)); }
Line3<Real> OrthogonalLineFit3 (int numPoints, const Vector3<Real>* points) { Line3<Real> line(Vector3<Real>::ZERO, Vector3<Real>::ZERO); // Compute the mean of the points. line.Origin = points[0]; int i; for (i = 1; i < numPoints; i++) { line.Origin += points[i]; } Real invNumPoints = ((Real)1)/numPoints; line.Origin *= invNumPoints; // Compute the covariance matrix of the points. Real sumXX = (Real)0, sumXY = (Real)0, sumXZ = (Real)0; Real sumYY = (Real)0, sumYZ = (Real)0, sumZZ = (Real)0; for (i = 0; i < numPoints; i++) { Vector3<Real> diff = points[i] - line.Origin; sumXX += diff[0]*diff[0]; sumXY += diff[0]*diff[1]; sumXZ += diff[0]*diff[2]; sumYY += diff[1]*diff[1]; sumYZ += diff[1]*diff[2]; sumZZ += diff[2]*diff[2]; } sumXX *= invNumPoints; sumXY *= invNumPoints; sumXZ *= invNumPoints; sumYY *= invNumPoints; sumYZ *= invNumPoints; sumZZ *= invNumPoints; // Set up the eigensolver. EigenDecomposition<Real> esystem(3); esystem(0,0) = sumYY+sumZZ; esystem(0,1) = -sumXY; esystem(0,2) = -sumXZ; esystem(1,0) = esystem(0,1); esystem(1,1) = sumXX+sumZZ; esystem(1,2) = -sumYZ; esystem(2,0) = esystem(0,2); esystem(2,1) = esystem(1,2); esystem(2,2) = sumXX+sumYY; // Compute eigenstuff, smallest eigenvalue is in last position. esystem.Solve(false); // Unit-length direction for best-fit line. line.Direction = esystem.GetEigenvector3(2); return line; }