235 lines
6.5 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,FractalNoise
import matplotlib.pyplot as pp
import numpy as np
from math import floor,ceil
from time import sleep
import threading
import sys
#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.rx,dy/self.ry)
self.lastx,self.lasty = e.x(),e.y()
self.x += -dy/self.rx
self.y += -dx/self.ry
self.updateImage()# TODO separer le updateImage dans un autre thread pour éviter de l'appeler 1000 fois. Plutot set un tag indiquant qu'il faudrait l'appeler.
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
x,y = 0,0
rx,ry = 256,256
w,h = 512,512
def getChunk(self,x,y,rx,ry):
if (x,y) not in self.generator.generated:
self.generator.genqueue.append((x,y))
return np.zeros((rx,ry))
return self.generator.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.w,self.h))
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)
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.carte.setPixmap(qp)
class Generator(threading.Thread):
updatefunc = None
noise = None
res = None
generated = {}
genqueue = []
running = True
def __init__(self,updatefunc,noise,res):
super().__init__()
self.updatefunc = updatefunc
self.noise = noise
self.res = res
def run(self):
while(self.running):
if(len(self.genqueue) > 0):
x,y = self.genqueue.pop(0)
if (x,y) in self.generated:
continue
chunk = self.noise.getChunk(x,y,self.res)
self.generated[(x,y)] = chunk
self.updatefunc()
else:
sleep(0.01)
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.updateImage,noise,(nav.rx,nav.ry))
nav.generator = generator
generator.start()
nav.updateImage()
###### Content #####