double Geo3d_Line_Line_Dist(double line1_start[], double line1_end[], double line2_start[], double line2_end[]) { double intersect1, intersect2; double dc1[3], dc2[3]; double lamda; switch (geo3d_line_line_dist(line1_start, line1_end, line2_start, line2_end, dc1, dc2, &intersect1, &intersect2, TZ_DIST_3D_EPS)) { case -3: /* point to point */ return Geo3d_Dist(line1_start[0], line1_start[1], line1_start[2], line2_start[0], line2_start[1], line2_start[2]); case -1: /* point to line2 */ geo3d_point_line_dist(line1_start, line2_start, line2_end, &lamda, TZ_DIST_3D_EPS); return Geo3d_Dist(line1_start[0], line1_start[1], line1_start[2], line2_start[0] + lamda * dc2[0], line2_start[1] + lamda * dc2[1], line2_start[2] + lamda * dc2[2]); case -2: /* point to line 1 */ geo3d_point_line_dist(line2_start, line1_start, line1_end, &lamda, TZ_DIST_3D_EPS); return Geo3d_Dist(line2_start[0], line2_start[1], line2_start[2], line1_start[0] + lamda * dc1[0], line1_start[1] + lamda * dc1[1], line1_start[2] + lamda * dc1[2]); case 0: /* parallel */ geo3d_point_line_dist(line1_start, line2_start, line2_end, &lamda, TZ_DIST_3D_EPS); return Geo3d_Dist(line1_start[0], line1_start[1], line1_start[2], line2_start[0] + lamda * dc2[0], line2_start[1] + lamda * dc2[1], line2_start[2] + lamda * dc2[2]); default: /* line to line */ return sqrt(Geo3d_Dist_Sqr(line1_start[0] + intersect1 * dc1[0], line1_start[1] + intersect1 * dc1[1], line1_start[2] + intersect1 * dc1[2], line2_start[0] + intersect2 * dc2[0], line2_start[1] + intersect2 * dc2[1], line2_start[2] + intersect2 * dc2[2])); } }
double Geo3d_Point_Lineseg_Dist(const double *point, const double *line_start, const double *line_end, double *lamda) { double tmp_lamda; int status = geo3d_point_line_dist(point, line_start, line_end, &tmp_lamda, GEO3D_POINT_LINESEG_EPS); double dist; if (status == 0) { dist = Geo3d_Dist(line_start[0], line_start[1], line_start[2], point[0], point[1], point[2]); } else { if ((tmp_lamda >= 0.0) && (tmp_lamda <= 1.0)) { dist = Geo3d_Dist(point[0], point[1], point[2], (1.0 - tmp_lamda) * line_start[0] + tmp_lamda * line_end[0], (1.0 - tmp_lamda) * line_start[1] + tmp_lamda * line_end[1], (1.0 - tmp_lamda) * line_start[2] + tmp_lamda * line_end[2]); } else if (tmp_lamda < 0.0) { tmp_lamda = 0.0; dist = sqrt(Geo3d_Dist_Sqr(line_start[0], line_start[1], line_start[2], point[0], point[1], point[2])); } else { tmp_lamda = 1.0; dist = sqrt(Geo3d_Dist_Sqr(line_end[0], line_end[1], line_end[2], point[0], point[1], point[2])); } } /* double line_vec[3]; double point_vec[3]; int i; for (i = 0; i < 3; i++) { line_vec[i] = line_end[i] - line_start[i]; point_vec[i] = point[i] - line_start[i]; } double length_sqr = Geo3d_Orgdist_Sqr(line_vec[0], line_vec[1], line_vec[2]); double tmp_lamda = 0.0; double dist = -1.0; if (length_sqr <= GEO3D_POINT_LINESEG_EPS) { dist = sqrt(Geo3d_Dist_Sqr(line_start[0], line_start[1], line_start[2], point[0], point[1], point[2])); } else { double dot = point_vec[0] * line_vec[0] + point_vec[1] * line_vec[1] + point_vec[2] * line_vec[2]; double point_vec_lensqr = Geo3d_Orgdist_Sqr(point_vec[0], point_vec[1], point_vec[2]); if (point_vec_lensqr <= GEO3D_POINT_LINESEG_EPS) { dist = 0.0; } else { tmp_lamda = dot / length_sqr; if ((tmp_lamda >= 0.0) && (tmp_lamda <= 1.0)) { dist = sqrt(point_vec_lensqr - dot * dot / length_sqr); } else if (tmp_lamda < 0.0) { dist = sqrt(Geo3d_Dist_Sqr(line_start[0], line_start[1], line_start[2], point[0], point[1], point[2])); } else { dist = sqrt(Geo3d_Dist_Sqr(line_end[0], line_end[1], line_end[2], point[0], point[1], point[2])); } } } */ if (lamda != NULL) { *lamda = tmp_lamda; } return dist; }
double Geo3d_Lineseg_Lineseg_Dist(double line1_start[], double line1_end[], double line2_start[], double line2_end[], double *intersect1, double *intersect2, int *cond) { double dc1[3]; /*21*/ double dc2[3]; /*43*/ double d1, d2; switch (geo3d_line_line_dist(line1_start, line1_end, line2_start, line2_end, dc1, dc2, intersect1, intersect2, TZ_DIST_3D_EPS)) { case 0: /* parallel */ *cond = 9; d1 = Geo3d_Point_Lineseg_Dist(line1_end, line2_start, line2_end, intersect1); d2 = Geo3d_Point_Lineseg_Dist(line1_start, line2_start, line2_end, intersect2); if (d1 <= d2) { *intersect2 = *intersect1; *intersect1 = 1.0; return d1; } else { *intersect1 = 0.0; return d2; } case -1: *intersect1 = 0.0; *cond = 10; return Geo3d_Point_Lineseg_Dist(line1_start, line2_start, line2_end, intersect2); case -2: *intersect2= 0.0; *cond = 10; return Geo3d_Point_Lineseg_Dist(line2_start, line1_start, line1_end, intersect1); case -3: *cond = 10; *intersect1 = 0.0; *intersect2 = 0.0; return Geo3d_Dist(line1_start[0], line1_start[1], line1_start[2], line2_start[0], line2_start[1], line2_start[2]); default: #if defined BREAK_IS_IN_RANGE # undef BREAK_IS_IN_RANGE #endif #define BREAK_IS_IN_RANGE(mu) ((mu >= 0.0) && (mu <= 1.0)) if (BREAK_IS_IN_RANGE(*intersect1) && BREAK_IS_IN_RANGE(*intersect2)) { *cond = 0; return sqrt(Geo3d_Dist_Sqr(line1_start[0] + *intersect1 * dc1[0], line1_start[1] + *intersect1 * dc1[1], line1_start[2] + *intersect1 * dc1[2], line2_start[0] + *intersect2 * dc2[0], line2_start[1] + *intersect2 * dc2[1], line2_start[2] + *intersect2 * dc2[2])); } else if ((*intersect1 < 0.0) && BREAK_IS_IN_RANGE(*intersect2)) { *cond = 1; *intersect1 = 0.0; return Geo3d_Point_Lineseg_Dist(line1_start, line2_start, line2_end, intersect2); } else if ((*intersect1 > 0.0) && BREAK_IS_IN_RANGE(*intersect2)) { *cond = 2; *intersect1 = 1.0; return Geo3d_Point_Lineseg_Dist(line1_end, line2_start, line2_end, intersect2); } else if ((*intersect2 < 0.0) && BREAK_IS_IN_RANGE(*intersect1)) { *cond = 3; *intersect2 = 0.0; return Geo3d_Point_Lineseg_Dist(line2_start, line1_start, line1_end, intersect1); } else if ((*intersect2 > 1.0) && BREAK_IS_IN_RANGE(*intersect1)) { *cond = 4; *intersect2 = 1.0; return Geo3d_Point_Lineseg_Dist(line2_end, line1_start, line1_end, intersect1); } else if ((*intersect1 < 0.0) && (*intersect2 < 0.0)) { *cond = 5; d1 = Geo3d_Point_Lineseg_Dist(line1_start, line2_start, line2_end, intersect2); d2 = Geo3d_Point_Lineseg_Dist(line2_start, line1_start, line1_end, intersect1); if (d1 <= d2) { *intersect1 = 0.0; return d1; } else { *intersect2 = 0.0; return d2; } } else if ((*intersect1 > 1.0) && (*intersect2 < 0.0)) { *cond = 6; d1 = Geo3d_Point_Lineseg_Dist(line1_end, line2_start, line2_end, intersect2); d2 = Geo3d_Point_Lineseg_Dist(line2_start, line1_start, line1_end, intersect1); if (d1 <= d2) { *intersect1 = 1.0; return d1; } else { *intersect2 = 0.0; return d2; } } else if ((*intersect1 < 0.0) && (*intersect2 > 1.0)) { *cond = 7; d1 = Geo3d_Point_Lineseg_Dist(line1_start, line2_start, line2_end, intersect2); d2 = Geo3d_Point_Lineseg_Dist(line2_end, line1_start, line1_end, intersect1); if (d1 <= d2) { *intersect1 = 0.0; return d1; } else { *intersect2 = 1.0; return d2; } } else if ((*intersect1 > 1.0) && (*intersect2 > 1.0)) { *cond = 8; d1 = Geo3d_Point_Lineseg_Dist(line1_end, line2_start, line2_end, intersect2); d2 = Geo3d_Point_Lineseg_Dist(line2_end, line1_start, line1_end, intersect1); if (d1<= d2) { *intersect1 = 1.0; return d1; } else { *intersect2 = 1.0; return d2; } } } return -1.0; }
int main(int argc, char *argv[]) { static char *Spec[] = {"[-t]", NULL}; Process_Arguments(argc, argv, Spec, 1); if (Is_Arg_Matched("-t")) { coordinate_3d_t coord = {0, 0, 0}; /* Translate coordinates. */ Geo3d_Translate_Coordinate(coord, coord+1, coord+2, 1.0, 2.0, 3.0); if ((coord[0] != 1.0) || (coord[1] != 2.0) || (coord[2] != 3.0)) { Print_Coordinate_3d(coord); PRINT_EXCEPTION(":( Bug?", "Unexpected coordinate values."); return 1; } coordinate_3d_t coord2 = {0, 0, 0}; double dx, dy, dz; Geo3d_Coordinate_Offset(coord[0], coord[1], coord[2], coord2[0], coord2[1], coord2[2], &dx, &dy, &dz); if ((dx != -coord[0]) || (dy != -coord[1]) || (dz != -coord[2])) { PRINT_EXCEPTION(":( Bug?", "Unexpected offset values."); return 1; } Coordinate_3d_Copy(coord2, coord); /* Rotate coordinates. */ Geo3d_Rotate_Coordinate(coord, coord+1, coord+2, 0.1, 0.5, 0); if (fabs(Geo3d_Orgdist_Sqr(coord[0], coord[1], coord[2]) - Geo3d_Orgdist_Sqr(coord2[0], coord2[1], coord2[2])) > 0.01) { PRINT_EXCEPTION(":( Bug?", "Rotation failed."); return 1; } /* inverse rotation */ Geo3d_Rotate_Coordinate(coord, coord+1, coord+2, 0.1, 0.5, 1); if ((fabs(coord[0] - coord2[0]) > 0.01) || (fabs(coord[1] - coord2[1]) > 0.01) || (fabs(coord[2] - coord2[2]) > 0.01)){ PRINT_EXCEPTION(":( Bug?", "Rotation failed."); return 1; } /* Normal vector of an orientation. This is a canonical representaion * of an orientation. */ Geo3d_Orientation_Normal(0.1, 0.5, coord, coord+1, coord+2); /* We can also turn the normal vector into orientation. */ double theta, psi; Geo3d_Normal_Orientation(coord[0], coord[1], coord[2], &theta, &psi); if (fabs(theta - 0.1) > 0.01 || fabs(Normalize_Radian(psi) - 0.5) > 0.01) { printf("%g, %g\n", theta, psi); PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values."); return 1; } /* If we rotate the vector back, we should get (0, 0, 1). */ Geo3d_Rotate_Coordinate(coord, coord+1, coord+2, 0.1, 0.5, 1); if ((fabs(coord[0]) > 0.01) || (fabs(coord[1]) > 0.01) || (fabs(coord[2] - 1.0) > 0.01)){ PRINT_EXCEPTION(":( Bug?", "Rotation failed."); return 1; } Geo3d_Coord_Orientation(1, 0, 0, &theta, &psi); double in[3] = {0, 0, 1}; double out[3] = {0, 0, 0}; Rotate_XZ(in, out, 1, theta, psi, 0); if (fabs(out[0] - 1.0) > 0.01 || fabs(out[1]) > 0.01 || fabs(out[2]) > 0.01) { printf("%g, %g, %g\n", out[0], out[1], out[2]); printf("%g, %g\n", theta, psi); PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values."); return 1; } /* if (fabs(theta - TZ_PI_2) > 0.01 || fabs(Normalize_Radian(psi) - TZ_PI_2) > 0.01) { printf("%g, %g\n", theta, psi); PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values."); return 1; } */ Geo3d_Coord_Orientation(5, 0, 0, &theta, &psi); { double in[3] = {0, 0, 5}; double out[3] = {0, 0, 0}; Rotate_XZ(in, out, 1, theta, psi, 0); if (fabs(out[0] - 5.0) > 0.01 || fabs(out[1]) > 0.01 || fabs(out[2]) > 0.01) { printf("%g, %g, %g\n", out[0], out[1], out[2]); printf("%g, %g\n", theta, psi); PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values."); return 1; } } /* if (fabs(theta - TZ_PI_2) > 0.01 || fabs(Normalize_Radian(psi) - TZ_PI_2) > 0.01) { printf("%g, %g\n", theta, psi); PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values."); return 1; } */ /* Rotate the orientation. */ theta = TZ_PI_2; psi = TZ_PI; Geo3d_Rotate_Orientation(-TZ_PI, TZ_PI_2, &theta, &psi); if (fabs(theta + TZ_PI_2) > 0.01 || fabs(psi + TZ_PI_2) > 0.01) { printf("%g, %g\n", theta, psi); PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values."); return 1; } /* More extensive test on rotation */ Random_Seed(time(NULL) - getpid()); int i; for (i = 0; i < 100; i++) { double x = Unifrnd() * (1 - Bernrnd(0.5) * 2.0); double y = Unifrnd() * (1 - Bernrnd(0.5) * 2.0); double z = Unifrnd() * (1 - Bernrnd(0.5) * 2.0); double theta, psi; Geo3d_Coord_Orientation(x, y, z, &theta, &psi); double x2 = 0.0; double y2 = 0.0; double z2 = Geo3d_Orgdist(x, y, z); Geo3d_Rotate_Coordinate(&x2, &y2, &z2, theta, psi, 0); if (fabs(x - x2) > 0.01 || fabs(y - y2) > 0.01 || fabs(z - z2) > 0.01) { printf("%g, %g\n", theta, psi); printf("%g, %g, %g\n", x, y, z); printf("%g, %g, %g\n", x2, y2, z2); PRINT_EXCEPTION(":( Bug?", "Unexpected orientation values."); return 1; } } /* Dot product. */ if (Geo3d_Dot_Product(1.0, 2.0, 3.0, 3.0, 2.0, 1.0) != 10.0) { PRINT_EXCEPTION(":( Bug?", "Unexpected dot product."); return 1; } /* Cross product. */ Geo3d_Cross_Product(1.0, 2.0, 3.0, 3.0, 1.0, 2.0, coord, coord+1, coord+2); if (fabs(Geo3d_Dot_Product(1.0, 2.0, 3.0, coord[0], coord[1], coord[2])) > 0.01) { PRINT_EXCEPTION(":( Bug?", "Unexpected dot product."); return 1; } if (fabs(Geo3d_Dot_Product(3.0, 1.0, 2.0, coord[0], coord[1], coord[2])) > 0.01) { PRINT_EXCEPTION(":( Bug?", "Unexpected dot product."); return 1; } /* Distance calculations. */ if (Geo3d_Orgdist_Sqr(1.0, 2.0, 3.0) != 14.0) { PRINT_EXCEPTION(":( Bug?", "Unexpected value."); return 1; } if (fabs(Geo3d_Orgdist(1.0, 2.0, 3.0) - sqrt(14.0)) > 0.01) { PRINT_EXCEPTION(":( Bug?", "Unexpected value."); return 1; } if (Geo3d_Dist(1.0, 2.0, 3.0, 1.0, 2.0, 3.0) != 0.0) { PRINT_EXCEPTION(":( Bug?", "Unexpected value."); return 1; } if (Geo3d_Dist_Sqr(1.0, 2.0, 3.0, 0.0, 0.0, 0.0) != 14.0) { PRINT_EXCEPTION(":( Bug?", "Unexpected value."); return 1; } /* Angle between two vectors. */ if (fabs(Geo3d_Angle2(1, 0, 0, 0, 0, 1) - TZ_PI_2) > 0.01) { PRINT_EXCEPTION(":( Bug?", "Unexpected value."); return 1; } /* Distance between two lines */ coordinate_3d_t line1_start = {0, 0, 0}; coordinate_3d_t line1_end = {1, 0, 0}; coordinate_3d_t line2_start = {0, 1, 1}; coordinate_3d_t line2_end = {0, 2, 1}; double d = Geo3d_Line_Line_Dist(line1_start, line1_end, line2_start, line2_end); if (fabs(d - 1.0) > 0.01) { PRINT_EXCEPTION(":( Bug?", "Unexpected distance."); return 1; } /* Distance between two line segments. */ double intersect1, intersect2; int cond; d = Geo3d_Lineseg_Lineseg_Dist(line1_start, line1_end, line2_start, line2_end, &intersect1, &intersect2, &cond); if (fabs(d - sqrt(2.0)) > 0.01) { PRINT_EXCEPTION(":( Bug?", "Unexpected distance."); return 1; } /* Distance between a point and a line segment. */ coord[0] = 0.5; coord[1] = 1.0; coord[2] = 1.0; d = Geo3d_Point_Lineseg_Dist(coord, line1_start, line1_end, &intersect1); if (fabs(d - sqrt(2.0)) > 0.01) { PRINT_EXCEPTION(":( Bug?", "Unexpected distance."); return 1; } /* Get a break point of a line segment. */ Geo3d_Lineseg_Break(line1_start, line1_end, 0.1, coord); if ((coord[0] != 0.1) || (coord[1] != 0.0) || (coord[2] != 0.0)) { PRINT_EXCEPTION(":( Bug?", "Unexpected break point."); return 1; } /* Orientations of a set of points */ /* Orientation of a covariance matrix */ /* 3D coordinates routines */ /* Unitize a point. */ Coordinate_3d_Unitize(coord); if (fabs(Coordinate_3d_Norm(coord) - 1.0) > 0.01) { PRINT_EXCEPTION(":( Bug?", "Unexpected norm."); return 1; } Set_Coordinate_3d(coord, 0.0, 0.0, 0.0); /* origin point is not affected by unitization */ Coordinate_3d_Unitize(coord); if (Coordinate_3d_Norm(coord) != 0.0) { PRINT_EXCEPTION(":( Bug?", "Unexpected norm."); return 1; } Set_Coordinate_3d(coord, 1.0, 2.0, 3.0); /* Square length */ if (Coordinate_3d_Length_Square(coord) != 14) { PRINT_EXCEPTION(":( Bug?", "Unexpected square length"); } /* Angle between two vectors */ coordinate_3d_t coord_a1 = { 1, 0, 0 }; coordinate_3d_t coord_a2 = { 0, 0, 1 }; if (fabs(Coordinate_3d_Angle2(coord_a1, coord_a2) - TZ_PI_2) > 0.01) { PRINT_EXCEPTION(":( Bug?", "Unexpected angle"); } /* Scale coordinates */ Coordinate_3d_Scale(coord, 2.0); if ((coord[0] != 2.0) || (coord[1] != 4.0) || (coord[2] != 6.0)) { PRINT_EXCEPTION(":( Bug?", "Unexpected coordinate value."); return 1; } /* Normalizd dot product */ if (Coordinate_3d_Normalized_Dot(coord, coord2) > 1.0) { PRINT_EXCEPTION(":( Bug?", "Unexpected dot product."); return 1; } Set_Coordinate_3d(coord, 1.0, 2.0, 3.0); Coordinate_3d_Copy(coord2, coord); Coordinate_3d_Scale(coord2, 2.0); coordinate_3d_t coord3; Coordinate_3d_Copy(coord3, coord); Coordinate_3d_Scale(coord3, 3.0); /* cos value of an angle formed by 3 points */ if (Coordinate_3d_Cos3(coord, coord2, coord3) != 1.0) { PRINT_EXCEPTION(":( Bug?", "Unexpected cos value."); return 1; } /* cos value of an angle formed by 4 points */ coordinate_3d_t coord4; Coordinate_3d_Copy(coord4, coord); Coordinate_3d_Scale(coord4, 4.0); if (Coordinate_3d_Cos4(coord, coord2, coord3, coord4) != 1.0) { PRINT_EXCEPTION(":( Bug?", "Unexpected cos value."); return 1; } printf(":) Testing passed.\n"); return 0; } #if 0 Geo3d_Vector v1 = {1.1, 0, 0}; Geo3d_Vector v2 = {5, 0, 0}; double theta1 = 3.83812; double psi1 = 3.53202; double theta2 = 0.72657; double psi2 = 3.61214; Geo3d_Orientation_Normal(theta1, psi1, &(v1.x), &(v1.y), &(v1.z)); Geo3d_Orientation_Normal(theta2, psi2, &(v2.x), &(v2.y), &(v2.z)); Print_Geo3d_Vector(&v1); Print_Geo3d_Vector(&v2); printf("%g\n", Geo3d_Vector_Dot(&v1, &v2)); printf("%g\n", Geo3d_Vector_Angle2(&v1, &v2)); double angle = Vector_Angle(-1.0, -1.0); theta1 = -3.0; psi1 = -5.0; double x, y, z; Geo3d_Orientation_Normal(theta1, psi1, &x, &y, &z); printf("%g, %g, %g\n", x, y, z); Geo3d_Normal_Orientation(x, y, z, &theta1, &psi1); printf("%g\n", angle * 180.0 / TZ_PI); printf("%g, %g\n", theta1, psi1); Geo3d_Orientation_Normal(theta1, psi1, &x, &y, &z); printf("%g, %g, %g\n", x, y, z); #endif #if 0 Geo3d_Scalar_Field *field = Read_Geo3d_Scalar_Field("../data/mouse_neuron/seeds.bn"); Print_Geo3d_Scalar_Field_Info(field); Stack *stack = Read_Stack("../data/mouse_neuron/mask.tif"); Geo3d_Scalar_Field_Draw_Stack(field, stack, NULL, NULL); Write_Stack("../data/test.tif", stack); #endif #if 0 double line_start[3] = {2.0, 3.0, 4.0}; double line_end[3] = {1.0, 1.0, 6.0}; double point[3] = {10.5, 20.5, 40.7}; double lamda; printf("%g\n", Geo3d_Point_Lineseg_Dist(point, line_start, line_end, &lamda)); double line_point[3]; double length = sqrt(Geo3d_Dist_Sqr(line_start[0], line_start[1], line_start[2], line_end[0], line_end[1], line_end[2])); line_point[0] = line_start[0] + lamda * (line_end[0] - line_start[0]); line_point[1] = line_start[1] + lamda * (line_end[1] - line_start[1]); line_point[2] = line_start[2] + lamda * (line_end[2] - line_start[2]); printf("%g\n", lamda); printf("%g\n", sqrt(Geo3d_Dist_Sqr(line_point[0], line_point[1], line_point[2], point[0], point[1], point[2]))); darray_sub(point, line_point, 3); darray_sub(line_end, line_point, 3); printf("%g\n", Geo3d_Dot_Product(point[0], point[1], point[2], line_end[0], line_end[1], line_end[2])); #endif #if 0 Geo3d_Scalar_Field *field = Read_Geo3d_Scalar_Field("../data/mouse_neuron3_org/seeds"); //Print_Geo3d_Scalar_Field(field); darray_write("../data/pts.bn", (double *)field->points, field->size * 3); darray_write("../data/ws.bn", field->values, field->size); coordinate_3d_t centroid; Geo3d_Scalar_Field_Centroid(field, centroid); Print_Coordinate_3d(centroid); double cov[9]; Geo3d_Scalar_Field_Cov(field, cov); darray_print2(cov, 3, 3); darray_write("../data/cov.bn", cov, 9); double vec[3]; Geo3d_Cov_Orientation(cov, vec); darray_print2(vec, 3, 1); #endif #if 0 double mu1, mu2; # if 0 /* parallel case */ double line1_start[3] = {0, 0, 0}; double line1_end[3] = {1, 1, 10}; double line2_start[3] = {0, 1, 0}; double line2_end[3] = {1, 2, 10}; # endif # if 0 /* parallel case */ double line1_start[3] = {0, 0, 0}; double line1_end[3] = {1, 1, 10}; double line2_start[3] = {-1, -1, -1}; double line2_end[3] = {-3, -3, -21}; # endif # if 0 /* i-i case */ double line1_start[3] = {0, 0, 0}; double line1_end[3] = {3, 4, 5}; double line2_start[3] = {-1, 8, 9}; double line2_end[3] = {1, -3, -4}; # endif # if 0 /* point to line case */ double line1_start[3] = {3, 4, 5}; double line1_end[3] = {3, 4, 5}; double line2_start[3] = {-1, 8, 9}; double line2_end[3] = {1, -3, -4}; # endif # if 0 /* point to line case */ double line2_start[3] = {3, 4, 5}; double line2_end[3] = {3, 4, 5}; double line1_start[3] = {-1, 8, 9}; double line1_end[3] = {1, -3, -4}; # endif # if 0 /* point to line case */ double line2_start[3] = {3, 4, 5}; double line2_end[3] = {3, 4, 5}; double line1_start[3] = {-1, 8, 9}; double line1_end[3] = {-1, 8, 9}; # endif # if 0 double line1_start[3] = {256.062, 328.674, 67.9029}; double line1_end[3] = {246.162, 330.078, 67.9896}; double line2_start[3] = {262.368, 336.609, 68.3076}; double line2_end[3] = {259.956, 326.944, 67.4325}; # endif int cond; double dist = Geo3d_Lineseg_Lineseg_Dist(line1_start, line1_end, line2_start, line2_end, &mu1, &mu2, &cond); printf("%d, %g\n", cond, dist); dist = Geo3d_Line_Line_Dist(line1_start, line1_end, line2_start, line2_end); printf("%g\n", dist); #endif #if 1 double *d = Unifrnd_Double_Array(12000000, NULL); double *d2 = Unifrnd_Double_Array(12000000, NULL); tic(); Rotate_XZ(d, d, 4000000, 0.1, 0.2, 1); printf("%llu\n", toc()); tic(); Rotate_XZ2(d, d, 4000000, 0.1, 0.2, 0); printf("%llu\n", toc()); #endif #if 0 double d[3] = {0.1, 0.2, 0.3}; Rotate_XZ(d, d, 1, 0.1, 0.2, 0); darray_print2(d, 3, 1); #endif #if 0 printf("%g\n", Ellipse_Point_Distance(5, 5, 3, 5)); #endif #if 0 Geo3d_Ellipse *ellipse = New_Geo3d_Ellipse(); ellipse->scale = 0.5; ellipse->orientation[0] = 1.0; Print_Geo3d_Ellipse(ellipse); FILE *fp = fopen("../data/test.swc", "w"); Swc_Node node; Geo3d_Ellipse_To_Swc_Node(ellipse, 1, -1, 1.0, 2, &node); Swc_Node_Fprint(fp, &node); /* double pt[3] = {0.0, 0.0, 1.0}; printf("%g\n", Geo3d_Ellipse_Point_Distance(ellipse, pt)); */ Geo3d_Ellipse *ellipse2 = Copy_Geo3d_Ellipse(ellipse); ellipse2->center[0] += 10.0; ellipse2->orientation[0] = 2.0; ellipse2->radius += 3.0; Geo3d_Ellipse *ellipse3 = Geo3d_Ellipse_Interpolate(ellipse, ellipse2, 0.2, NULL); Geo3d_Ellipse_To_Swc_Node(ellipse3, 2, 1, 1.0, 2, &node); Swc_Node_Fprint(fp, &node); Geo3d_Ellipse_To_Swc_Node(ellipse2, 3, 2, 1.0, 2, &node); Swc_Node_Fprint(fp, &node); Print_Geo3d_Ellipse(ellipse3); fclose(fp); #endif #if 0 Geo3d_Ellipse *ellipse = New_Geo3d_Ellipse(); ellipse->scale = 0.5; FILE *fp = fopen("../data/test.swc", "w"); coordinate_3d_t *pts = Geo3d_Ellipse_Sampling(ellipse, 20, 0, NULL); Geo3d_Point_Array_Swc_Fprint(fp, pts, 20, 1, -1, 1.0, 2); ellipse->orientation[0] = 1.0; pts = Geo3d_Ellipse_Sampling(ellipse, 20, 0, NULL); Geo3d_Point_Array_Swc_Fprint(fp, pts, 20, 21, -1, 1.0, 3); ellipse->center[2] = 5.0; pts = Geo3d_Ellipse_Sampling(ellipse, 20, 0, NULL); Geo3d_Point_Array_Swc_Fprint(fp, pts, 20, 41, -1, 1.0, 4); coordinate_3d_t vec[2]; Coordinate_3d_Copy(vec[0], ellipse->center); Geo3d_Ellipse_First_Vector(ellipse, vec[1]); Coordinate_3d_Add(vec[0], vec[1], vec[1]); Geo3d_Point_Array_Swc_Fprint(fp, vec, 2, 101, -1, 1.0, 5); Geo3d_Ellipse_Second_Vector(ellipse, vec[1]); Coordinate_3d_Add(vec[0], vec[1], vec[1]); Geo3d_Point_Array_Swc_Fprint(fp, vec, 2, 111, -1, 1.0, 6); Geo3d_Ellipse_Normal_Vector(ellipse, vec[1]); Coordinate_3d_Add(vec[0], vec[1], vec[1]); Geo3d_Point_Array_Swc_Fprint(fp, vec, 2, 121, -1, 1.0, 7); fclose(fp); #endif #if 0 Geo3d_Ellipse ep_array[10]; Geo3d_Ellipse *ellipse = New_Geo3d_Ellipse(); ellipse->scale = 0.5; Geo3d_Ellipse_Copy(ep_array, ellipse); FILE *fp = fopen("../data/test.swc", "w"); ellipse->orientation[0] += 0.5; ellipse->center[2] += 3.0; ellipse->center[0] += 1.0; Geo3d_Ellipse_Copy(ep_array + 1, ellipse); ellipse->center[2] += 3.0; Geo3d_Ellipse_Copy(ep_array + 2, ellipse); coordinate_3d_t *pts = Geo3d_Ellipse_Array_Sampling(ep_array, 3, 20, NULL); Geo3d_Point_Array_Swc_Fprint(fp, pts, 60, 1, -1, 1.0, 2); fclose(fp); #endif #if 0 printf("%g\n", Vector_Angle(1.0, 1.0) * 180 / TZ_PI); #endif #if 0 double theta, psi; coordinate_3d_t coord; coord[0] = 0.0822; coord[1] = 0.1515; coord[2] = 0.1369; Geo3d_Coord_Orientation(coord[0], coord[1], coord[2], &theta, &psi); printf("%g, %g\n", theta, psi); Geo3d_Orientation_Normal(theta, psi, coord, coord+1, coord+2); Print_Coordinate_3d(coord); #endif #if 0 double theta, psi; double x = -1; double y = 1.83697019872103e-16; double z = 3; Geo3d_Coord_Orientation(x, y, z, &theta, &psi); #endif #if 0 double theta = Vector_Angle2(0, 1, 1, 0, TRUE); printf("angle: %g\n", theta); theta = Vector_Angle2(0, 1, -1, 0, FALSE); printf("angle: %g\n", theta); theta = Vector_Angle2(-1, 0, -1, -1, TRUE); printf("angle: %g\n", theta); #endif return 0; }
Int_Arraylist *Stack_Route(const Stack *stack, int start[], int end[], Stack_Graph_Workspace *sgw) { if (sgw->gw == NULL) { sgw->gw = New_Graph_Workspace(); } if (sgw->range == NULL) { double dist = Geo3d_Dist(start[0], start[1], start[2], end[0], end[1], end[2]); int margin[3]; int i = 0; for (i = 0; i < 3; ++i) { margin[i] = iround(dist - abs(end[i] - start[i] + 1)); if (margin[i] < 0) { margin[i] = 0; } } Stack_Graph_Workspace_Set_Range(sgw, start[0], end[0], start[1], end[1], start[2], end[2]); Stack_Graph_Workspace_Expand_Range(sgw, margin[0], margin[0], margin[1], margin[1], margin[2], margin[2]); Stack_Graph_Workspace_Validate_Range(sgw, stack->width, stack->height, stack->depth); } int swidth = sgw->range[1] - sgw->range[0] + 1; int sheight = sgw->range[3] - sgw->range[2] + 1; int sdepth = sgw->range[5] - sgw->range[4] + 1; int start_index = Stack_Util_Offset(start[0] - sgw->range[0], start[1] - sgw->range[2], start[2] - sgw->range[4], swidth, sheight, sdepth); int end_index = Stack_Util_Offset(end[0] - sgw->range[0], end[1] - sgw->range[2], end[2] - sgw->range[4], swidth, sheight, sdepth); if (start_index > end_index) { int tmp; SWAP2(start_index, end_index, tmp); } ASSERT(start_index >= 0, "Invalid starting index."); ASSERT(end_index >= 0, "Invalid ending index."); tic(); Graph *graph = Stack_Graph_W(stack, sgw); ptoc(); tic(); int *path = NULL; switch (sgw->sp_option) { case 0: path = Graph_Shortest_Path_E(graph, start_index, end_index, sgw->gw); break; case 1: { //printf("%g\n", sgw->intensity[start_index]); sgw->intensity[end_index] = 4012; sgw->intensity[start_index] = 4012; path = Graph_Shortest_Path_Maxmin(graph, start_index, end_index, sgw->intensity, sgw->gw); } break; } sgw->value = sgw->gw->dlist[end_index]; Kill_Graph(graph); if (isinf(sgw->value)) { return NULL; } #ifdef _DEBUG_2 { Graph_Update_Edge_Table(graph, sgw->gw); Stack *stack = Make_Stack(GREY, swidth, sheight, sdepth); Zero_Stack(stack); int nvoxel = (int) Stack_Voxel_Number(stack); int index = end_index; printf("%d -> %d\n", start_index, end_index); while (index >= 0) { if (index < nvoxel) { stack->array[index] = 255; } int x, y, z; Stack_Util_Coord(index, swidth, sheight, &x, &y, &z); printf("%d (%d, %d, %d), %g\n", index, x, y, z, sgw->gw->dlist[index]); index = path[index]; } Write_Stack("../data/test2.tif", stack); Kill_Stack(stack); } #endif Int_Arraylist *offset_path = Parse_Stack_Shortest_Path(path, start_index, end_index, stack->width, stack->height, sgw); int org_start = Stack_Util_Offset(start[0], start[1], start[2], stack->width, stack->height, stack->depth); if (org_start != offset_path->array[0]) { iarray_reverse(offset_path->array, offset_path->length); } int org_end = Stack_Util_Offset(end[0], end[1], end[2], stack->width, stack->height, stack->depth); //printf("%d, %d\n", org_end, offset_path->array[offset_path->length -]); ASSERT(org_start == offset_path->array[0], "Wrong path head."); if (org_end != offset_path->array[offset_path->length - 1]) { printf("debug here\n"); } ASSERT(org_end == offset_path->array[offset_path->length - 1], "Wrong path tail."); ptoc(); return offset_path; }