265 lines
7.7 KiB
Python

# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import (QWidget, QSlider, QApplication,
QHBoxLayout, QVBoxLayout, QLabel, QLineEdit, QDesktopWidget, QPushButton, QComboBox)
from PyQt5.QtCore import QObject, Qt
from PyQt5.QtGui import QPainter, QFont, QColor, QPen, QImage, QPixmap
from perlin import PerlinNoise
import matplotlib.pyplot as pp
import numpy as np
from math import floor,ceil
import threading
import sys
try: application
except NameError: application = QApplication([])
class MapNavigator(QWidget):
carte = QLabel()
def __init__(self):
super().__init__()
self.setWindowTitle("Navigateur")
### Centrer la fenetre ###
self.resize(750,505)
self.initFrame()
self.show()
self.centrer()
def centrer(self):
qtRectangle = self.frameGeometry()
centerPoint = QDesktopWidget().availableGeometry().center()
qtRectangle.moveCenter(centerPoint)
self.move(qtRectangle.topLeft())
def initFrame(self):
##### Config #####
globalayout = QHBoxLayout()
configl = QVBoxLayout()
configl.setAlignment(Qt.AlignTop)
## Fichier ##
fichier = QHBoxLayout()
fichierlabel = QLabel("Fichier :")
fichiertext = QLineEdit()
fichier.addWidget(fichierlabel)
fichier.addWidget(fichiertext)
## Refresh ##
refresh = QPushButton("Refresh")
## Coords ##
Xs = QHBoxLayout()
posxlabel = QLabel("x:")
posxtext = QLineEdit()
lxlabel = QLabel("lx:")
lxtext = QLineEdit()
Xs.addWidget(posxlabel)
Xs.addWidget(posxtext)
Xs.addWidget(lxlabel)
Xs.addWidget(lxtext)
Ys = QHBoxLayout()
posylabel = QLabel("y:")
posytext = QLineEdit()
lylabel = QLabel("ly:")
lytext = QLineEdit()
Ys.addWidget(posylabel)
Ys.addWidget(posytext)
Ys.addWidget(lylabel)
Ys.addWidget(lytext)
## Redraw ##
redraw = QPushButton("Redraw")
## Colormap ##
colormap = QHBoxLayout()
colormaplabel = QLabel("Color map :")
colormapchooser = QComboBox()#["Noir","Blanc","Rouge","Vert","Bleu"])
colormap.addWidget(colormaplabel)
colormap.addWidget(colormapchooser)
configl.addLayout(fichier)
configl.addWidget(refresh)
configl.addLayout(Xs)
configl.addLayout(Ys)
configl.addWidget(redraw)
configl.addLayout(colormap)
globalayout.addLayout(configl)
globalayout.addWidget(self.carte)
self.setLayout(globalayout)
lastx,lasty = None,None
def mouseMoveEvent(self,e):
dx,dy = e.x() - self.lastx,e.y() - self.lasty
print(dx/self.generator.w*self.generator.rx,dy/self.generator.h*self.generator.ry)
self.lastx,self.lasty = e.x(),e.y()
self.generator.x += dx/self.generator.w*self.generator.rx
self.generator.y += dy/self.generator.h*self.generator.ry
def mousePressEvent(self,e):
self.lastx,self.lasty = e.x(),e.y()
def mouseReleaseEvent(self,e):
self.lastx,self.lasty = None,None
def closeEvent(self,e):
self.generator.running = False
def getChunk(self,x,y,rx,ry):
if (x,y) not in self.generated:
self.genqueue.append((x,y))
return np.zeroes((rx,ry))
return self.generated[(x,y)]
def updateImage(self):
x,y = self.x,self.y
rx,ry = self.rx,self.ry
w,h = self.w,self.h
lx,ly = w/rx,h/ry
#out = np.zeros((self.WIDTH,self.HEIGTH))
x0 = x-lx/2
x1 = x+lx/2
y0 = y-ly/2
y1 = y+ly/2
cx0,cy0 = int((x0-floor(x0))*rx),int((y0-floor(y0))*ry)
cx1,cy1 = int((x1-floor(x1))*rx),int((y1-floor(y1))*ry)
zx,zy = int((1+floor(x0)-x0)*rx),int((1+floor(y0)-y0)*ry)
print(x0,x1,y0,y1,cx0,cy0,w,h,lx,ly)
for i in range(floor(x0),floor(x1)+1):
for j in range(floor(y0),floor(y1)+1):
chk = self.getChunk(i,j,rx,ry)
cx,dx = cx0 if i==floor(x0) else 0 , cx1 if i==floor(x1) else rx
cy,dy = cy0 if j==floor(y0) else 0 , cy1 if j==floor(y1) else ry
ax,ay = 0 if i==floor(x0) else zx+(i-floor(x0)-1)*rx , 0 if j==floor(y0) else zy+(j-floor(y0)-1)*ry
bx,by = ax + (dx-cx) , ay + (dy-cy)
print(i,j,"->",ax,bx,cx,dx,ay,by,cy,dy)
out[ax:bx,ay:by] = chk[cx:dx,cy:dy]
self.setImage(out)
class Generator(threading.Thread):
label = None
noise = None
generated = {}
genqueue = []
running = True
x,y = 0,0
rx,ry = 256,256
w,h = 512,512
def __init__(self,linkedLabel,noise):
super().__init__()
self.label = linkedLabel
self.noise = noise
def getChunk(self,x,y,rx,ry):
if (x,y) not in self.generated:
self.genqueue.append((x,y))
chunk = self.noise.getChunk(x,y,(rx,ry))
self.generated[(x,y)] = chunk
return self.generated[(x,y)]
def setImage(self,im):
im = np.uint8((im - im.min())/im.ptp()*255.0)
qi = QImage(im.data, im.shape[1], im.shape[0], im.shape[1], QImage.Format_Indexed8)
qp = QPixmap.fromImage(qi)
self.label.setPixmap(qp)
def run(self):
out = np.zeros((self.w,self.h))
while(self.running):
x,y = self.x,self.y
rx,ry = self.rx,self.ry
w,h = self.w,self.h
lx,ly = w/rx,h/ry
#out = np.zeros((self.WIDTH,self.HEIGTH))
x0 = x-lx/2
x1 = x+lx/2
y0 = y-ly/2
y1 = y+ly/2
cx0,cy0 = int((x0-floor(x0))*rx),int((y0-floor(y0))*ry)
cx1,cy1 = int((x1-floor(x1))*rx),int((y1-floor(y1))*ry)
zx,zy = int((1+floor(x0)-x0)*rx),int((1+floor(y0)-y0)*ry)
print(x0,x1,y0,y1,cx0,cy0,w,h,lx,ly)
for i in range(floor(x0),floor(x1)+1):
for j in range(floor(y0),floor(y1)+1):
self.setImage(out)
chk = self.getChunk(i,j,rx,ry)
cx,dx = cx0 if i==floor(x0) else 0 , cx1 if i==floor(x1) else rx
cy,dy = cy0 if j==floor(y0) else 0 , cy1 if j==floor(y1) else ry
ax,ay = 0 if i==floor(x0) else zx+(i-floor(x0)-1)*rx , 0 if j==floor(y0) else zy+(j-floor(y0)-1)*ry
bx,by = ax + (dx-cx) , ay + (dy-cy)
print(i,j,"->",ax,bx,cx,dx,ay,by,cy,dy)
out[ax:bx,ay:by] = chk[cx:dx,cy:dy]
self.setImage(out)
print('Bybye !')
nav = MapNavigator()
seed=42
perl1 = PerlinNoise(10 ,seed)
perl2 = PerlinNoise(5 ,seed)
perl3 = PerlinNoise(1 ,seed)
noise = perl1+.1*perl2+.03*perl3
generator = Generator(nav.carte,noise)
nav.generator = generator
generator.start()
###### Content #####