def moveAndDraw(self, event): m = 1 point = Point(event.x(), event.y()) distance_from_previous_point = Point.dist(point, self.basepoint) self.pos = event.pos() if distance_from_previous_point >= m: if distance_from_previous_point >= 2*m: cos = (point.x() - self.basepoint.x()) / distance_from_previous_point sin = (point.y() - self.basepoint.y()) / distance_from_previous_point point = Point(self.basepoint.x() + round(cos), self.basepoint.y() + round(sin)) for i in range(m, math.ceil(distance_from_previous_point), m): self.pointList.append(point) point = Point(self.basepoint.x() + round(cos*i), self.basepoint.y() + round(sin*i)) self.pointList.append(point) self.basepoint = point if self.mindistance(point) <= 20 and len(self.pointList) >= 50: v = self.closestvertex(point) self.pointList.append(Point(v.x(), v.y())) self.finishTheRoad(v)
def triangle(coords, win, zbufer,rte,light_dir): new = QColor() #Отрисовка поверхности треугольниками. Внимание тут будет дописан Гуро!!! a = Point(coords[0].x, coords[0].y, coords[0].z, coords[0].norma) b = Point(coords[1].x, coords[1].y, coords[1].z, coords[1].norma) c = Point(coords[2].x, coords[2].y, coords[2].z, coords[2].norma) min_m = min(half_scr_x,half_scr_y) # Преобразование координат к экранным a.x = int(a.x * min_m )+ 150 a.y = 650 - int(a.y * min_m ) a.z = a.z * min_m b.x = int(b.x * min_m ) + 150 b.y = 650 - int(b.y * min_m ) b.z = b.z * min_m c.x = int(c.x * min_m ) +150 c.y = 650 - int(c.y * min_m ) c.z = c.z * min_m #Сортировка по возростанию y a,b,c = sorted([a,b,c], key=lambda p: p.y) I1 = ligh * light_dir.mul(a.norma) I2 = ligh * light_dir.mul(b.norma) I3 = ligh * light_dir.mul(c.norma) # Вырожденный треугольник if a.y == b.y and a.y == c.y: return rte win.pen.setColor(new) total_height = c.y - a.y win.pen.setColor(new) # Цикл по всем строкам треугольника. Каждую строку закрашиваем. for i in range(total_height): # Сначала вычисляем границы строки test = (i > b.y - a.y) or(b.y == a.y) if test: seg = c.y - b.y else: seg = b.y - a.y first = Point(i/total_height, 1, 1,0) if test: second = Point((i - b.y + a.y)/seg, 1, 1,0) else: second = Point(i/seg, 1, 1,0) al = a + (c - a) * first if test: bl = b + (c - b) * second else: bl = a + (b - a) * second #линейная интерполяция if test == False and a.y != b.y: Ia = abs(I1 + ((I2 - I1)/(b.y - a.y))*(i)) elif test and b.y != c.y: Ia = abs(I2 + ((I3 - I2)/(c.y - b.y))*(a.y + i - b.y)) else: Ia = abs(I1 + (I2 - I1) * (i)) if (c.y != a.y): Ib = abs(I1 + ((I3 - I1)/(c.y - a.y))*(i)) else: Ib =abs( I1 + (I3 - I1) * (i)) if al.x > bl.x: al, bl = bl, al else: Ia, Ib = Ib, Ia # Идём от одной вычесленной границы до другой # Пока нет защиты от выхода за границы экрана. for j in range(int(al.x),int(bl.x)+1): if al.x == bl.x: phi = 1 else: phi = (j - al.x)/(bl.x - al.x) p = Point(j,a.y+i,al.z + (bl.z-al.z)*phi,0) idx = int(p.x+p.y*width) # Применяем z-буфер if (bl.x - al.x) == 0: I = abs(Ia + (Ib - Ia)*(p.x-al.x)) else: I = abs(Ia + (Ib - Ia)/(bl.x - al.x)*(p.x - al.x)) #new.setRgb( int(I),int(I),int(I)) try: if (zbufer[idx] < p.z): zbufer[idx] = p.z #win.image.setPixel(p.x, p.y, win.pen.color().rgb()) if p.x < 780 and p.x > 0 and p.y< 650 and p.y > 0: win.image.setPixel(p.x, p.y,qRgb(int(I), int(I), int(I))) except: return rte return rte