// checks if three lines are intersecting at one point // algorithm: if intersection of 1st and 2nd is same as intersection of 1st and 3rd bool are_intersecting(double line1[3], double line2[3], double line3[3]) { return !is_parallel(line1, line2) && !is_parallel(line1, line3) && !is_parallel(line2, line3) && are_equal ( intersection(line1, line2), intersection(line1, line3) ); }
bool intersection(const Line<T> &l, Point<T> &p) const { if (is_parallel(l)) return false; const Line<T> &rl = is_vertical() ? l : *this; p.x = (l.b*c - b*l.c) / (l.a*b - a*l.b); p.y = -(rl.a * p.x + rl.c) / rl.b; return true; }
/* decide_point returns the number of hops needed in the given directions * along the 2 edges to get to a deciding point (or NODES) and also puts * into prec the appropriate dependency (follows same convention as seg_cmp) */ static pair decide_point(segment* si, segment* sj, int dir1, int dir2) { int prec, ans = 0, temp; pair ret; segment* np1; segment* np2; while ((np1 = next_seg(si,dir1)) && (np2 = next_seg(sj,dir2)) && is_parallel(np1, np2)) { ans++; si = np1; sj = np2; } if (!np1) prec = 0; else if (!np2) assert(0); /* FIXME */ else { temp = seg_cmp(np1, np2); prec = propagate_prec(np1, temp, ans+1, 1-dir1); } ret.a = ans; ret.b = prec; return(ret); }
bool conv_offset::cross(double A1, double B1, double C1, double A2, double B2, double C2, GPoint& p) { if(!is_parallel(A1, B1, A2, B2)) { p.x = GUnits((B1*C2 - B2*C1) / (A1*B2 - A2*B1)); p.y = GUnits((C1*A2 - C2*A1) / (A1*B2 - A2*B1)); return true; } return false; }
bool has_parallel_group_children(void) const { if (is_parallel()) return true; for (const auto & elem : child_groups) if (elem.has_parallel_group_children()) return true; return false; }
bool has_parallel_group_children(void) const { if (is_parallel()) return true; for (group_list::const_iterator it = child_groups.begin(); it != child_groups.end(); ++it) if (it->has_parallel_group_children()) return true; return false; }
/* removes the edge between segments after the resolution of a conflict */ static void removeEdge(segment* seg1, segment* seg2, int dir, maze* mp) { segment* ptr1; segment* ptr2; channel* chan; ptr1 = seg1; ptr2 = seg2; while(is_parallel(ptr1, ptr2)) { ptr1 = next_seg(ptr1, 1); ptr2 = next_seg(ptr2, dir); } if(ptr1->isVert) chan = chanSearch(mp->vchans, ptr1); else chan = chanSearch(mp->hchans, ptr1); remove_redge (chan->G, ptr1->ind_no, ptr2->ind_no); }
bool operator==(const Line &l) const { return is_parallel(l) && a * l.c == c * l.a; }
bool conv_offset::calc_segment(const GPoint& p1, const GPoint& p2, const GPoint& p3, GUnits offset, GPoint& beg, GPoint& end, bool first_seg, bool *use_both) { *use_both = false; offset = -offset; double A1, B1, C1, A2, B2, C2; if(!gen_line_koef(p1, p2, &A1, &B1, &C1)) return false; if(!gen_line_koef(p2, p3, &A2, &B2, &C2)) return false; if(is_parallel(A1, B1, A2, B2) && !is_same_orientation(A1, B1, A2, B2)) *use_both = true; double l1 = sqrt(A1 * A1 + B1 * B1); double vec_y_1 = B1 / l1, vec_x_1 = A1 / l1; double l2 = sqrt(A2 * A2 + B2 * B2); double vec_y_2 = B2 / l2, vec_x_2 = A2 / l2; if(first_seg) { beg.x = GUnits(p1.x + vec_x_1 * double(offset)); beg.y = GUnits(p1.y + vec_y_1 * double(offset)); } else { end.x = GUnits(p3.x + vec_x_2 * double(offset)); end.y = GUnits(p3.y + vec_y_2 * double(offset)); } if(*use_both || is_parallel(A1, B1, A2, B2)) { if(first_seg) { end.x = GUnits(p2.x + vec_x_1 * double(offset)); end.y = GUnits(p2.y + vec_y_1 * double(offset)); } else { end.x = GUnits(p3.x + vec_x_2 * double(offset)); end.y = GUnits(p3.y + vec_y_2 * double(offset)); } } else { if(first_seg) cross(A1, B1, C1 - offset * l1, A2, B2, C2 - offset * l2, end); else cross(A1, B1, C1 - offset * l1, A2, B2, C2 - offset * l2, beg); } // отсекаем через чур длинные линии bool cut = false; double maxlen = 0; double l = len(beg, end); if(first_seg) { maxlen = len(p1, p2) + abs((int)offset); if(l > maxlen) cut = true; } else { maxlen = len(p2, p3) + abs((int)offset); if(l > maxlen) cut = true; } if(cut) { *use_both = true; double koef = maxlen / l; if(first_seg) { end.x = GUnits(beg.x + koef * (end.x - beg.x)); end.y = GUnits(beg.y + koef * (end.y - beg.y)); } else { beg.x = GUnits(end.x - koef * (end.x - beg.x)); beg.y = GUnits(end.y - koef * (end.y - beg.y)); } } return true; }
static void addPEdges (channel* cp, maze* mp) { int i,j; /* dir[1,2] are used to figure out whether we should use prev * pointers or next pointers -- 0 : decrease, 1 : increase */ int dir; /* number of hops along the route to get to the deciding points */ pair hops; /* precedences of the deciding points : same convention as * seg_cmp function */ int prec1, prec2; pair p; rawgraph* G = cp->G; segment** segs = cp->seg_list; for(i=0;i+1<cp->cnt;i++) { for(j=i+1;j<cp->cnt;j++) { if (!edge_exists(G,i,j) && !edge_exists(G,j,i)) { if (is_parallel(segs[i], segs[j])) { /* get_directions */ if(segs[i]->prev==0) { if(segs[j]->prev==0) dir = 0; else dir = 1; } else if(segs[j]->prev==0) { dir = 1; } else { if(segs[i]->prev->comm_coord==segs[j]->prev->comm_coord) dir = 0; else dir = 1; } p = decide_point(segs[i], segs[j], 0, dir); hops.a = p.a; prec1 = p.b; p = decide_point(segs[i], segs[j], 1, 1-dir); hops.b = p.a; prec2 = p.b; switch(prec1) { case -1 : set_parallel_edges (segs[j], segs[i], dir, 0, hops.a, mp); set_parallel_edges (segs[j], segs[i], 1-dir, 1, hops.b, mp); if(prec2==1) removeEdge (segs[i], segs[j], 1-dir, mp); break; case 0 : switch(prec2) { case -1: set_parallel_edges (segs[j], segs[i], dir, 0, hops.a, mp); set_parallel_edges (segs[j], segs[i], 1-dir, 1, hops.b, mp); break; case 0 : set_parallel_edges (segs[i], segs[j], 0, dir, hops.a, mp); set_parallel_edges (segs[i], segs[j], 1, 1-dir, hops.b, mp); break; case 1: set_parallel_edges (segs[i], segs[j], 0, dir, hops.a, mp); set_parallel_edges (segs[i], segs[j], 1, 1-dir, hops.b, mp); break; } break; case 1 : set_parallel_edges (segs[i], segs[j], 0, dir, hops.a, mp); set_parallel_edges (segs[i], segs[j], 1, 1-dir, hops.b, mp); if(prec2==-1) removeEdge (segs[i], segs[j], 1-dir, mp); break; } } } } } }
/** * @brief 直線と直線の距離 * @param[in] a 判定する直線 * @param[in] b 判定する直線 * @return 直線aと直線bの距離 */ inline double distance(const Line &a, const Line &b){ if(!is_parallel(a, b)){ return 0.0; } return distance(a.a, b); }
void c15() { double lines[max_number_of_lines][parameters + 2]; // array to store lines, entered by user int lines_entered = 0; // counter, how many lines are entered const int checked = 1; // flag line is already processed (used in parallelness check and printing) const int not_checked = -1; // flag line is not yet processed // getting lines from user for (int line = 0; line < max_number_of_lines; line++, lines_entered++) { double* input_line = get_line(); if (is_stop(input_line)) { lines_entered--; break; } else { lines[line][a] = input_line[a]; lines[line][b] = input_line[b]; lines[line][c] = input_line[c]; lines[line][state] = not_checked; lines[line][parallelness] = not_checked; } } bool exists_parallels = false; // mark lines parallel for (int line = 0; line < lines_entered; line++) { // if line not yet marked as being parallel if (lines[line][state] == not_checked) { // loop through lines, starting from next one till end for (int next_line = line + 1; next_line < lines_entered; next_line++) { if (is_parallel(lines[line], lines[next_line])) { // mark current line as parallel to line from outer loop lines[next_line][state] = checked; lines[next_line][parallelness] = line; exists_parallels = true; } } } } // reseting state for printing for (int line = 0; line < lines_entered; line++) lines[line][state] = not_checked; // print out result of parallelness check if (exists_parallels) { bool has_parallels; print("Parallel lines are:"); for (int line = 0; line < lines_entered; line++) { // cout << "entering with line " << line + 1 << endl; string output_lines = " Line " + to_char(line+1); has_parallels = false; // if line is not yet printed if (lines[line][state] == not_checked) { for (int next_line = line + 1; next_line < lines_entered; next_line++) { if (lines[next_line][parallelness] == line) { lines[next_line][state] = checked; output_lines += ", line " + to_char(next_line+1); has_parallels = true; } } } if (has_parallels) print(output_lines); } } else { print("There are no parallel lines."); } // combinations by 3 lines out of all lines bool exists_triple_intersection = false; for (int line1 = 0; line1 < lines_entered; line1++) { for (int line2 = line1+1; line2 < lines_entered; line2++) { for (int line3 = line2+1; line3 < lines_entered; line3++) { if (are_intersecting(lines[line1], lines[line2], lines[line3])) { exists_triple_intersection = true; // double* intersection_of_1_and_2 = intersection(lines[line1], lines[line2]); // cout << "Intersection is " << intersection_of_1_and_2[0] << ";" << intersection_of_1_and_2[1]; cout << endl << "Following lines are intersecting at same point: "; print(lines[line1]); print(lines[line2]); print(lines[line3]); } } } } if (!exists_triple_intersection) print("Not triple intersection exists."); }
bool is_parallel(scgl::line const& l1, scgl::line const& l2) { return is_parallel(l1.m_direction, l2.m_direction) && !is_in_line(l1, l2.m_point); }