std::pair<std::vector<TaggedLine>, std::vector<TaggedLine>> BSPTree::makeLines(Communicator *, time_t, const std::vector<TaggedLine> &lines, BSPNode *base) { std::vector<TaggedLine> leftlines; std::vector<TaggedLine> rightlines; // for optimization of the tree (this reduced a six-minute gen time to a 38 second gen time) int chosen = -1; if (lines.size() > 3) { chosen = BSPTree::pickMidpointLine(lines, base->m_parent); } else { chosen = pafrand() % lines.size(); } Line chosenLine = lines[chosen].line; int chosenTag = lines[chosen].tag; base->setLine(chosenLine); base->setTag(chosenTag); Point2f v0 = chosenLine.end() - chosenLine.start(); v0.normalise(); for (size_t i = 0; i < lines.size(); i++) { if (i == static_cast<unsigned int>(chosen)) { continue; } const Line &testline = lines[i].line; int tag = lines[i].tag; Point2f v1 = testline.start() - chosenLine.start(); v1.normalise(); Point2f v2 = testline.end() - chosenLine.start(); v2.normalise(); // should use approxeq here: double a = testline.start() == chosenLine.start() ? 0 : det(v0, v1); double b = testline.end() == chosenLine.start() ? 0 : det(v0, v2); // note sure what to do if a == 0 and b == 0 (i.e., it's parallel... this test at least ensures on the line is // one or the other side) if (a >= 0 && b >= 0) { leftlines.push_back(TaggedLine(testline, tag)); } else if (a <= 0 && b <= 0) { rightlines.push_back(TaggedLine(testline, tag)); } else { Point2f p = intersection_point(chosenLine, testline); Line x = Line(testline.start(), p); Line y = Line(p, testline.end()); if (a >= 0) { if (x.length() > 0.0) // should use a tolerance here too leftlines.push_back(TaggedLine(x, tag)); if (y.length() > 0.0) // should use a tolerance here too rightlines.push_back(TaggedLine(y, tag)); } else { if (x.length() > 0.0) // should use a tolerance here too rightlines.push_back(TaggedLine(x, tag)); if (y.length() > 0.0) // should use a tolerance here too leftlines.push_back(TaggedLine(y, tag)); } } } return std::make_pair(leftlines, rightlines); }
int main() { double tcrit = intersection_point(); printf("Result: %.12f\n", tcrit); printf("True: %.12f\n", M_PI/6.); printf("Error: %e\n", fabs(tcrit - M_PI/6.)); return 0; }
void closest_point(point2d p, line l, point2d *cp) { if (fabs(l.b) <= EPSILON) { // vertical line cp->x = -l.c; cp->y = p.y; return; } if (fabs(l.a) <= EPSILON) { // horizontal line cp->x = p.x; cp->y = -l.c; return; } // line with slope line perp; // perpendicular to l through (x,y) point_and_slope_to_line(p, 1/l.a, &perp); intersection_point(l, perp, cp); }
bool segments_intersect(segment s1, segment s2) { line l1, l2; /* lines containing the input segments */ point p; /* intersection point */ points_to_line(s1.p1, s1.p2, &l1); points_to_line(s2.p1, s2.p2, &l2); if(same_lineQ(l1, l2)) /* overlapping or disjoint segments */ return( point_in_box(s1.p1, s2.p1, s2.p2) || point_in_box(s1.p2, s2.p1, s2.p2) || point_in_box(s2.p1, s1.p1, s1.p2) || point_in_box(s2.p2, s1.p1, s1.p2) ); if(parallelQ(l1, l2)) return(FALSE); intersection_point(l1, l2, p); return( point_in_box(p, s1.p1, s1.p2) && point_in_box(p, s2.p1, s2.p2) ); }
bool segments_intersect(segment s1, segment s2) { line l1, l2; points_to_line(s1.p1, s1.p2, &l1); points_to_line(s2.p1, s2.p2, &l2); if (same_lineQ(l1, l2)) return (point_in_box(s1.p1, s2.p1, s2.p2) || point_in_box(s1.p2, s2.p1, s2.p2) || point_in_box(s2.p1, s1.p1, s1.p2) || point_in_box(s2.p1, s1.p1, s1.p2) ); if (parallelQ(l1, l2)) return false; point2d p; // intersection point intersection_point(l1, l2, p); return (point_in_box(p, s1.p1, s1.p2) && point_in_box(p, s2.p1, s2.p2) ); }
void closest_point(const point p_in, line l, point p_c) { line perp; /* perpendicular to l through (x,y) */ if(fabs(l.b) <= EPSILON) { /* vertical line */ p_c[X] = -(l.c); p_c[Y] = p_in[Y]; return; } if(fabs(l.a) <= EPSILON) { /* horizontal line */ p_c[X] = p_in[X]; p_c[Y] = -(l.c); return; } point_and_slope_to_line(p_in, 1/l.a, &perp); /* non-degenerate line */ /*printf("perpendicular bisector "); print_line(perp);*/ intersection_point(l, perp, p_c); /*printf("closest point "); print_point(p_c);*/ }
void FaceOffDriver::set_predicted_vertex_positions( const SurfTrack& surf, std::vector<Vec3d>& new_positions, double current_t, double& adaptive_dt ) { const NonDestructiveTriMesh& mesh = surf.m_mesh; std::vector<double> triangle_areas; triangle_areas.reserve(mesh.num_triangles()); std::vector<Vec3d> triangle_normals; triangle_normals.reserve(mesh.num_triangles()); std::vector<Vec3d> triangle_centroids; triangle_centroids.reserve(mesh.num_triangles()); std::vector<double> triangle_plane_distances; triangle_plane_distances.reserve(mesh.num_triangles()); const std::vector<Vec3st>& tris = mesh.get_triangles(); for ( size_t i = 0; i < tris.size(); ++i ) { if ( tris[i][0] == tris[i][1] ) { triangle_areas.push_back( 0 ); triangle_normals.push_back( Vec3d(0,0,0) ); triangle_centroids.push_back( Vec3d(0,0,0) ); } else { triangle_areas.push_back( surf.get_triangle_area( i ) ); triangle_normals.push_back( surf.get_triangle_normal( i ) ); triangle_centroids.push_back( (surf.get_position(tris[i][0]) + surf.get_position(tris[i][1]) + surf.get_position(tris[i][2])) / 3 ); } double switch_speed = (current_t >= 1.0) ? -speed : speed; triangle_plane_distances.push_back( adaptive_dt * switch_speed ); } std::vector<Vec3d> displacements; displacements.resize( surf.get_num_vertices() ); // // Null space smoothing // { for ( size_t i = 0; i < surf.get_num_vertices(); ++i ) { const MeshSmoother& smoother = surf.m_smoother; smoother.null_space_smooth_vertex( i, triangle_areas, triangle_normals, triangle_centroids, displacements[i] ); } } // // Primary space displacement // for ( size_t p = 0; p < surf.get_num_vertices(); ++p ) { Vec3d normal_dispacement; intersection_point( triangle_normals, triangle_plane_distances, triangle_areas, mesh.m_vertex_to_triangle_map[p], normal_dispacement ); displacements[p] += normal_dispacement; // // Entropy solution // if ( surf.m_mesh.m_vertex_to_triangle_map[p].empty() ) { continue; } double sum_mu_l = 0, sum_mu = 0; const std::vector<size_t>& incident_triangles = mesh.m_vertex_to_triangle_map[p]; for ( size_t j = 0; j < incident_triangles.size(); ++j ) { size_t triangle_index = incident_triangles[j]; const Vec3st& tri = surf.m_mesh.get_triangle( triangle_index ); Vec3d edge_vector; if ( tri[0] == p ) { edge_vector = surf.get_position(tri[1]) - surf.get_position(tri[2]); } else if ( tri[1] == p ) { edge_vector = surf.get_position(tri[2]) - surf.get_position(tri[0]); } else { edge_vector = surf.get_position(tri[0]) - surf.get_position(tri[1]); } Vec3d s = cross( triangle_normals[triangle_index], edge_vector ); // orthogonal to normal and edge oposite vertex bool contracting = dot( s, displacements[p] ) >= 0.0; double cos_theta = dot( triangle_normals[triangle_index], normal_dispacement ) / mag(normal_dispacement); double mu = triangle_areas[triangle_index]; if ( contracting ) { mu *= cos_theta * cos_theta; } double li = fabs( triangle_plane_distances[triangle_index] ); if ( contracting ) { li /= fabs( cos_theta ); } sum_mu_l += mu * li; sum_mu += mu; } double length = sum_mu_l / sum_mu; displacements[p] += length * normal_dispacement / mag(normal_dispacement); } double beta = MeshSmoother::compute_max_timestep_quadratic_solve( surf.m_mesh.get_triangles(), surf.get_positions(), displacements, false ); adaptive_dt *= beta; for(size_t i = 0; i < surf.get_num_vertices(); i++) { new_positions[i] = surf.get_position(i) + beta * displacements[i]; } }
main() { point p1,p2,q1,q2,i; line l1,l2; segment s1,s2,s3,s4; while ( scanf("%lf %lf",&p1[X],&p1[Y]) != EOF ) { scanf("%lf %lf",&p2[X],&p2[Y]); scanf("%lf %lf",&q1[X],&q1[Y]); scanf("%lf %lf",&q2[X],&q2[Y]); /* print_point(p1); print_point(p2); print_point(q1); print_point(q2); */ points_to_segment(p1,p2,&s1); points_to_segment(q1,q2,&s2); points_to_line(p1,p2,&l1); points_to_line(q1,q2,&l2); print_segment(s1); print_segment(s2); /* printf("slope and line tests\n"); point_and_slope_to_line(p1,-l1.a,&l3); print_line(l3); point_and_slope_to_line(p2,-l1.a,&l3); print_line(l3); point_and_slope_to_line(q1,-l2.a,&l3); print_line(l3); point_and_slope_to_line(q2,-l2.a,&l3); print_line(l3); */ printf("segments_intersect test\n"); printf("%d\n", segments_intersect(s1,s2)); printf("intersection point\n"); intersection_point(l1,l2,i); print_point(i); /* printf("closest point\n"); closest_point(p1,l1,i); print_point(i); closest_point(p2,l1,i); print_point(i); closest_point(q1,l1,i); print_point(i); closest_point(q2,l1,i); print_point(i); closest_point(p1,l2,i); print_point(i); closest_point(p2,l2,i); print_point(i); closest_point(q1,l2,i); print_point(i); closest_point(q2,l2,i); print_point(i); */ printf("--------------------------------\n"); } }