def findEvent(s_left, s_right, p): global etree global R sl_line = Line.points2Line(s_left.start, s_left.end) sr_line = Line.points2Line(s_right.start, s_right.end) #print(sl_line) #print(sr_line) hit = sl_line.intersects(sr_line) # case: sr and sl are same segment, they never intersect if not hit: return if s_left.isInSegment(hit) == -1: return if s_right.isInSegment(hit) == -1: return isThere = etree.find(hit) if hit.y < p.y and isThere == None: e = Event(hit) etree.insert(e) #print("added event:", e) elif hit.y == p.y and hit.x < p.x and isThere == None: e = Event(hit) etree.insert(e) #print("added event:", e) if animated and not single_plot: paint(p) paint(p)
def isLessThan(s1, s2, t1): t2 = Point(t1.x + 1, t1.y) tline = Line.points2Line(t1, t2) hit1 = tline.intersects(Line.points2Line(s1.start, s1.end)) hit2 = tline.intersects(Line.points2Line(s2.start, s2.end)) # if insert horizontal s1, insert at the end if not hit1: return False if hit1.x < hit2.x: return True else: return False
def isInSegment(self, p): if p == self.start: return 0 if p == self.end: return 1 sline = Line.points2Line(self.start, self.end) result = (sline.a * p.x) + (sline.b * p.y) + sline.c if abs(result) < eps: if self.inBounds(p): # point in middle of segment return 2 else: # point in segment line but not in segment return -1 else: return -1
def getSegmentHit(s, p): t2 = Point(p.x + 1, p.y) tline = Line.points2Line(p, t2) hit = tline.intersects(Line.points2Line(s.start, s.end)) return hit
min_dist = 0 perpPoint = Point() seg = [] fig = plt.figure() fig.add_axes() ax1 = plt.gca() ax1.plot(x,y, color="green") ax1.scatter(hide_point.x,hide_point.y, s=100, marker="P", color='blue') for i in range(len(x) - 1): p1 = Point(x[i], y[i]) p2 = Point(x[i + 1], y[i + 1]) ax1.scatter(p1.x,p1.y, s=100, marker="o", color="green") dist = Line.point2SegDist(p1, p2, hide_point) if i == 0: min_dist = dist if i == len(x) - 2: ax1.scatter(p2.x,p2.y, s=100, marker="o", color="green") if dist <= min_dist: min_dist = dist perpPoint = Line.perpPoint2Seg(p1, p2, hide_point) seg.append([tuple([hide_point.x, hide_point.y]), tuple([perpPoint.x, perpPoint.y])]) mid = Point.midPoint(hide_point, perpPoint) coord = tuple([mid.x, mid.y]) coordt = tuple([mid.x + 1, mid.y + 1]) ax1.annotate("d={a:.2f}".format(a=min_dist), xy=coord, xytext=coordt, size=12, arrowprops = dict(facecolor ='black',width=1,headwidth=4))
cycles.append(cycle) extremes.append(extreme[0]) # fetch its origin to get extreme vertex of ith cycle # internal cycles are always faces # external cycles may be united with others and form one face # we will represent the union graphs where cycles are vertices in a dict: keys are the vertices graph = {} for c in range(len(cycles)): if cycles[c][len(cycles[c]) - 1] == "external": # fill each key with an empty list that will be filled if that external cycle gets together with another graph[f"c{c}"] = [] print("Graph:", graph) for c in range(len(cycles)): if cycles[c][len(cycles[c]) - 1] == "external": extEdge = extremes[c] horizontal = Line.points2Line(extEdge.origin.pos, Point(extEdge.origin.pos.x - 0.1, extEdge.origin.pos.y)) # with the line, check every external cycle and each of its edges to see if there is an intersection for ec in ext_cycles: for edge in ec[:len(ec) - 1]: tempLine = Line.points2Line(edge.origin.pos, edge.next.origin.pos) hit = horizontal.intersects(tempLine) # if the two lines intersect and the point is in left side of the extreme point of that cycle if isinstance(hit, Point) and hit.x < extEdge.origin.pos.x: # if hit point inside edge bounds if hit.x >= edge.origin.pos.x and hit.x <= edge.next.origin.pos.x and hit.y >= edge.origin.pos.y and hit.y <= edge.next.origin.pos.y: # connect it to the graph by appending the cycle index where that hitting edge is idx = cycles.index(ext_cycles[ext_cycles.index(ec)]) print(f"Union -> Edge: {edge} in ext cycle: {ec} from ext cycles: {ext_cycles} at cycle index: {idx} from cycles array") graph[f"c{c}"].append(f"c{idx}") print("Graph:", graph)
curr_peak = mountains[i][1] max_peak = tuple([0, 0]) sun = True for j in range(i, len(mountains), 2): if (mountains[j][1] > curr_peak): sun = False break if sun == True: peaks_x.append(mountains[i][0]) peaks_y.append(mountains[i][1]) for k in range(i + 2, len(mountains), 2): if (mountains[k][1] > max_peak[1]): max_peak = mountains[k] other_point = Point(max_peak[0] + 1, max_peak[1]) block_point = Point(max_peak[0], max_peak[1]) sun_ray = Line.points2Line(block_point, other_point) peak_point = Point(mountains[i][0], mountains[i][1]) low_point = Point(mountains[i + 1][0], mountains[i + 1][1]) peak_slope = Line.points2Line(peak_point, low_point) hit_point = sun_ray.intersects(peak_slope) sunny_segs.append([ tuple([hit_point.x, hit_point.y]), tuple([peak_point.x, peak_point.y]) ]) sun_lows_x.append(hit_point.x) sun_lows_y.append(hit_point.y) distances.append( [Point.distance(peak_point, low_point), peak_point, hit_point])
def processEvent(p): global tot_seg global tLine global R global R_segs p = p.value.point if animated and not single_plot: paint(p) paint(p) U = [s for s in tot_seg if s.start == p] # tree finding if fast: U2, C, L = tLine.findByPoint(p) # brute force finding if not fast: in_array = tLine.inorder(tLine.root) #print("T line:", in_array) L = [s for s in in_array if s.end == p] C = [] for s in in_array: if s.isInSegment(p) == 2: C.append(s) U = U #print("U:{u}\nC:{c}\nL:{l}".format(u=U, c=C, l=L)) # lists to sets U = set(U) C = set(C) L = set(L) UCL = (U.union(C)).union(L) UC = U.union(C) #print("UCL: {0}".format(UCL)) if len(UCL) > 1: R.append(p) R_segs.append([s.index for s in UCL]) # print output on the go if live_output: ucl = list(UCL) segs_involved = "" for j in range(len(ucl)): segs_involved += str(ucl[j].name) + " " print(("Intersection at: ({x},{y}) -> " + segs_involved).format( x=p.x, y=p.y)) for s in (L.union(C)): tLine.deleteValue(s, p) for s in (UC): tLine.insert(s, p) if len(UC) == 0: s_l = tLine.getLeftFromP(p, tLine.root) s_r = tLine.getRightFromP(p, tLine.root) #print("########### new step neighbours:", s_l.value, s_r.value) if s_l != None and s_r != None: findEvent(s_l.value, s_r.value, p) else: uc = list(UC) hits = [] # UC in T: list of hits with segment index for s in uc: t2 = Point(p.x + 1, p.y) tempLine = Line.points2Line(p, t2) hit = tempLine.intersects(Line.points2Line(s.start, s.end)) if not hit: continue hits.append([hit, s.index]) # UC in T (ordered horizontally) hits = sorted(hits, key=lambda p: p[0].x, reverse=False) if len(hits) < 1: return else: s_prime = tot_seg[hits[0][1]] # left neighbour is the inorder predecessor s_left = tLine.getPredecessor(tLine.root, s_prime, p) if s_left != None: #print("left neighbour:", s_left.value) findEvent(s_left.value, s_prime, p) s_bprime = tot_seg[hits[len(hits) - 1][1]] # right neighbour is the inorder successor s_right = tLine.getSuccessor(tLine.root, s_bprime, p) if s_right != None: #print("right neighbour:", s_right.value) findEvent(s_bprime, s_right.value, p)
theta = 45 p1 = Point(1, 1) p2 = Point(p1.x + d * cos(theta * pi / 180), p1.y + d * sin(theta * pi / 180)) # (1.9999, 1.9999) p3 = Point(2, 2) # POINTS print(p2 == p3) print(p2) print("Point distance:", Point.distance(p1, p3)) # 1.4142 print("Point rotation:", p1.rotate(90)) # LINE FROM 2 POINTS p1 = Point(2, 2) p2 = Point(2, 4) line1 = Line.points2Line(p1, p2) print("Line from 2 points:", line1) # CHECK PARALLEL LINES p3 = Point(4, 1) p4 = Point(4, 3) line2 = Line.points2Line(p3, p4) print("Is Paralel:", line1.isParallelTo(line2)) # CHECK INTERSECTION line1 = Line.points2Line(Point(0, 0), Point(1, 1)) line2 = Line.points2Line(Point(1, 0), Point(1, 2)) line1 = Line.points2Line(Point(15, 10), Point(49, 25)) line2 = Line.points2Line(Point(29, 5), Point(32, 32)) print("Intersection:", line1.intersects(line2))