Premier commit - Introdution au système git.
13
.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Extensions de compilation LaTeX
|
||||||
|
*.aux
|
||||||
|
*.toc
|
||||||
|
*.synctex.gz
|
||||||
|
*.out
|
||||||
|
*.log
|
||||||
|
*.snm
|
||||||
|
*.nav
|
||||||
|
svg-inkscape/
|
||||||
|
|
||||||
|
__pycache__
|
||||||
|
*compresse.pdf
|
||||||
|
.metadata
|
||||||
13
3dmaker.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Created on Wed May 15 18:43:29 2019
|
||||||
|
|
||||||
|
@author: mysaa
|
||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
|
Les hhmaps seront des np array bidimentionnels de listes a nombre impair d'éléments
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
BIN
Diapo/Diapo.pdf
Normal file
275
Diapo/Diapo.tex
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
\documentclass[11pt]{beamer}
|
||||||
|
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage[T1]{fontenc}
|
||||||
|
\usepackage{lmodern}
|
||||||
|
\usepackage[french]{babel}
|
||||||
|
\usepackage{amsmath}
|
||||||
|
\usepackage{amsfonts}
|
||||||
|
\usepackage{amssymb}
|
||||||
|
\usepackage{graphicx}
|
||||||
|
\usepackage{multicol}
|
||||||
|
\usepackage{courier}
|
||||||
|
\usepackage{appendix}
|
||||||
|
\usepackage{appendixnumberbeamer}
|
||||||
|
\usepackage{minted}
|
||||||
|
|
||||||
|
\usetheme{Madrid}
|
||||||
|
%\usetheme{Warsaw}
|
||||||
|
|
||||||
|
\addtobeamertemplate{frametitle}{
|
||||||
|
\let\insertframetitle\insertsectionhead}{}
|
||||||
|
\addtobeamertemplate{frametitle}{
|
||||||
|
\let\insertframesubtitle\insertsubsectionhead}{}
|
||||||
|
|
||||||
|
|
||||||
|
\makeatletter
|
||||||
|
\CheckCommand*\beamer@checkframetitle{\@ifnextchar\bgroup\beamer@inlineframetitle{}}
|
||||||
|
\renewcommand*\beamer@checkframetitle{\global\let\beamer@frametitle\relax\@ifnextchar\bgroup\beamer@inlineframetitle{}}
|
||||||
|
\makeatother
|
||||||
|
|
||||||
|
|
||||||
|
\hypersetup{pdfpagemode=FullScreen}
|
||||||
|
% Transition en fade-in par défaut
|
||||||
|
\addtobeamertemplate{background canvas}{\transfade[duration=0.4]}{}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\usebeamercolor{orchid}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\author{Samy Avrillon - 24817}
|
||||||
|
\title{Stockage et génération de topographie artificielle de fond océanique}
|
||||||
|
\subtitle{Projet "Sonar de l'infini"}
|
||||||
|
\logo{\includegraphics[width=.5cm]{logoLafayette}}
|
||||||
|
\institute{Lycée Lafayette}
|
||||||
|
%\subject{}
|
||||||
|
%\setbeamercovered{transparent}
|
||||||
|
%\setbeamertemplate{navigation symbols}{}
|
||||||
|
\begin{frame}[plain]
|
||||||
|
\maketitle
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\section*{Sommaire}
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Sommaire}
|
||||||
|
\pause
|
||||||
|
\begin{multicols}{2}
|
||||||
|
\tableofcontents[pausesections]
|
||||||
|
\end{multicols}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\section{Introduction}
|
||||||
|
\subsection{Le but : un format inéxistant}
|
||||||
|
\begin{frame}
|
||||||
|
\pause
|
||||||
|
\begin{columns}
|
||||||
|
\column{0.5\textwidth}
|
||||||
|
\begin{itemize}
|
||||||
|
\item<2-4> Un champ des hauteurs
|
||||||
|
\item<3-4> Une discrétisation 3D
|
||||||
|
\item<4> Quelques formats privés
|
||||||
|
\end{itemize}
|
||||||
|
\column{0.5\textwidth}
|
||||||
|
\only<2>{
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[width=\textwidth]{heightmapExample}
|
||||||
|
\caption{Exemple de champ de hauteur}
|
||||||
|
\end{figure}
|
||||||
|
}
|
||||||
|
\only<3>{
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[width=\textwidth]{discretisation3d}
|
||||||
|
\caption{Exemple de discrétisation 3d de l'espace}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
}
|
||||||
|
\end{columns}
|
||||||
|
|
||||||
|
\end{frame}
|
||||||
|
\subsection{Débouchés et utilisations}
|
||||||
|
\begin{frame}
|
||||||
|
\pause
|
||||||
|
\begin{columns}
|
||||||
|
\column{0.5\textwidth}
|
||||||
|
\begin{itemize}[<+->]
|
||||||
|
\item<2-4> Jeu vidéo on monde ouvert
|
||||||
|
\item<3-4> Graphisme, cinéma
|
||||||
|
\item<4> Simulation physique ou de rover
|
||||||
|
\end{itemize}
|
||||||
|
\column{0.5\textwidth}
|
||||||
|
\only<2>{
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[width=\textwidth]{minecraftOcean}
|
||||||
|
\caption{Capture du jeu vidéo Minecraft}
|
||||||
|
\end{figure}
|
||||||
|
}
|
||||||
|
\only<3>{
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[width=0.8\textwidth]{nemoCoraux}
|
||||||
|
\includegraphics[width=0.8\textwidth]{samyTortue}
|
||||||
|
\caption{Extrait des films \fg{} Le monde de némo \og et \fg{} Le Voyage extraordinaire de Samy \og}
|
||||||
|
\end{figure}
|
||||||
|
}
|
||||||
|
\end{columns}
|
||||||
|
\end{frame}
|
||||||
|
\section{Le format TMF}
|
||||||
|
\subsection{Contraintes}
|
||||||
|
\begin{frame}
|
||||||
|
\pause
|
||||||
|
\begin{itemize}[<+->]
|
||||||
|
\item Liberté totale
|
||||||
|
\item Complexité spatiale
|
||||||
|
\item Référencabilité
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\subsection{Modélisation}
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Modélisation}
|
||||||
|
\pause
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[height=0.6\textheight]{fond}
|
||||||
|
\caption{Représentation 2D du stockage des colonnes}
|
||||||
|
\end{figure}
|
||||||
|
\end{frame}
|
||||||
|
\subsection{Réalité du stoquage}
|
||||||
|
\begin{frame}
|
||||||
|
Ici format de fichier,
|
||||||
|
\end{frame}
|
||||||
|
\subsection{Algorithme d'abstraction: tmfeur}
|
||||||
|
|
||||||
|
\section{Module Objection}
|
||||||
|
|
||||||
|
\subsection{Minecraft}
|
||||||
|
\begin{frame}
|
||||||
|
\pause
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[height=0.6\textheight]{minecraftGrottes}
|
||||||
|
\caption{Usage de Minecraft comme moteur graphique}
|
||||||
|
\end{figure}
|
||||||
|
\end{frame}
|
||||||
|
\subsection{Rectangle}
|
||||||
|
\begin{frame}
|
||||||
|
\pause
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[height=0.6\textheight]{recImage}
|
||||||
|
\caption{Usage de rectangles}
|
||||||
|
\end{figure}
|
||||||
|
\end{frame}
|
||||||
|
\subsection{Colonnes}
|
||||||
|
\begin{frame}
|
||||||
|
\pause
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[height=0.6\textheight]{filImage}
|
||||||
|
\caption{Usage de parallélépipèdes}
|
||||||
|
\end{figure}
|
||||||
|
\end{frame}
|
||||||
|
\subsection{Triangles}
|
||||||
|
\begin{frame}
|
||||||
|
\pause
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[height=0.6\textheight]{triImage}
|
||||||
|
\caption{Usage de triangles}
|
||||||
|
\end{figure}
|
||||||
|
\end{frame}
|
||||||
|
\section{Génération}
|
||||||
|
|
||||||
|
\subsection{Contraintes}
|
||||||
|
\begin{frame}
|
||||||
|
\pause
|
||||||
|
\begin{itemize}[<+->]
|
||||||
|
\item Infinité
|
||||||
|
\item Répétabilité
|
||||||
|
\item Modulabilité
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\subsection{Noisette}
|
||||||
|
|
||||||
|
\subsubsection{Méthodes et attributs}
|
||||||
|
\begin{frame}
|
||||||
|
\pause
|
||||||
|
\begin{itemize}[<+->]
|
||||||
|
\item \texttt{getChunk(self,x,y,n)}
|
||||||
|
\item \texttt{\_\_add\_\_(self,other)}
|
||||||
|
\item \texttt{\_\_rmul\_\_(self,other)}
|
||||||
|
\item \texttt{\_\_sub\_\_(self,other)}
|
||||||
|
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
\subsubsection{Bruits généraux}
|
||||||
|
\begin{frame}
|
||||||
|
\pause
|
||||||
|
\begin{itemize}[<+->]
|
||||||
|
\item Bruit sur le cercle trigonométrique
|
||||||
|
\item Bruit avec des interpolations linéaires
|
||||||
|
\item Bruit avec des droites
|
||||||
|
\item Bruit de Perlin (2d)
|
||||||
|
\item Bruit fractal
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
\subsection{Cartman}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Bruit de Perlin}
|
||||||
|
\pause
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[height=0.6\textheight]{perlin}
|
||||||
|
\caption{Heightmap créée par un bruit de perlin}
|
||||||
|
\end{figure}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Bruit Fractal}
|
||||||
|
\begin{columns}
|
||||||
|
\pause
|
||||||
|
\begin{column}{0.5\textwidth}
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[width=0.8\textwidth]{bfractal}
|
||||||
|
\caption{Bruit fractal avec peu de droites}
|
||||||
|
\end{figure}
|
||||||
|
\end{column}
|
||||||
|
\pause
|
||||||
|
\begin{column}{0.5\textwidth}
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[width=0.8\textwidth]{hfractal}
|
||||||
|
\caption{Bruit fractal avec plus de droites}
|
||||||
|
\end{figure}
|
||||||
|
\end{column}
|
||||||
|
\end{columns}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\subsubsection{Quelques algorithmes}
|
||||||
|
\begin{frame}
|
||||||
|
Bruit Caverne à présenter
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
|
||||||
|
\appendix
|
||||||
|
\section{Sommaire}
|
||||||
|
\begin{frame}
|
||||||
|
TODO sommaire de l'appendice
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\section{Python}
|
||||||
|
\subsection{data.py}
|
||||||
|
\begin{frame}[allowframebreaks]
|
||||||
|
\inputminted[fontsize=\footnotesize,breaklines=true]{python}{data.py}
|
||||||
|
\end{frame}
|
||||||
|
\subsection{objection.py}
|
||||||
|
\begin{frame}[allowframebreaks]
|
||||||
|
\inputminted[fontsize=\footnotesize,breaklines=true]{python}{objection.py}
|
||||||
|
\end{frame}
|
||||||
|
\subsection{perlin.py}
|
||||||
|
\begin{frame}[allowframebreaks]
|
||||||
|
\inputminted[fontsize=\footnotesize,breaklines=true]{python}{perlin.py}
|
||||||
|
\end{frame}
|
||||||
|
\subsection{tmf.py}
|
||||||
|
\begin{frame}[allowframebreaks]
|
||||||
|
\inputminted[fontsize=\footnotesize,breaklines=true]{python}{tmf.py}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\end{document}
|
||||||
BIN
Diapo/bernardLogo.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
Diapo/bfractal.png
Normal file
|
After Width: | Height: | Size: 331 KiB |
2
Diapo/compressateur
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dQUIET -dBATCH -sOutputFile=Diapo-compesse.pdf Diapo.pdf
|
||||||
153
Diapo/data.py
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Created on Wed Aug 28 17:39:43 2019
|
||||||
|
|
||||||
|
Module contanant les classes générales structurant les données, ainsi que les
|
||||||
|
|
||||||
|
@author: mysaa
|
||||||
|
"""
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def appendeur(l1,l2):
|
||||||
|
"""
|
||||||
|
Effectue l1=l1+l2 de manière opti
|
||||||
|
"""
|
||||||
|
for l in l2:
|
||||||
|
l1.append(l)
|
||||||
|
|
||||||
|
class WorldChunk():
|
||||||
|
|
||||||
|
def getSize(self):
|
||||||
|
raise NotImplementedError("Vous avez fait un monde qui n'implemente pas cette méthode. Vous êtes bizzare vous savez ? Un monde sans taille !!!")
|
||||||
|
|
||||||
|
|
||||||
|
def getColumn(self,x,y):
|
||||||
|
raise NotImplementedError("Vous avez fait un monde qui n'implemente pas cette méthode. Vous êtes bizzare vous savez ?")
|
||||||
|
|
||||||
|
|
||||||
|
def asList(self):
|
||||||
|
return [ [self.getColumn(x,y) for y in range(self.size[1])] for x in range(self.size[0]) ]
|
||||||
|
|
||||||
|
def getIndexed(self,fullCoords=False,addZero=False):
|
||||||
|
points = []
|
||||||
|
pointIndexes = [0]
|
||||||
|
for pos in np.ndindex(self.getSize()):
|
||||||
|
col = self.getColumn(pos[0],pos[1])
|
||||||
|
if(addZero): col = np.insert(col,0,0)
|
||||||
|
if(fullCoords): col = [(pos[0],pos[1],c) for c in col]
|
||||||
|
appendeur(points,col)
|
||||||
|
pointIndexes.append(pointIndexes[-1]+len(col))
|
||||||
|
return points,pointIndexes
|
||||||
|
|
||||||
|
|
||||||
|
class CollageWorldChunk(WorldChunk):
|
||||||
|
|
||||||
|
def __init__(self,chunk,xp,yp,xy):
|
||||||
|
|
||||||
|
self.orgChunk,self.xp,self.yp,self.xy = chunk,xp,yp,xy
|
||||||
|
self.orgSize = chunk.getSize()
|
||||||
|
|
||||||
|
def getSize(self) : return (self.orgChunk.size[0]+1,self.orgChunk.size[1]+1)
|
||||||
|
|
||||||
|
def getColumn(self,x,y):
|
||||||
|
xout,yout = x>=self.orgSize[0],y>=self.orgSize[1]
|
||||||
|
if(xout and yout):
|
||||||
|
return self.xy.getColumn(x-self.orgSize[0],y-self.orgSize[1])
|
||||||
|
if(xout):
|
||||||
|
return self.xp.getColumn(x-self.orgSize[0],y)
|
||||||
|
if(yout):
|
||||||
|
return self.yp.getColumn(x,y-self.orgSize[1])
|
||||||
|
|
||||||
|
return self.orgChunk.getColumn(x,y)
|
||||||
|
|
||||||
|
class ArrayedWorldChunk(WorldChunk):
|
||||||
|
|
||||||
|
def fromList(liste):
|
||||||
|
size = len(liste),len(liste[0])
|
||||||
|
indexes=np.empty(size[0]*size[1]+1,dtype=np.uint32)
|
||||||
|
index = 0
|
||||||
|
data = []
|
||||||
|
for y in range(size[1]):
|
||||||
|
for x in range(size[0]):
|
||||||
|
indexes[x+size[0]*y]=index
|
||||||
|
data += liste[x][y]
|
||||||
|
index += len(liste[x][y])
|
||||||
|
indexes[size[0]*size[1]] = index
|
||||||
|
data = np.array(data,dtype=np.float)
|
||||||
|
return ArrayedWorldChunk(size,indexes,data)
|
||||||
|
|
||||||
|
def __init__(self,size,indexes,data):
|
||||||
|
self.size = size
|
||||||
|
self.indexes=indexes
|
||||||
|
self.data=data
|
||||||
|
|
||||||
|
|
||||||
|
def getColumn(self,x,y):
|
||||||
|
i0,i1 = self.indexes[x+self.size[0]*y],self.indexes[x+self.size[0]*y+1]
|
||||||
|
return self.data[i0:i1]
|
||||||
|
|
||||||
|
def getSize(self) : return self.size
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Noise:
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
"""
|
||||||
|
Cette fonction renvoie un array numpy de taille rx*ry correspondant au chunk x y avec le seed donné.
|
||||||
|
Cette fonction doit être déterministe (si les attributs de l'objets ne sont pas changés bien sur)
|
||||||
|
"""
|
||||||
|
raise NotImplementedError("Vous avez fait un bruit qui n'implemente pas cette méthode. Vous êtes bizzare vous savez ?")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def __add__(self,other):
|
||||||
|
|
||||||
|
def addedChunk(self,x,y,n):
|
||||||
|
return self.noise1.getChunk(x,y,n) + self.noise2.getChunk(x,y,n)
|
||||||
|
noise = Noise()
|
||||||
|
noise.noise1 = self
|
||||||
|
noise.noise2 = other
|
||||||
|
noise.getChunk = addedChunk
|
||||||
|
return noise
|
||||||
|
|
||||||
|
def __iadd__(self,other):
|
||||||
|
|
||||||
|
return self.__add__(other)
|
||||||
|
|
||||||
|
def __rmul__(self,other):
|
||||||
|
|
||||||
|
if type(other) in ['float','int']:
|
||||||
|
def mulChunk(self,x,y,n):
|
||||||
|
return self.prop*self.noise1.getChunk(x,y,n)
|
||||||
|
noise = Noise()
|
||||||
|
noise.noise1 = self
|
||||||
|
noise.prop = other
|
||||||
|
noise.getChunk = mulChunk
|
||||||
|
else:
|
||||||
|
def mulChunk(self,x,y,n):
|
||||||
|
return self.noise1.getChunk(x,y,n) * self.noise2.getChunk(x,y,n)
|
||||||
|
noise = Noise()
|
||||||
|
noise.noise1 = self
|
||||||
|
noise.noise2 = other
|
||||||
|
noise.getChunk = mulChunk
|
||||||
|
return noise
|
||||||
|
|
||||||
|
def __sub__(self,other):
|
||||||
|
|
||||||
|
def subChunk(self,x,y,n):
|
||||||
|
return self.noise1.getChunk(x,y,n) - self.noise2.getChunk(x,y,n)
|
||||||
|
noise = Noise()
|
||||||
|
noise.noise1 = self
|
||||||
|
noise.noise2 = other
|
||||||
|
noise.getChunk = subChunk
|
||||||
|
return noise
|
||||||
|
|
||||||
BIN
Diapo/discretisation3d.png
Normal file
|
After Width: | Height: | Size: 277 KiB |
BIN
Diapo/filImage.png
Normal file
|
After Width: | Height: | Size: 982 KiB |
665
Diapo/fond.svg
Normal file
@ -0,0 +1,665 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="171mm"
|
||||||
|
height="96mm"
|
||||||
|
viewBox="0 0 171 96.000002"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.1 r15371"
|
||||||
|
sodipodi:docname="fond.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="marker5549"
|
||||||
|
style="overflow:visible;"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path5547"
|
||||||
|
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||||
|
style="fill-rule:evenodd;stroke:#ffffff;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||||
|
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Sstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="Arrow1Sstart"
|
||||||
|
style="overflow:visible"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path4945"
|
||||||
|
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||||
|
style="fill-rule:evenodd;stroke:#ffffff;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||||
|
transform="scale(0.2) translate(6,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="Arrow1Send"
|
||||||
|
style="overflow:visible;"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path4948"
|
||||||
|
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||||
|
style="fill-rule:evenodd;stroke:#ffffff;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||||
|
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
style="overflow:visible"
|
||||||
|
id="DistanceStart"
|
||||||
|
refX="0.0"
|
||||||
|
refY="0.0"
|
||||||
|
orient="auto"
|
||||||
|
inkscape:stockid="DistanceStart"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<g
|
||||||
|
id="g2300"
|
||||||
|
style="stroke:#000000;stroke-opacity:1;fill:#ffffff;fill-opacity:1">
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;stroke:#000000;stroke-width:1.15;stroke-linecap:square;stroke-opacity:1;fill-opacity:1"
|
||||||
|
d="M 0,0 L 2,0"
|
||||||
|
id="path2306" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-opacity:1;fill-opacity:1"
|
||||||
|
d="M 0,0 L 13,4 L 9,0 13,-4 L 0,0 z "
|
||||||
|
id="path2302" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-opacity:1;fill-opacity:1"
|
||||||
|
d="M 0,-4 L 0,40"
|
||||||
|
id="path2304" />
|
||||||
|
</g>
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible;"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path4942"
|
||||||
|
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||||
|
style="fill-rule:evenodd;stroke:#ffffff;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||||
|
transform="scale(0.4) rotate(180) translate(10,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="Arrow2Lstart"
|
||||||
|
style="overflow:visible"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path4951"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#ffffff;stroke-opacity:1;fill:#ffffff;fill-opacity:1"
|
||||||
|
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||||
|
transform="scale(1.1) translate(1,0)" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.98994949"
|
||||||
|
inkscape:cx="545.48304"
|
||||||
|
inkscape:cy="160.38082"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
units="mm"
|
||||||
|
inkscape:pagecheckerboard="false"
|
||||||
|
inkscape:window-width="1366"
|
||||||
|
inkscape:window-height="709"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-200.99998)">
|
||||||
|
<rect
|
||||||
|
style="fill:#2e00d3;fill-opacity:1;stroke:none;stroke-width:0.79403234;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect4653"
|
||||||
|
width="170.6492"
|
||||||
|
height="95.87648"
|
||||||
|
x="0.17539978"
|
||||||
|
y="201.06174" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.5159505;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10"
|
||||||
|
width="5.0079031"
|
||||||
|
height="73.768311"
|
||||||
|
x="5.3582149"
|
||||||
|
y="218.42317" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.53897732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-6"
|
||||||
|
width="5.0171337"
|
||||||
|
height="80.351669"
|
||||||
|
x="10.361502"
|
||||||
|
y="211.85553" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.30675566;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-7"
|
||||||
|
width="5.0079031"
|
||||||
|
height="26.075878"
|
||||||
|
x="15.404671"
|
||||||
|
y="266.15738" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.28103706;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-5"
|
||||||
|
width="5.0079031"
|
||||||
|
height="21.886734"
|
||||||
|
x="20.412569"
|
||||||
|
y="270.34653" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.26525033;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-3"
|
||||||
|
width="5.0351334"
|
||||||
|
height="19.391466"
|
||||||
|
x="25.297941"
|
||||||
|
y="272.96432" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.24671662;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-56"
|
||||||
|
width="5.0351334"
|
||||||
|
height="16.776276"
|
||||||
|
x="30.333073"
|
||||||
|
y="275.57953" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.24395819;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-2"
|
||||||
|
width="5.1045647"
|
||||||
|
height="16.180122"
|
||||||
|
x="35.3335"
|
||||||
|
y="276.21039" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.23208007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-9"
|
||||||
|
width="5.0351334"
|
||||||
|
height="14.844803"
|
||||||
|
x="40.403351"
|
||||||
|
y="277.51099" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.21698384;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-1"
|
||||||
|
width="5.1315393"
|
||||||
|
height="12.732593"
|
||||||
|
x="45.390278"
|
||||||
|
y="279.67139" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.24474481;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-27"
|
||||||
|
width="5.0351334"
|
||||||
|
height="16.509188"
|
||||||
|
x="50.473614"
|
||||||
|
y="275.84659" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22369346;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-0"
|
||||||
|
width="5.0351334"
|
||||||
|
height="13.791304"
|
||||||
|
x="55.508751"
|
||||||
|
y="278.56448" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.19373304;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-93"
|
||||||
|
width="5.0351334"
|
||||||
|
height="10.344419"
|
||||||
|
x="60.543877"
|
||||||
|
y="282.01138" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.23857896;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-60"
|
||||||
|
width="5.0351334"
|
||||||
|
height="15.687835"
|
||||||
|
x="65.579018"
|
||||||
|
y="276.66797" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-62"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="70.614151"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-61"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="75.644226"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-8"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="80.674309"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-79"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="85.704399"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-20"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="90.734489"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-23"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="95.764587"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-75"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="100.79462"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-92"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="105.82474"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-28"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="110.85483"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-97"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="115.8849"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="120.91499"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-1"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="125.94507"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-2"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="130.97516"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-9"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="136.00525"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-3"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="141.03534"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.51674014;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-19"
|
||||||
|
width="5.0079031"
|
||||||
|
height="73.994278"
|
||||||
|
x="146.06543"
|
||||||
|
y="218.32138" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.52555859;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-19-4"
|
||||||
|
width="5.0079031"
|
||||||
|
height="76.541336"
|
||||||
|
x="151.07333"
|
||||||
|
y="215.77432" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.54030454;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-19-7"
|
||||||
|
width="5.0079031"
|
||||||
|
height="80.896736"
|
||||||
|
x="156.08124"
|
||||||
|
y="211.41893" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.52905655;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-19-8"
|
||||||
|
width="5.0079031"
|
||||||
|
height="77.563599"
|
||||||
|
x="161.08914"
|
||||||
|
y="214.75206" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.30675566;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-7-4"
|
||||||
|
width="5.0079031"
|
||||||
|
height="26.07588"
|
||||||
|
x="15.378635"
|
||||||
|
y="210.79721" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.28387639;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-3-5"
|
||||||
|
width="5.0351334"
|
||||||
|
height="22.210445"
|
||||||
|
x="25.470028"
|
||||||
|
y="206.0863" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.28517467;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-56-0"
|
||||||
|
width="5.0351334"
|
||||||
|
height="22.414066"
|
||||||
|
x="30.505161"
|
||||||
|
y="208.52849" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.31338966;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-2-3"
|
||||||
|
width="5.0351334"
|
||||||
|
height="27.068741"
|
||||||
|
x="35.540306"
|
||||||
|
y="206.51961" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.33414468;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-9-6"
|
||||||
|
width="5.0351334"
|
||||||
|
height="30.772858"
|
||||||
|
x="40.575436"
|
||||||
|
y="208.10709" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.32834858;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-1-1"
|
||||||
|
width="5.0351334"
|
||||||
|
height="29.714539"
|
||||||
|
x="45.610569"
|
||||||
|
y="205.46129" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.30311945;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-27-0"
|
||||||
|
width="5.0693293"
|
||||||
|
height="25.15283"
|
||||||
|
x="50.628605"
|
||||||
|
y="207.3943" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.2901814;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-0-6"
|
||||||
|
width="5.0351334"
|
||||||
|
height="23.208008"
|
||||||
|
x="55.680836"
|
||||||
|
y="208.2637" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.28728414;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-93-3"
|
||||||
|
width="5.0351334"
|
||||||
|
height="22.746889"
|
||||||
|
x="60.715961"
|
||||||
|
y="207.13734" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.31338966;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-60-2"
|
||||||
|
width="5.0351334"
|
||||||
|
height="27.068741"
|
||||||
|
x="65.751114"
|
||||||
|
y="204.93213" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.3009901;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-3-5-0"
|
||||||
|
width="5.047533"
|
||||||
|
height="24.907778"
|
||||||
|
x="20.422495"
|
||||||
|
y="208.15141" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.19651835;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-62-6"
|
||||||
|
width="5.0593157"
|
||||||
|
height="10.593125"
|
||||||
|
x="70.771629"
|
||||||
|
y="241.73154" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.20728494;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-61-1"
|
||||||
|
width="5.0485487"
|
||||||
|
height="11.810781"
|
||||||
|
x="75.807098"
|
||||||
|
y="244.00478" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-8-5"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="80.846413"
|
||||||
|
y="245.45027" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.27457732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-79-5"
|
||||||
|
width="4.9812565"
|
||||||
|
height="21.003906"
|
||||||
|
x="85.900917"
|
||||||
|
y="241.77057" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22912541;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-20-4"
|
||||||
|
width="5.0144625"
|
||||||
|
height="14.528869"
|
||||||
|
x="90.889984"
|
||||||
|
y="243.37294" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-23-7"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="95.842194"
|
||||||
|
y="246.47086" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.24984716;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-75-6"
|
||||||
|
width="5.014329"
|
||||||
|
height="17.2761"
|
||||||
|
x="100.88016"
|
||||||
|
y="245.42041" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-92-5"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="105.99683"
|
||||||
|
y="243.86279" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.23376569;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-28-6"
|
||||||
|
width="5.038465"
|
||||||
|
height="15.051262"
|
||||||
|
x="111.02273"
|
||||||
|
y="241.74196" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.27858368;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-97-9"
|
||||||
|
width="5.0064182"
|
||||||
|
height="21.51265"
|
||||||
|
x="116.06884"
|
||||||
|
y="237.88997" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.29652894;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-37"
|
||||||
|
width="4.9840579"
|
||||||
|
height="24.48278"
|
||||||
|
x="121.11011"
|
||||||
|
y="238.51682" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.30494329;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-1-4"
|
||||||
|
width="4.9643555"
|
||||||
|
height="25.994709"
|
||||||
|
x="126.15005"
|
||||||
|
y="239.5341" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.30701888;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-2-5"
|
||||||
|
width="4.9781718"
|
||||||
|
height="26.276651"
|
||||||
|
x="131.17323"
|
||||||
|
y="236.98726" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.33450949;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-9-2"
|
||||||
|
width="4.958868"
|
||||||
|
height="31.314398"
|
||||||
|
x="136.21298"
|
||||||
|
y="235.14709" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.3934584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-3-5"
|
||||||
|
width="4.9187098"
|
||||||
|
height="43.677338"
|
||||||
|
x="141.26314"
|
||||||
|
y="225.03587" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.28808108;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-62-4"
|
||||||
|
width="5.0459113"
|
||||||
|
height="22.824408"
|
||||||
|
x="70.778336"
|
||||||
|
y="206.51169" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.26175141;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-61-7"
|
||||||
|
width="4.9870887"
|
||||||
|
height="19.065166"
|
||||||
|
x="75.837822"
|
||||||
|
y="207.5735" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.25958091;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-8-4"
|
||||||
|
width="5.0300837"
|
||||||
|
height="18.590023"
|
||||||
|
x="80.846405"
|
||||||
|
y="206.26607" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.24191141;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-79-4"
|
||||||
|
width="5.0181313"
|
||||||
|
height="16.183794"
|
||||||
|
x="85.882469"
|
||||||
|
y="207.58391" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-20-3"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="90.906578"
|
||||||
|
y="208.1071" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-23-0"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="95.936684"
|
||||||
|
y="207.57793" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-75-7"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="100.96672"
|
||||||
|
y="207.04877" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.21416378;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-92-8"
|
||||||
|
width="5.0300837"
|
||||||
|
height="12.653961"
|
||||||
|
x="105.99683"
|
||||||
|
y="206.33833" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.18696997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-28-68"
|
||||||
|
width="5.0200224"
|
||||||
|
height="9.6637945"
|
||||||
|
x="111.03195"
|
||||||
|
y="207.37691" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.14067207;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-97-8"
|
||||||
|
width="5.0300837"
|
||||||
|
height="5.4594669"
|
||||||
|
x="116.057"
|
||||||
|
y="209.82872" />
|
||||||
|
<path
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.75189924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker5549)"
|
||||||
|
d="M 3.7041667,292.4141 V 204.96278"
|
||||||
|
id="path4931"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:5.82004309px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14550108"
|
||||||
|
x="5.1185122"
|
||||||
|
y="209.7113"
|
||||||
|
id="text5934"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan5932"
|
||||||
|
x="5.1185122"
|
||||||
|
y="209.7113"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Linux Libertine Display O';-inkscape-font-specification:'Linux Libertine Display O';fill:#ffffff;fill-opacity:1;stroke-width:0.14550108">z=42m</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:5.82004309px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14550108"
|
||||||
|
x="4.907176"
|
||||||
|
y="295.92572"
|
||||||
|
id="text5934-7"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="4.907176"
|
||||||
|
y="295.92572"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Linux Libertine Display O';-inkscape-font-specification:'Linux Libertine Display O';fill:#ffffff;fill-opacity:1;stroke-width:0.14550108"
|
||||||
|
id="tspan5954">z=0m</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 28 KiB |
BIN
Diapo/heightmapExample.png
Normal file
|
After Width: | Height: | Size: 136 KiB |
BIN
Diapo/hfractal.png
Normal file
|
After Width: | Height: | Size: 345 KiB |
BIN
Diapo/logoLafayette.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
98
Diapo/logo_lafayette.svg
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="371.862"
|
||||||
|
height="336.866"
|
||||||
|
viewBox="0 0 371.862 336.866"
|
||||||
|
version="1.1"
|
||||||
|
id="svg863"
|
||||||
|
sodipodi:docname="logo_lafayette.svg"
|
||||||
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||||
|
inkscape:export-filename="F:\Sonar\Diapo\logo_lafayette.svg.png"
|
||||||
|
inkscape:export-xdpi="92.800003"
|
||||||
|
inkscape:export-ydpi="92.800003">
|
||||||
|
<metadata
|
||||||
|
id="metadata869">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs867" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1280"
|
||||||
|
inkscape:window-height="962"
|
||||||
|
id="namedview865"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:zoom="0.97816438"
|
||||||
|
inkscape:cx="65.453353"
|
||||||
|
inkscape:cy="186.91296"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg863" />
|
||||||
|
<path
|
||||||
|
d="M 172.72,49.576 256.622,14.607 209.616,12.904 Z M 296.255,0 269.303,12.261 h 0.14 l 51.307,1.872 z"
|
||||||
|
id="path843"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#8c0a71" />
|
||||||
|
<path
|
||||||
|
d="m 31.366,111.525 45.861,29.02 3.938,-3.91 15.501,-15.362 0.028,-0.028 v -0.056 l 1.09,-37.343 -66.418,27.68 z m 1.62,4.33 v 0.027 l 15.613,53.151 v 0.028 l 22.064,-21.98 4.525,-4.498 -5.893,-3.714 -36.31,-23.015 z"
|
||||||
|
id="path845"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#ec7303" />
|
||||||
|
<path
|
||||||
|
d="m 99.04,263.605 h -0.028 l -37.482,-14.412 2.263,57.592 h 3.184 l 8.267,-11.116 z m 28.35,10.893 -0.028,-0.028 -25.612,-9.832 h -0.028 l -22.68,30.584 -8.602,11.563 h 74.043 z"
|
||||||
|
id="path847"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#77b827" />
|
||||||
|
<path
|
||||||
|
d="M 218.777,309.578 H 149.12 l 14.44,27.288 81.584,-17.15 -26.366,-10.138 z m -7.29,-2.793 -57.731,-22.177 -22.4,-8.602 16.283,30.779 64.044,0.084 z"
|
||||||
|
id="path849"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#079283" />
|
||||||
|
<path
|
||||||
|
d="m 330.05,306.785 h 29.69 l 12.122,-21.171 -41.811,21.17 z m -75.047,13.714 23.768,9.133 39.605,-20.054 H 226.57 l 28.433,10.92 z"
|
||||||
|
id="path851"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#046aa5" />
|
||||||
|
<path
|
||||||
|
d="m 99.543,118.368 h 0.028 l 14.999,-14.915 v -0.028 l 46.084,-45.805 -60.05,25.053 -1.06,35.695 z m 1.983,-66.725 -0.838,27.958 65.161,-27.148 0.056,-0.028 0.028,-0.028 23.21,-23.098 z"
|
||||||
|
id="path853"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#d30846" />
|
||||||
|
<path
|
||||||
|
d="M 47.258,174.34 0,221.32 57.117,208.835 h 0.028 l -0.056,-0.978 -9.831,-33.516 z m 78.344,0.168 -47.984,-30.388 -5.335,5.306 -22.79,22.652 v 0.028 l 10.39,35.471 0.027,0.642 88.455,-19.3 z m -3.687,-5.642 v -0.028 l -9.245,-59.547 -13.238,13.127 -2.877,2.849 v 0.028 l -16.898,16.785 7.066,4.469 35.192,22.316 z"
|
||||||
|
id="path859"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#f5ba0f" />
|
||||||
|
<path
|
||||||
|
d="m 152.36,190.93 h -0.057 l -92.28,20.138 1.396,35.08 39.325,15.139 h 0.028 l 31.924,-43.013 20.445,-27.511 v -0.028 l -0.782,0.196 z m -48.907,71.39 5.866,2.262 16.06,6.145 h 0.028 l 3.938,1.508 v 0.028 l 19.998,7.653 -17.652,-55.609 z M 57.117,244.268 V 211.833 L 2.391,223.32 Z"
|
||||||
|
id="path861"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="fill:#c7d504" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.0 KiB |
BIN
Diapo/minecraftGrottes.png
Normal file
|
After Width: | Height: | Size: 2.7 MiB |
BIN
Diapo/minecraftOcean.jpg
Normal file
|
After Width: | Height: | Size: 229 KiB |
BIN
Diapo/nemoCoraux.png
Normal file
|
After Width: | Height: | Size: 9.0 MiB |
365
Diapo/objection.py
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Created on Thu Aug 22 19:46:36 2019
|
||||||
|
|
||||||
|
@author: mysaa
|
||||||
|
"""
|
||||||
|
import numpy as np
|
||||||
|
from data import CollageWorldChunk
|
||||||
|
from perlin import CavernedNoise2,TestNoise
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def getTriangles(x0,y0,chunk,xp,yp,xy):
|
||||||
|
|
||||||
|
|
||||||
|
nx,ny = chunk.size
|
||||||
|
newChunk = CollageWorldChunk(chunk,xp,yp,xy)
|
||||||
|
|
||||||
|
# pointIndexes = np.zeros((nx+1,ny+1),dtype=np.uint32)
|
||||||
|
# pointLengthes = np.zeros((nx+1,ny+1),dtype=np.uint32)
|
||||||
|
# points = []
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# pos = 0
|
||||||
|
# for j in range(ny):
|
||||||
|
# for i in range(nx):
|
||||||
|
# carotte = [(x0+i/nx,y0+j/ny,z) for z in sorted([0.]+list(chunk.getColumn(i,j)))]
|
||||||
|
# points += carotte
|
||||||
|
# pointLengthes[i,j] = len(carotte)
|
||||||
|
# pointIndexes[i,j] = pos
|
||||||
|
# pos+=len(carotte)
|
||||||
|
# carotte = [(x0+1,y0+j/ny,z) for z in sorted([0.]+list(xp.getColumn(0,j)))]
|
||||||
|
# points += carotte
|
||||||
|
# pointLengthes[nx,j]= len(carotte)
|
||||||
|
# pointIndexes[nx,j] = pos
|
||||||
|
# pos+=len(carotte)
|
||||||
|
# for i in range(nx):
|
||||||
|
# carotte = [(x0+i/nx,y0+1,z) for z in sorted([0.]+list(yp.getColumn(i,0)))]
|
||||||
|
# points += carotte
|
||||||
|
# pointLengthes[i,ny] = len(carotte)
|
||||||
|
# pointIndexes[i,ny] = pos
|
||||||
|
# pos+=len(carotte)
|
||||||
|
# carotte = [(x0+1,y0+1,z) for z in sorted([0.]+list(xy.getColumn(0,0)))]
|
||||||
|
# points += carotte
|
||||||
|
# pointLengthes[nx,ny] = len(carotte)
|
||||||
|
# pointIndexes[nx,ny] = pos
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
points,pointIndexes = newChunk.getIndexed(fullCoords=True,addZero=True)
|
||||||
|
|
||||||
|
points=[(p[0]/nx+x0,p[1]/ny+y0,p[2]) for p in points]
|
||||||
|
pointLengthes = np.reshape([pointIndexes[i+1]-pointIndexes[i] for i in range(len(pointIndexes)-1)],(nx+1,ny+1))
|
||||||
|
pointIndexes = np.reshape(pointIndexes[:-1],(nx+1,ny+1))
|
||||||
|
print(points,pointIndexes,pointLengthes)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
triangles = []
|
||||||
|
|
||||||
|
|
||||||
|
for x in range(nx*2):
|
||||||
|
for y in range(ny):
|
||||||
|
# On récupère les coordonées entières du triangle indicé (x,y)
|
||||||
|
if(x%2==0):
|
||||||
|
col0=(x//2 ,y )
|
||||||
|
col1=(x//2+1,y )
|
||||||
|
col2=(x//2 ,y+1)
|
||||||
|
else:
|
||||||
|
col0=(x//2+1,y+1)
|
||||||
|
col1=(x//2+1,y )
|
||||||
|
col2=(x//2 ,y+1)
|
||||||
|
|
||||||
|
# On récupère la liste des points dans la colonne
|
||||||
|
colonne0 = points[pointIndexes[col0[0],col0[1]]:pointIndexes[col0[0],col0[1]]+pointLengthes[col0[0],col0[1]]]
|
||||||
|
colonne1 = points[pointIndexes[col1[0],col1[1]]:pointIndexes[col1[0],col1[1]]+pointLengthes[col1[0],col1[1]]]
|
||||||
|
colonne2 = points[pointIndexes[col2[0],col2[1]]:pointIndexes[col2[0],col2[1]]+pointLengthes[col2[0],col2[1]]]
|
||||||
|
#print("colonne:",colonne1)
|
||||||
|
# st contient des triplets (numéro de colonne,index interne dans la colonne,coordonée z)
|
||||||
|
st = [(0,i,colonne0[i][2]) for i in range(len(colonne0))]
|
||||||
|
st += [(1,i,colonne1[i][2]) for i in range(len(colonne1))]
|
||||||
|
st += [(2,i,colonne2[i][2]) for i in range(len(colonne2))]
|
||||||
|
|
||||||
|
|
||||||
|
# On y trie par coordonée z
|
||||||
|
st = sorted(st,key=lambda c:c[2])
|
||||||
|
|
||||||
|
#Liste des coordonées des colonnes, pour pouvoir sélectionner les coordonées selon l'index de la colonne
|
||||||
|
cols = [col0,col1,col2]
|
||||||
|
# Là, tout est bon à peu près
|
||||||
|
|
||||||
|
i=0
|
||||||
|
try:
|
||||||
|
while i<len(st):
|
||||||
|
v1 = st[i] ; i+=1
|
||||||
|
v2 = st[i] ; i+=1
|
||||||
|
if v1[0]==v2[0]: continue #Cas où une colonne apparait puis disparaît
|
||||||
|
v3 = st[i] ; i+=1
|
||||||
|
v4=v3 # Pour pouvoir observer le changement de colonne dans la chaine aller/retour 2/1
|
||||||
|
while v1[0]+v2[0]+v3[0]!=3:
|
||||||
|
# On est dans la chaine aller-retour 2/1
|
||||||
|
|
||||||
|
if v4[0]!=v3[0]:
|
||||||
|
# Les deux colonnes ont disparu
|
||||||
|
# On peut créer le rectangle v1,v2,v3,v4
|
||||||
|
triangle1 = [pointIndexes[cols[v[0]]] + v[1] for v in (v1,v2,v3)]
|
||||||
|
triangle2 = [pointIndexes[cols[v[0]]] + v[1] for v in (v1 if v1[0]==v3[0] else v2,v3,v4)]
|
||||||
|
triangles.append(triangle1)
|
||||||
|
triangles.append(triangle2)
|
||||||
|
break
|
||||||
|
v4=v3
|
||||||
|
v3 = st[i] ; i+=1
|
||||||
|
else:
|
||||||
|
# On est dans le cas ou v1,v2,v3 correspondent à trois colonnes
|
||||||
|
# différentes (le cas (1,1,1) ayant déjà été filtré par la première condition)
|
||||||
|
|
||||||
|
# On ajoute le triangle en dessous
|
||||||
|
triangle = [pointIndexes[cols[v[0]]] + v[1] for v in (v1,v2,v3)]
|
||||||
|
triangles.append(triangle)
|
||||||
|
|
||||||
|
# On "attends" jusqu'à ce que les trois colonnes soient à nouveau vides
|
||||||
|
vs = [None,None,None]
|
||||||
|
while None in vs:
|
||||||
|
v = st[i] ; i+=1
|
||||||
|
vs[v[0]] = v if vs[v[0]]==None else None
|
||||||
|
|
||||||
|
# Avec cette mthode, on déssine le triangle avec les derniers points étant apparus (les plus hauts)
|
||||||
|
triangle = [pointIndexes[cols[v[0]]] + v[1] for v in vs]
|
||||||
|
triangles.append(triangle)
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
# Une fin de liste a été atteinte, la colonne n'a pas été refermée: lance un warn
|
||||||
|
print("Attention ! Une colonne n'avait pas de toit. veuillez vérifier que vos colonnes aient un nombre impair de coordonées, merci !")
|
||||||
|
|
||||||
|
return points,triangles
|
||||||
|
########################################
|
||||||
|
# while i<len(st):
|
||||||
|
# #Plein
|
||||||
|
# v0 = st[i]
|
||||||
|
# i+=1
|
||||||
|
# v1 = st[i]
|
||||||
|
# i+=1
|
||||||
|
# if(v0[0] == v1[0]): # S'est la même colonne qui est apparu puis disparu
|
||||||
|
#
|
||||||
|
# print("Tribord")
|
||||||
|
# colz = cols[v0[0]]
|
||||||
|
# # Triangle sur les bords
|
||||||
|
# # Demis-points
|
||||||
|
# halfZ = (v0[2]+v1[2])/2
|
||||||
|
# #Les deux autres colonnes sont :
|
||||||
|
# cola = cols[(v0[0]+1)%3]
|
||||||
|
# colb = cols[(v0[0]+2)%3]
|
||||||
|
#
|
||||||
|
# zi1,zi2=pointIndexes[colz]+v0[1],pointIndexes[colz]+v1[1]
|
||||||
|
# print('OoOOoO',points[zi1],points[zi2])
|
||||||
|
#
|
||||||
|
## points.append( (x0+(cola[0])/nx,y0+(cola[1])/ny,halfZ) )
|
||||||
|
## points.append( (x0+(colb[0])/nx,y0+(colb[1])/ny,halfZ) )
|
||||||
|
##
|
||||||
|
## triangles.append([zi1,len(points)-1,len(points)-2])
|
||||||
|
## triangles.append([zi2,len(points)-1,len(points)-2])
|
||||||
|
# print("Tribord-fin")
|
||||||
|
# # print(points[-1],points[-2],points[zi1])
|
||||||
|
# #print(cola,colb,points[triangles[-1][0]-1],points[triangles[-1][1]-1],points[triangles[-1][2]-1])
|
||||||
|
#
|
||||||
|
# else: # Deux colonnes différentes ont apparus successivement
|
||||||
|
# # vs stoque les états des colonnes
|
||||||
|
# # vs[i] est l'état de la ième colonne, le point de st, dernier à apparaître si
|
||||||
|
# # cette colonne est présente, None sinon
|
||||||
|
# vs=[None,None,None]
|
||||||
|
# vs[v0[0]] = v0
|
||||||
|
# vs[v1[0]] = v1
|
||||||
|
# while None in vs and vs != [None,None,None]:# Tant qu'il y a une abscente ou une présente
|
||||||
|
# v2 = st[i]
|
||||||
|
# i+=1
|
||||||
|
# vs[v2[0]] = v2 if vs[v2[0]]==None else None
|
||||||
|
#
|
||||||
|
# if not None in vs:
|
||||||
|
# # Une face complète a été créée
|
||||||
|
# # Triangle complet
|
||||||
|
# # Face dessous (apparition de la colonne)
|
||||||
|
# triangle = [pointIndexes[cols[i]] + vs[i][1] for i in range(3)]
|
||||||
|
# triangles.append(triangle)
|
||||||
|
# #print("#",[points[triangle[i]] for i in range(0,3)])
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# # On inverse le sens de vs, et stoque les premiers points à apparaître
|
||||||
|
# vs = [None,None,None]
|
||||||
|
# while None in vs and i<len(st):
|
||||||
|
# v2 = st[i]
|
||||||
|
# i+=1
|
||||||
|
# vs[v2[0]] = v2 if vs[v2[0]]==None else None
|
||||||
|
#
|
||||||
|
# #Face dessus
|
||||||
|
# if not None in vs:
|
||||||
|
# triangle = [pointIndexes[cols[i]] + vs[i][1] for i in range(3)]
|
||||||
|
# triangles.append(triangle)
|
||||||
|
# #print("0",[points[triangle[i]] for i in range(3)])
|
||||||
|
# else:
|
||||||
|
# # Il faut placer un carré
|
||||||
|
# #########################################
|
||||||
|
# print(points)
|
||||||
|
# return points,triangles
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def getRectangles(x0,y0,chunk):
|
||||||
|
nx,ny = chunk.size
|
||||||
|
|
||||||
|
triangles = []
|
||||||
|
points = []
|
||||||
|
|
||||||
|
for x in range(nx) :
|
||||||
|
for y in range(ny):
|
||||||
|
for z in [0]+chunk.getColumn(x,y):
|
||||||
|
points.append([x/nx+x0,y/ny+y0,z])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0,z])
|
||||||
|
points.append([x/nx+x0,y/ny+y0+1/ny,z])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0+1/ny,z])
|
||||||
|
triangles.append([len(points)-4,len(points)-3,len(points)-2])
|
||||||
|
triangles.append([len(points)-3,len(points)-2,len(points)-1])
|
||||||
|
|
||||||
|
return points,triangles
|
||||||
|
|
||||||
|
def getRectCols(x0,y0,chunk):
|
||||||
|
nx,ny = chunk.size
|
||||||
|
|
||||||
|
triangles = []
|
||||||
|
points = []
|
||||||
|
e=0.3
|
||||||
|
|
||||||
|
for x in range(nx) :
|
||||||
|
for y in range(ny):
|
||||||
|
for z in [0]+chunk.getColumn(x,y):
|
||||||
|
points.append([x/nx+x0-e,y/ny+y0-e,z])
|
||||||
|
points.append([x/nx+x0+e,y/ny+y0-e,z])
|
||||||
|
points.append([x/nx+x0-e,y/ny+y0+e,z])
|
||||||
|
points.append([x/nx+x0+e,y/ny+y0+e/ny,z])
|
||||||
|
triangles.append([len(points)-4,len(points)-3,len(points)-2])
|
||||||
|
triangles.append([len(points)-3,len(points)-2,len(points)-1])
|
||||||
|
|
||||||
|
return points,triangles
|
||||||
|
|
||||||
|
|
||||||
|
def getFilled(x0,y0,chunk):
|
||||||
|
nx,ny = chunk.size
|
||||||
|
|
||||||
|
triangles = []
|
||||||
|
points = []
|
||||||
|
|
||||||
|
for x in range(nx) :
|
||||||
|
for y in range(ny):
|
||||||
|
boule = True
|
||||||
|
lz = 0
|
||||||
|
for z in sorted(chunk.getColumn(x,y)):
|
||||||
|
|
||||||
|
if boule:
|
||||||
|
points.append([x/nx+x0 ,y/ny+y0 ,z ])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0 ,z ])
|
||||||
|
points.append([x/nx+x0 ,y/ny+y0+1/ny,z ])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0+1/ny,z ])
|
||||||
|
points.append([x/nx+x0 ,y/ny+y0 ,lz])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0 ,lz])
|
||||||
|
points.append([x/nx+x0 ,y/ny+y0+1/ny,lz])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0+1/ny,lz])
|
||||||
|
l = len(points)
|
||||||
|
triangles.append([l-4,l-2,l-1])
|
||||||
|
triangles.append([l-4,l-3,l-1])
|
||||||
|
triangles.append([l-4,l-2,l-6])
|
||||||
|
triangles.append([l-4,l-8,l-6])
|
||||||
|
triangles.append([l-4,l-3,l-7])
|
||||||
|
triangles.append([l-4,l-8,l-7])
|
||||||
|
triangles.append([l-5,l-1,l-2])
|
||||||
|
triangles.append([l-5,l-6,l-2])
|
||||||
|
triangles.append([l-5,l-6,l-8])
|
||||||
|
triangles.append([l-5,l-7,l-8])
|
||||||
|
triangles.append([l-5,l-7,l-3])
|
||||||
|
triangles.append([l-5,l-1,l-3])
|
||||||
|
|
||||||
|
boule = not boule
|
||||||
|
lz = z
|
||||||
|
|
||||||
|
|
||||||
|
return points,triangles
|
||||||
|
|
||||||
|
def printObject(file,name,delta,points,triangles):
|
||||||
|
file.write("o "+name+"\n\n")
|
||||||
|
|
||||||
|
sf = lambda x : "%.6f" % float(x)
|
||||||
|
si = lambda x : str(int(x+1)+delta)
|
||||||
|
|
||||||
|
for p in points:
|
||||||
|
file.write("v "+sf(p[0])+" "+sf(p[1])+" "+sf(np.array(p[2])/20.)+"\n")
|
||||||
|
|
||||||
|
file.write("\n")
|
||||||
|
|
||||||
|
for t in triangles:
|
||||||
|
file.write("f "+" ".join([si(tp) for tp in t])+"\n")
|
||||||
|
|
||||||
|
|
||||||
|
def writeMap(filePath,noise,x0,y0,sx,sy,cx,cy,objType='triangle',log=print):
|
||||||
|
log("Génération de la carte")
|
||||||
|
generated = {}
|
||||||
|
formatter='\rÉcriture du chunk {};{} '+" "*(sx//10+sy//10)
|
||||||
|
for i in range(x0,sx+x0+(1 if objType=='triangle' else 0)):
|
||||||
|
for j in range(y0,sy+y0+(1 if objType=='triangle' else 0)):
|
||||||
|
log(formatter.format(i,j), end='\r')
|
||||||
|
generated[(i,j)] = noise.getChunk(i,j,(cx,cy))
|
||||||
|
log("Génération des objets")
|
||||||
|
file = open(filePath,"w+")
|
||||||
|
file.write("g carte\n")
|
||||||
|
delta=0
|
||||||
|
for i in range(x0,sx+x0):
|
||||||
|
for j in range(y0,sy+y0):
|
||||||
|
log(formatter.format(i,j), end='\r')
|
||||||
|
if objType=='triangle':
|
||||||
|
points,triangles = getTriangles(i,j,generated[(i,j)],generated[(i+1,j)],generated[(i,j+1)],generated[(i+1,j+1)])
|
||||||
|
elif objType=='rectangle':
|
||||||
|
points,triangles = getRectangles(i,j,generated[(i,j)])
|
||||||
|
elif objType=='filled':
|
||||||
|
points,triangles = getFilled(i,j,generated[(i,j)])
|
||||||
|
elif objType=='rectcols':
|
||||||
|
points,triangles = getRectCols(i,j,generated[(i,j)])
|
||||||
|
else:
|
||||||
|
raise ValueError("Je en connais pas le type d'objet "+objType)
|
||||||
|
printObject(file,"chunk_"+objType+"_"+str(i)+"-"+str(j),delta,points,triangles)
|
||||||
|
file.write("\n\n")
|
||||||
|
delta+=len(points)
|
||||||
|
log("\nTerminé ! "+" "*(sx//10+sy//10))
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
noise = CavernedNoise2(93152)
|
||||||
|
|
||||||
|
size = 12
|
||||||
|
taille=16
|
||||||
|
|
||||||
|
#writeMap("gros.obj",noise,-size//2+1,-size//2+1,size,size,taille,taille,'triangle')
|
||||||
|
#writeMap("carte.obj",noise,2,1,1,1,4,4,'triangle')
|
||||||
|
#writeMap("carteTri.obj",noise,-8,-8,16,16,16,16,'triangle')
|
||||||
|
writeMap("carteRec.obj",noise,-8,-8,16,16,16,16,'rectangle')
|
||||||
|
writeMap("carteFil.obj",noise,-8,-8,16,16,16,16,'filled')
|
||||||
|
writeMap("carteRCo.obj",noise,-8,-8,16,16,16,16,'rectcols')
|
||||||
|
|
||||||
|
#xy0=-taille*size
|
||||||
|
#for x in range(2*taille):
|
||||||
|
# for y in range(2*taille):
|
||||||
|
#
|
||||||
|
# writeMap("render2/carte"+str(x)+","+str(y)+".obj",noise,xy0-size//2+x*size,xy0-size//2+y*size,size,size,'rectangle')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
Diapo/perlin.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
465
Diapo/perlin.py
Normal file
@ -0,0 +1,465 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Created on Fri Mar 8 15:13:12 2019
|
||||||
|
|
||||||
|
Ce module contient de nombreuses implémentations de Noise, permetant en les assemblant de créer des mondes
|
||||||
|
|
||||||
|
@author: mysaa
|
||||||
|
"""
|
||||||
|
|
||||||
|
from data import ArrayedWorldChunk,Noise
|
||||||
|
import random as r
|
||||||
|
import numpy as np
|
||||||
|
import sys
|
||||||
|
import matplotlib.pyplot as pp
|
||||||
|
import matplotlib.image as img
|
||||||
|
from mpl_toolkits.mplot3d import Axes3D
|
||||||
|
from math import sqrt,floor,ceil,pi
|
||||||
|
|
||||||
|
|
||||||
|
##### Paramètres #####
|
||||||
|
G = 4.5
|
||||||
|
F = 5.2
|
||||||
|
|
||||||
|
|
||||||
|
class RandNoise(Noise):
|
||||||
|
"""
|
||||||
|
Ce bruit renvoie une carte de vecteurs complexes (2d) du cercle trigonométrique (de module 1)
|
||||||
|
"""
|
||||||
|
seed = None
|
||||||
|
f = None
|
||||||
|
|
||||||
|
def __init__(self,seed,f=lambda r : r.random()):
|
||||||
|
self.seed = seed
|
||||||
|
self.f = f
|
||||||
|
|
||||||
|
def getRandomly(self,xg,yg):
|
||||||
|
"""
|
||||||
|
Cette fonction renvoie un nombre complexe aléatoire du cercle
|
||||||
|
trigonométrique, uniformément distribué selon l'argument.
|
||||||
|
Cette fonction est déterministe pour un même seed demandé.
|
||||||
|
"""
|
||||||
|
s = ((self.seed & 0xFFFFFFFFFFFFFFFF) << 64) | ((int(xg) & 0xFFFFFFFF) << 32) | (int(yg) & 0xFFFFFFFF)
|
||||||
|
r.seed(s)
|
||||||
|
return self.f(r)
|
||||||
|
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
"""
|
||||||
|
x,y sont les coordonées du chunk à considérer (boucle au bout de 4294967296=2^32) java:int
|
||||||
|
n est un couple ou une liste d'aumoins deux éléments contenant la précision suivant x et y du chunk
|
||||||
|
"""
|
||||||
|
randomizer = lambda i,j : self.getRandomly(x+i,y+j)
|
||||||
|
|
||||||
|
return np.fromfunction(np.vectorize(randomizer),(n[0],n[1]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class RandLinNoise(RandNoise):
|
||||||
|
|
||||||
|
y0 = 0
|
||||||
|
y1 = 1
|
||||||
|
|
||||||
|
def __init__(self,seed,y0,y1):
|
||||||
|
super().__init__(seed,lambda r : (y1-y0)*r.random() + y0)
|
||||||
|
|
||||||
|
class RandTrigNoise(RandNoise):
|
||||||
|
|
||||||
|
def __init__(self,seed):
|
||||||
|
super().__init__(seed,lambda r : np.exp(1j*2*pi*r.random()))
|
||||||
|
|
||||||
|
class DroiteNoise(Noise):
|
||||||
|
|
||||||
|
seed = None
|
||||||
|
F,D = 0,0
|
||||||
|
|
||||||
|
def __init__(self,seed,F,D):
|
||||||
|
self.seed = seed
|
||||||
|
self.F,self.D = F,D
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n=None):
|
||||||
|
|
||||||
|
return self.getLoadedDroites(x,y)
|
||||||
|
|
||||||
|
# randomizer = lambda i,j : self.getRandomGradient(x+i,y+j)
|
||||||
|
#
|
||||||
|
# return np.fromfunction(np.vectorize(randomizer),(n,))
|
||||||
|
|
||||||
|
def getLoadedDroites(self,x,y):
|
||||||
|
"""
|
||||||
|
Cette fonction renvoie la liste des droites devant être considérées dans la génération du chunk x,y. Cela permet d'effectuer la génération procédurale.
|
||||||
|
"""
|
||||||
|
def dst(x0,x1,y0,y1):
|
||||||
|
"""
|
||||||
|
Cette fonction renvoie la ditance eucildienne 2D entre les points (x0,y0) et (x1,y1)
|
||||||
|
"""
|
||||||
|
return sqrt( (x1-x0)**2 + (y1-y0)**2 )
|
||||||
|
|
||||||
|
F = self.F
|
||||||
|
x0 = floor(x-F)
|
||||||
|
x1 = floor(x+F+1)
|
||||||
|
y0 = floor(y-F)
|
||||||
|
y1 = floor(y+F+1)
|
||||||
|
# print(x0,x1,y0,y1)
|
||||||
|
drts = []
|
||||||
|
for i in range(x0,x1+1):
|
||||||
|
for j in range(y0,y1+1):
|
||||||
|
for d in self.getDroitesOnChunk(i,j):
|
||||||
|
# Tester si la droite sera utile
|
||||||
|
dx = d[0]+i
|
||||||
|
dy = d[1]+j
|
||||||
|
if (x <= dx <= x+1 and y-F <= dy <= y+F+1) or (y <= dy <= y+1 and x-F <= dx <= x+F+1) or (min(dst(x,dx,y,dy),dst(x+1,dx,y,dy),dst(x+1,dx,y+1,dy),dst(x,dx,y+1,dy)) <= F):
|
||||||
|
drts.append((dx,dy,d[2]))
|
||||||
|
# print(len(drts))
|
||||||
|
return drts
|
||||||
|
|
||||||
|
|
||||||
|
def getDroitesOnChunk(self,xg,yg):
|
||||||
|
s = ((self.seed & 0xFFFFFFFFFFFFFFFF) << 64) | ((int(xg) & 0xFFFFFFFF) << 32) | (int(yg) & 0xFFFFFFFF)
|
||||||
|
r.seed(s)
|
||||||
|
L = []
|
||||||
|
for i in range(self.D):
|
||||||
|
lx = r.random()
|
||||||
|
ly = r.random()
|
||||||
|
theta = r.random()*2*pi
|
||||||
|
L.append((lx,ly,theta))
|
||||||
|
return L
|
||||||
|
|
||||||
|
|
||||||
|
class PerlinNoise(Noise):
|
||||||
|
|
||||||
|
G = None
|
||||||
|
randomizer = None
|
||||||
|
interpol = None
|
||||||
|
wrapper = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self,G,randomizer,interpol=lambda a,b,w : (b-a)*w**2*6*(1/2-w/3)+a,wrapper = lambda x : np.tanh(x*3.8622)): # Par défaut, un banale interpolation linéaire
|
||||||
|
self.G = G
|
||||||
|
if type(randomizer) == int:
|
||||||
|
randomizer = RandTrigNoise(randomizer)
|
||||||
|
self.randomizer = randomizer
|
||||||
|
self.interpol = interpol
|
||||||
|
self.wrapper = wrapper
|
||||||
|
|
||||||
|
def getChunkGradients(self,x,y):
|
||||||
|
G=self.G # Python de merde !
|
||||||
|
x0 = floor(x/G)
|
||||||
|
x1 = ceil((x+1)/G)
|
||||||
|
y0 = floor(y/G)
|
||||||
|
y1 = ceil((y+1)/G)
|
||||||
|
nx = x1-x0+1
|
||||||
|
ny = y1-y0+1
|
||||||
|
# grads = np.fromfunction(np.vectorize(lambda x,y : self.getPerlinGradient(x+x0,y+y0)),(nx,ny))
|
||||||
|
grads = self.randomizer.getChunk(x0,y0,(nx,ny))
|
||||||
|
return grads,x0,y0
|
||||||
|
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
|
||||||
|
G = self.G
|
||||||
|
chunk = np.zeros(n) # Initialise la sortie
|
||||||
|
|
||||||
|
gradients,x0,y0 = self.getChunkGradients(x,y)
|
||||||
|
|
||||||
|
def dotGridGradient(ix, iy, tx, ty):
|
||||||
|
dx = tx - ix
|
||||||
|
dy = ty - iy
|
||||||
|
return (np.conj(gradients[ix-x0][iy-y0])*(dx+1j*dy)).real
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(n[0]):
|
||||||
|
for j in range(n[1]):
|
||||||
|
#C------------D#
|
||||||
|
#| |#
|
||||||
|
#| |#
|
||||||
|
#| |#
|
||||||
|
#| x M |#
|
||||||
|
#| |#
|
||||||
|
#A------------B#
|
||||||
|
posx = x + i/n[0]
|
||||||
|
posy = y + j/n[1]
|
||||||
|
xx = posx / G
|
||||||
|
yy = posy / G
|
||||||
|
xx0 = floor(xx)
|
||||||
|
yy0 = floor(yy)
|
||||||
|
xx1 = xx0 + 1
|
||||||
|
yy1 = yy0 + 1
|
||||||
|
|
||||||
|
|
||||||
|
gA = dotGridGradient(xx0, yy0, xx, yy);
|
||||||
|
gB = dotGridGradient(xx1, yy0, xx, yy);
|
||||||
|
gC = dotGridGradient(xx0, yy1, xx, yy);
|
||||||
|
gD = dotGridGradient(xx1, yy1, xx, yy);
|
||||||
|
haut = self.interpol(gA, gB, xx - xx0);
|
||||||
|
bas = self.interpol(gC, gD, xx - xx0);
|
||||||
|
valeur = self.interpol(haut, bas, yy - yy0);
|
||||||
|
|
||||||
|
chunk[i,j] = valeur
|
||||||
|
|
||||||
|
return self.wrapper(chunk)
|
||||||
|
|
||||||
|
class FractalNoise(Noise):
|
||||||
|
|
||||||
|
F = None
|
||||||
|
D = None
|
||||||
|
epsilon = None
|
||||||
|
interpol = None
|
||||||
|
droiteMaker = None
|
||||||
|
|
||||||
|
def interpolizer(n,F):
|
||||||
|
"""
|
||||||
|
Retourne une fonction polynomiale réelle sur [-F,F] et nulle autre part, s'annule en F et -F, vaut 1 en 0 et a comme dérivée 0 en -F,0 et F. n+1 est le degré de la racine 0.
|
||||||
|
"""
|
||||||
|
return lambda x : 0 if abs(x)>F else 1 + (2*n**2+6*n+4)/(F**(2*n+4)) * ((x**2)/(2*n+4)-(F**2)/(2*n+2))*abs(x)**(2*n+2)
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self,F,D,epsilon,droiteMaker,n = 1):
|
||||||
|
self.F = F
|
||||||
|
self.D = D
|
||||||
|
self.epsilon = epsilon
|
||||||
|
if type(droiteMaker) == int:
|
||||||
|
droiteMaker = DroiteNoise(droiteMaker,F,D)
|
||||||
|
self.droiteMaker = droiteMaker
|
||||||
|
self.interpol = FractalNoise.interpolizer(n,F)
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
drts = self.droiteMaker.getChunk(x,y)
|
||||||
|
chunk = np.zeros(n)
|
||||||
|
epsilon = self.epsilon
|
||||||
|
interpol = self.interpol
|
||||||
|
|
||||||
|
def dst(x0,x1,y0,y1):
|
||||||
|
return sqrt( (x1-x0)**2 + (y1-y0)**2 )
|
||||||
|
|
||||||
|
def kelkote(drt,x,y):
|
||||||
|
dx = drt[0]
|
||||||
|
dy = drt[1]
|
||||||
|
#print(x,y,dx,dy)
|
||||||
|
return 1 if (np.exp(1j*(drt[2]+pi/2)) * ((x-dx)+(dy-y)*1j)).real >= 0 else -1
|
||||||
|
|
||||||
|
# FractalNoise(0.7,511,0.01,42).getChunk(3,3,(16,16))
|
||||||
|
#33.8 s ± 72.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
|
||||||
|
for d in drts:
|
||||||
|
drteffect = lambda i,j : interpol(dst(d[0],i/n[0] + x,d[1],j/n[1] + y))*kelkote(d,i/n[0] + x,j/n[1] + y)*epsilon
|
||||||
|
chunk += np.fromfunction(np.vectorize(drteffect),n)
|
||||||
|
|
||||||
|
# FractalNoise(0.7,511,0.01,42).getChunk(3,3,(16,16))
|
||||||
|
#28.9 s ± 344 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
|
||||||
|
# for i in range(n[0]):
|
||||||
|
# for j in range(n[1]):
|
||||||
|
# posx = i/n[0] + x
|
||||||
|
# posy = j/n[1] + y
|
||||||
|
# value = 0
|
||||||
|
## print(i,j)
|
||||||
|
# for d in drts:
|
||||||
|
# value += interpol(dst(d[0],posx,d[1],posy))*kelkote(d,posx,posy)*epsilon
|
||||||
|
# chunk[i,j] = value
|
||||||
|
return chunk
|
||||||
|
|
||||||
|
|
||||||
|
class TestNoise(Noise):
|
||||||
|
|
||||||
|
nn = PerlinNoise
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
|
||||||
|
indexes = np.array([i for i in range(n[0]*n[1]+1)])
|
||||||
|
data = np.ones((n[0]*n[1]))
|
||||||
|
return WorldChunk(n,indexes,data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CavernedNoise(Noise):
|
||||||
|
|
||||||
|
perlinSurface = None
|
||||||
|
perlinGrotte = None
|
||||||
|
perlinFond = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.perlinSurface = PerlinNoise(.5,64)
|
||||||
|
self.perlinGrotte = PerlinNoise(7 ,77)
|
||||||
|
self.perlinFond = PerlinNoise(.3 ,23)
|
||||||
|
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
chk = self.perlinSurface.getChunk(x,y,n)
|
||||||
|
fond = self.perlinFond.getChunk(x,y,n)
|
||||||
|
grotte=self.perlinGrotte.getChunk(x,y,n)
|
||||||
|
|
||||||
|
out = []
|
||||||
|
|
||||||
|
for i in range(n[0]):
|
||||||
|
lig = []
|
||||||
|
for j in range(n[1]):
|
||||||
|
if(grotte[i,j]>.2): # Pas de grotte
|
||||||
|
lig.append([chk[i,j]])
|
||||||
|
elif(grotte[i,j]>0):
|
||||||
|
lig.append([fond[i,j]])
|
||||||
|
else:
|
||||||
|
lig.append([fond[i,j],chk[i,j]-0.1*abs(grotte[i,j]),chk[i,j]])
|
||||||
|
out.append(lig)
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
class CavernedNoise2(Noise):
|
||||||
|
|
||||||
|
perlinCielH = None
|
||||||
|
perlinGHaut = None
|
||||||
|
perlinGH = None
|
||||||
|
perlinGHp = None
|
||||||
|
perlinGBas = None
|
||||||
|
|
||||||
|
#-x^(4)+4x^(3)-6x^(2)+4x
|
||||||
|
|
||||||
|
def __init__(self,seed):
|
||||||
|
self.perlinCielH = PerlinNoise(7 ,seed)
|
||||||
|
self.perlinGHaut = PerlinNoise(5 ,seed)
|
||||||
|
self.perlinGH = PerlinNoise(25 ,seed)
|
||||||
|
self.perlinGHp = PerlinNoise(1 ,seed)
|
||||||
|
self.perlinGBas = PerlinNoise(5 ,seed)
|
||||||
|
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
gtTransform = np.vectorize(lambda x : 0 if x<0 else sqrt(2*x-x**2)**1.5)
|
||||||
|
transform=lambda M,a,b : M*b+a
|
||||||
|
cielH = transform(self.perlinCielH.getChunk(x,y,n),28,28)
|
||||||
|
gHaut = transform(self.perlinGHaut.getChunk(x,y,n),60,20)
|
||||||
|
ghp = transform(self.perlinGHp.getChunk(x,y,n) ,0.005,0.005)
|
||||||
|
ghh = transform(self.perlinGHp.getChunk(x,y,n) ,0.5,0.5)
|
||||||
|
gBas = transform(self.perlinGBas.getChunk(x,y,n),10,10)
|
||||||
|
gh = gtTransform(ghp+ghh)
|
||||||
|
|
||||||
|
toit = 128
|
||||||
|
|
||||||
|
out = []
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(n[0]):
|
||||||
|
lig = []
|
||||||
|
for j in range(n[1]):
|
||||||
|
ch = cielH[i,j] # la hauteur entre la surface et le ciel
|
||||||
|
ght = gHaut[i,j] # haut limite de la grotte
|
||||||
|
gbs = gBas[i,j] # bas limite de la grotte
|
||||||
|
hauteur=gh[i,j] # pourcentage de hauteur de la grotte
|
||||||
|
grh = (ght+gbs +hauteur*(ght-gbs))/2 # vrai plafond de la grotte
|
||||||
|
grb = (ght+gbs -hauteur*(ght-gbs))/2 # vrai sol de la grotte
|
||||||
|
if(ght<=40):print(ght)
|
||||||
|
if hauteur==0:
|
||||||
|
# Pas de grotte
|
||||||
|
lig.append([toit-ch])
|
||||||
|
elif(grh+ch>=toit):
|
||||||
|
# La grotte est ouverte sur la surface
|
||||||
|
lig.append([grb])
|
||||||
|
else:
|
||||||
|
# Grotte souterraine et surface
|
||||||
|
lig.append([grb,grh,toit-ch])
|
||||||
|
|
||||||
|
out.append(lig)
|
||||||
|
|
||||||
|
return ArrayedWorldChunk.fromList(out)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#for c in cmaps:
|
||||||
|
# pp.figure()
|
||||||
|
# print(c)
|
||||||
|
# pp.imshow(I, cmap=c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#sys.exit()
|
||||||
|
####### Fenêtre graphique #######
|
||||||
|
#from PyQt5.QtWidgets import QVBoxLayout,QHBoxLayout,QPushButton,QWidget,QApplication,QFormLayout,QLabel,QTextEdit,QDial
|
||||||
|
#
|
||||||
|
#app = QApplication([])
|
||||||
|
#
|
||||||
|
#class ExplorerWidget(QWidget):
|
||||||
|
#
|
||||||
|
# def __init__():
|
||||||
|
# print('wow')
|
||||||
|
#
|
||||||
|
##### Control Panel ####
|
||||||
|
#seedSelector = QTextEdit()
|
||||||
|
#ndroitesSelector = QDial()
|
||||||
|
#
|
||||||
|
#cPanel = QFormLayout()
|
||||||
|
#cPanel.addWidget(QLabel("Seed : "))
|
||||||
|
#cPanel.addWidget(seedSelector)
|
||||||
|
#cPanel.addWidget(QLabel("Nombre de droites :"))
|
||||||
|
#cPanel.addWidget(ndroitesSelector)
|
||||||
|
#
|
||||||
|
#globalL = QHBoxLayout()
|
||||||
|
#globalL.addStretch(1)
|
||||||
|
#globalL.addLayout(cPanel)
|
||||||
|
#
|
||||||
|
#window = QWidget()
|
||||||
|
#window.setLayout(globalL)
|
||||||
|
#window.show()
|
||||||
|
#
|
||||||
|
#app.exec_()
|
||||||
|
|
||||||
|
#
|
||||||
|
#(x0,x1,y0,y1) = (0,4,0,4)
|
||||||
|
#n = 100
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#x = np.linspace(x0,x1,n)
|
||||||
|
#y = np.linspace(y0,y1,n)
|
||||||
|
#x00 = int(x0)-1
|
||||||
|
#y00 = int(y0)-1
|
||||||
|
#x11 = int(x1)+1
|
||||||
|
#y11 = int(y1)+1
|
||||||
|
#gradient = np.exp(np.random.rand(x11-x00+1,y11-y00+1)*2*np.pi*1j)
|
||||||
|
#X,Y = np.meshgrid(x,y)
|
||||||
|
##print(gradient)
|
||||||
|
#
|
||||||
|
#def lerp(a0, a1, w):
|
||||||
|
# return a0 + (a1-a0)*(-2*w*w*w+3*w*w)
|
||||||
|
#
|
||||||
|
#def dotGridGradient(ix, iy, x, y):
|
||||||
|
# dx = x - ix
|
||||||
|
# dy = y - iy
|
||||||
|
# return (np.conj(gradient[iy-y00][ix-x00])*(dx+1j*dy)).real
|
||||||
|
#
|
||||||
|
#def bruit(x,y):
|
||||||
|
# (x0,y0) = (int(x),int(y))
|
||||||
|
# (x1,y1) = (x0+1,y0+1)
|
||||||
|
#
|
||||||
|
# sx = x - x0;
|
||||||
|
# sy = y - y0;
|
||||||
|
#
|
||||||
|
# n0 = dotGridGradient(x0, y0, x, y);
|
||||||
|
# n1 = dotGridGradient(x1, y0, x, y);
|
||||||
|
# ix0 = lerp(n0, n1, sx);
|
||||||
|
# n0 = dotGridGradient(x0, y1, x, y);
|
||||||
|
# n1 = dotGridGradient(x1, y1, x, y);
|
||||||
|
# ix1 = lerp(n0, n1, sx);
|
||||||
|
# return lerp(ix0, ix1, sy);
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#Z = np.zeros((n,n))
|
||||||
|
#for i in range(n):
|
||||||
|
# for j in range(n):
|
||||||
|
# Z[i,j] = bruit(x[i],y[j])
|
||||||
|
#
|
||||||
|
#pp.imshow(Z,cmap='autumn')
|
||||||
|
#
|
||||||
|
#fig = pp.figure()
|
||||||
|
#ax = pp.axes(projection='3d')
|
||||||
|
#
|
||||||
|
#ax.view_init(80, 42)
|
||||||
|
#ax.plot_surface(X,Y,Z, rstride=1, cstride=1,
|
||||||
|
# cmap='autumn', edgecolor='none')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
137
Diapo/pythonhighlight.sty
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
\NeedsTeXFormat{LaTeX2e}
|
||||||
|
\ProvidesPackage{pythonhighlight}[2011/09/19 python code highlighting; provided by Olivier Verdier <olivier.verdier@gmail.com>]
|
||||||
|
|
||||||
|
|
||||||
|
\RequirePackage{listings}
|
||||||
|
\RequirePackage{xcolor}
|
||||||
|
|
||||||
|
\renewcommand*{\lstlistlistingname}{Code Listings}
|
||||||
|
\renewcommand*{\lstlistingname}{Code Listing}
|
||||||
|
\definecolor{gray}{gray}{0.5}
|
||||||
|
\colorlet{commentcolour}{green!50!black}
|
||||||
|
|
||||||
|
\colorlet{stringcolour}{red!60!black}
|
||||||
|
\colorlet{keywordcolour}{magenta!90!black}
|
||||||
|
\colorlet{exceptioncolour}{yellow!50!red}
|
||||||
|
\colorlet{commandcolour}{blue!60!black}
|
||||||
|
\colorlet{numpycolour}{blue!60!green}
|
||||||
|
\colorlet{literatecolour}{magenta!90!black}
|
||||||
|
\colorlet{promptcolour}{green!50!black}
|
||||||
|
\colorlet{specmethodcolour}{violet}
|
||||||
|
|
||||||
|
\newcommand*{\framemargin}{3ex}
|
||||||
|
|
||||||
|
\newcommand*{\literatecolour}{\textcolor{literatecolour}}
|
||||||
|
|
||||||
|
\newcommand*{\pythonprompt}{\textcolor{promptcolour}{{>}{>}{>}}}
|
||||||
|
|
||||||
|
\lstdefinestyle{mypython}{
|
||||||
|
%\lstset{
|
||||||
|
%keepspaces=true,
|
||||||
|
language=python,
|
||||||
|
showtabs=true,
|
||||||
|
tab=,
|
||||||
|
tabsize=2,
|
||||||
|
basicstyle=\ttfamily\footnotesize,%\setstretch{.5},
|
||||||
|
stringstyle=\color{stringcolour},
|
||||||
|
showstringspaces=false,
|
||||||
|
alsoletter={1234567890},
|
||||||
|
otherkeywords={\%, \}, \{, \&, \|},
|
||||||
|
keywordstyle=\color{keywordcolour}\bfseries,
|
||||||
|
emph={and,break,class,continue,def,yield,del,elif ,else,%
|
||||||
|
except,exec,finally,for,from,global,if,import,in,%
|
||||||
|
lambda,not,or,pass,print,raise,return,try,while,assert,with},
|
||||||
|
emphstyle=\color{blue}\bfseries,
|
||||||
|
emph={[2]True, False, None},
|
||||||
|
emphstyle=[2]\color{keywordcolour},
|
||||||
|
emph={[3]object,type,isinstance,copy,deepcopy,zip,enumerate,reversed,list,set,len,dict,tuple,xrange,append,execfile,real,imag,reduce,str,repr},
|
||||||
|
emphstyle=[3]\color{commandcolour},
|
||||||
|
emph={Exception,NameError,IndexError,SyntaxError,TypeError,ValueError,OverflowError,ZeroDivisionError},
|
||||||
|
emphstyle=\color{exceptioncolour}\bfseries,
|
||||||
|
%upquote=true,
|
||||||
|
morecomment=[s]{"""}{"""},
|
||||||
|
commentstyle=\color{commentcolour}\slshape,
|
||||||
|
%emph={[4]1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
|
||||||
|
emph={[4]ode, fsolve, sqrt, exp, sin, cos,arctan, arctan2, arccos, pi, array, norm, solve, dot, arange, isscalar, max, sum, flatten, shape, reshape, find, any, all, abs, plot, linspace, legend, quad, polyval,polyfit, hstack, concatenate,vstack,column_stack,empty,zeros,ones,rand,vander,grid,pcolor,eig,eigs,eigvals,svd,qr,tan,det,logspace,roll,min,mean,cumsum,cumprod,diff,vectorize,lstsq,cla,eye,xlabel,ylabel,squeeze},
|
||||||
|
emphstyle=[4]\color{numpycolour},
|
||||||
|
emph={[5]__init__,__add__,__mul__,__div__,__sub__,__call__,__getitem__,__setitem__,__eq__,__ne__,__nonzero__,__rmul__,__radd__,__repr__,__str__,__get__,__truediv__,__pow__,__name__,__future__,__all__},
|
||||||
|
emphstyle=[5]\color{specmethodcolour},
|
||||||
|
emph={[6]assert,yield},
|
||||||
|
emphstyle=[6]\color{keywordcolour}\bfseries,
|
||||||
|
emph={[7]range},
|
||||||
|
emphstyle={[7]\color{keywordcolour}\bfseries},
|
||||||
|
% emph={[7]self},
|
||||||
|
% emphstyle=[7]\bfseries,
|
||||||
|
literate=*%
|
||||||
|
{:}{{\literatecolour:}}{1}%
|
||||||
|
{=}{{\literatecolour=}}{1}%
|
||||||
|
{-}{{\literatecolour-}}{1}%
|
||||||
|
{+}{{\literatecolour+}}{1}%
|
||||||
|
{*}{{\literatecolour*}}{1}%
|
||||||
|
{**}{{\literatecolour{**}}}2%
|
||||||
|
{/}{{\literatecolour/}}{1}%
|
||||||
|
{//}{{\literatecolour{//}}}2%
|
||||||
|
{!}{{\literatecolour!}}{1}%
|
||||||
|
%{(}{{\literatecolour(}}{1}%
|
||||||
|
%{)}{{\literatecolour)}}{1}%
|
||||||
|
{[}{{\literatecolour[}}{1}%
|
||||||
|
{]}{{\literatecolour]}}{1}%
|
||||||
|
{<}{{\literatecolour<}}{1}%
|
||||||
|
{>}{{\literatecolour>}}{1}%
|
||||||
|
{>>>}{\pythonprompt}{3}%
|
||||||
|
,%
|
||||||
|
%aboveskip=.5ex,
|
||||||
|
frame=trbl,
|
||||||
|
%frameround=tttt,
|
||||||
|
%framesep=.3ex,
|
||||||
|
rulecolor=\color{black!40},
|
||||||
|
%framexleftmargin=\framemargin,
|
||||||
|
%framextopmargin=.1ex,
|
||||||
|
%framexbottommargin=.1ex,
|
||||||
|
%framexrightmargin=\framemargin,
|
||||||
|
%framexleftmargin=1mm, framextopmargin=1mm, frame=shadowbox, rulesepcolor=\color{blue},#1
|
||||||
|
%frame=tb,
|
||||||
|
backgroundcolor=\color{white},
|
||||||
|
breakindent=.5\textwidth,frame=single,breaklines=true%
|
||||||
|
%}
|
||||||
|
}
|
||||||
|
|
||||||
|
\newcommand*{\inputpython}[3]{\lstinputlisting[firstline=#2,lastline=#3,firstnumber=#2,frame=single,breakindent=.5\textwidth,frame=single,breaklines=true,style=mypython]{#1}}
|
||||||
|
|
||||||
|
\lstnewenvironment{python}[1][]{\lstset{style=mypython}}{}
|
||||||
|
|
||||||
|
\lstdefinestyle{mypythoninline}{
|
||||||
|
style=mypython,%
|
||||||
|
basicstyle=\ttfamily,%
|
||||||
|
keywordstyle=\color{keywordcolour},%
|
||||||
|
emphstyle={[7]\color{keywordcolour}},%
|
||||||
|
emphstyle=\color{exceptioncolour},%
|
||||||
|
literate=*%
|
||||||
|
{:}{{\literatecolour:}}{2}%
|
||||||
|
{=}{{\literatecolour=}}{2}%
|
||||||
|
{-}{{\literatecolour-}}{2}%
|
||||||
|
{+}{{\literatecolour+}}{2}%
|
||||||
|
{*}{{\literatecolour*}}2%
|
||||||
|
{**}{{\literatecolour{**}}}3%
|
||||||
|
{/}{{\literatecolour/}}{2}%
|
||||||
|
{//}{{\literatecolour{//}}}{2}%
|
||||||
|
{!}{{\literatecolour!}}{2}%
|
||||||
|
%{(}{{\literatecolour(}}{2}%
|
||||||
|
%{)}{{\literatecolour)}}{2}%
|
||||||
|
{[}{{\literatecolour[}}{2}%
|
||||||
|
{]}{{\literatecolour]}}{2}%
|
||||||
|
{<}{{\literatecolour<}}{2}%
|
||||||
|
{<=}{{\literatecolour{<=}}}3%
|
||||||
|
{>}{{\literatecolour>}}{2}%
|
||||||
|
{>=}{{\literatecolour{>=}}}3%
|
||||||
|
{==}{{\literatecolour{==}}}3%
|
||||||
|
{!=}{{\literatecolour{!=}}}3%
|
||||||
|
{+=}{{\literatecolour{+=}}}3%
|
||||||
|
{-=}{{\literatecolour{-=}}}3%
|
||||||
|
{*=}{{\literatecolour{*=}}}3%
|
||||||
|
{/=}{{\literatecolour{/=}}}3%
|
||||||
|
%% emphstyle=\color{blue},%
|
||||||
|
}
|
||||||
|
|
||||||
|
\newcommand*{\pyth}{\lstinline[style=mypythoninline]}
|
||||||
|
|
||||||
BIN
Diapo/recImage.png
Normal file
|
After Width: | Height: | Size: 229 KiB |
BIN
Diapo/samyTortue.jpeg
Normal file
|
After Width: | Height: | Size: 188 KiB |
14
Diapo/tmf.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Module contant les fonctions permettant de lire et écrire des fichiers dans le format TMF
|
||||||
|
|
||||||
|
@author: mysaa
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class WorldSaver():
|
||||||
|
|
||||||
|
def __init__():
|
||||||
|
regSize=0
|
||||||
BIN
Diapo/triImage.png
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
MCOT/mcot.pdf
Normal file
86
MCOT/mcot.tex
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
\documentclass[10pt,a4paper]{article}
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage[T1]{fontenc}
|
||||||
|
\usepackage[french]{babel}
|
||||||
|
\usepackage{amsmath}
|
||||||
|
\usepackage{amsfonts}
|
||||||
|
\usepackage{amssymb}
|
||||||
|
\usepackage{graphicx}
|
||||||
|
\usepackage{hyperref}
|
||||||
|
\usepackage{tabularx}
|
||||||
|
|
||||||
|
% les tableaux on désormais tous des lignes
|
||||||
|
%\let \clone@tabularcr \@tabularcr
|
||||||
|
%\def\@tabularcr{\clone@tabularcr\hline}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\author{Samy Avrillon}
|
||||||
|
\title{Mise en Cohérence des Objectifs du TIPE (MCOT)}
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
\maketitle
|
||||||
|
|
||||||
|
\tableofcontents
|
||||||
|
|
||||||
|
\newpage
|
||||||
|
|
||||||
|
Professeur encadrant : Mr H.\textbf{RICHARD}
|
||||||
|
|
||||||
|
\part{Titre, motivation et ancrage}
|
||||||
|
|
||||||
|
\begin{description}
|
||||||
|
\item[Titre] \underline{\smash{Stockage et génération de topographie artificielle de fond océanique}}
|
||||||
|
|
||||||
|
\item[Motivation] La génération des océans de Minecraft semble magique : aléatoire et pourtant déterministe. J'ai voulu étudier ce phénomène de pseudo-aléatoire et j'en ai été conduit à créer un format de fichier pour stocker ces topographies de manière plus optimisée que les formats actuels (triangles ou discrétisation 3D)
|
||||||
|
|
||||||
|
\item[Ancrage] Créer et stocker des fonds océaniques permet de pouvoir créer des images graphiques d'océans pour le cinéma de manière automatisée ou de créer des environnements pour des simulation ou jeu vidéo
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\part{Positionnements thématiques et mots-clés}
|
||||||
|
|
||||||
|
\section{Positionnement thématique}
|
||||||
|
|
||||||
|
INFORMATIQUE
|
||||||
|
INFORMATIQUE
|
||||||
|
INFORMATIQUE
|
||||||
|
|
||||||
|
\section{Mots clés}
|
||||||
|
\begin{tabular}{|c|c|}
|
||||||
|
Français & English \\
|
||||||
|
\hline
|
||||||
|
Format de fichier & File format \\
|
||||||
|
Génération de carte & Map generator \\
|
||||||
|
Pseudo-aléatoire & Pseudorandom \\
|
||||||
|
Champ de hauteur & Heightmap \\
|
||||||
|
Infographie & Computer graphics \\
|
||||||
|
\end{tabular}
|
||||||
|
|
||||||
|
\part{Bibliographie commentée}
|
||||||
|
Le bruit de Perlin a été créé par Ken Perlin pour le film Tron{[}2{]}. Ce bruit a permit à Markus Persson de créer Minecraft, une révolution dans le monde vidéoludique {[}1{]}. Dans ce jeu, le joueur est libre de progresser dans un monde qui se génère avec lui. De nombreux jeux ont ensuite repris ce concept de génération \og procédurale \fg
|
||||||
|
Dans Minecraft l'espace est discrétisé en trois dimensions, ce qui sert très bien le jeu. Mais pour générer de grandes surfaces, cette façon de stocker est très peu optimisée spatialement. Je voulais donc changer pour une version discrétisée en deux dimensions à la manière d'un champ de hauteur, mais permettant de représenter des grottes (plusieurs changements de densité sur une même colonne). Les jeux actuels manquent en effet de degrés de profondeur. Il n'y a qu'une surface. Le format permettrait de pouvoir développer des mondes plus complexes
|
||||||
|
|
||||||
|
\part{Problématique retenue}
|
||||||
|
Comment créer et stocker de manière efficace et modulable une topographie de fond océanique
|
||||||
|
|
||||||
|
\part{Objectifs du TIPE}
|
||||||
|
Mon objectif est de créer un format de fichier, le \textit{TMF} (topographic map format), permettant de stocker une carte potentiellement infinie représentant la topographie d'une région d'un océan aussi grand que souhaité. Ce format est accompagné de trois modules python. Le premier permet à d'autres programmes python de lire et écrire des fichiers TMF à travers une interface orientée objet. Le second génère procéduralement et pseudo-aléatoirement des topographies/cartes sous-marines réalistes (ou non). Le troisième convertit les objets topographiques en objets graphiques, à base de triangles, pouvant directement être affiché par l'ordinateur (par exemple au format OBJ).
|
||||||
|
|
||||||
|
\part{Liste des références bibliographiques}
|
||||||
|
|
||||||
|
\begin{tabularx}{\textwidth}{cXXX}
|
||||||
|
Index & Auteur & Titre & Référence \\\hline \\
|
||||||
|
{[}1{]} & Markus Persson alias Notch & Terrain Generation part 1 & \url{https://notch.tumblr.com/post/3746989361/terrain-generation-part-1} \\[+20pt]
|
||||||
|
{[}2{]} & Ken Perlin & Making Noise - based on a talk at GDCHardcore & \url{https://web.archive.org/web/20160408014440/http://www.noisemachine.com/talk1/index.html} \\[+20pt]
|
||||||
|
|
||||||
|
\hline \\
|
||||||
|
& & & \url{http://universe.tuxfamily.org/oldblog/index.php?tag/Heightmap}\\
|
||||||
|
|
||||||
|
\end{tabularx}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\end{document}
|
||||||
BIN
MinecraftScreenShots/2019-08-05_20.48.22.png
Normal file
|
After Width: | Height: | Size: 685 KiB |
BIN
MinecraftScreenShots/2019-08-05_20.48.30.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
MinecraftScreenShots/2019-08-05_20.48.37.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
MinecraftScreenShots/2019-08-05_20.48.55.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
MinecraftScreenShots/2019-08-05_20.49.29.png
Normal file
|
After Width: | Height: | Size: 661 KiB |
BIN
MinecraftScreenShots/2019-08-27_22.13.22.png
Normal file
|
After Width: | Height: | Size: 817 KiB |
BIN
MinecraftScreenShots/2019-08-27_22.13.46.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
MinecraftScreenShots/2019-08-27_22.13.55.png
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
BIN
MinecraftScreenShots/2019-08-27_22.13.57.png
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
BIN
MinecraftScreenShots/2019-08-27_22.14.06.png
Normal file
|
After Width: | Height: | Size: 2.7 MiB |
BIN
MinecraftScreenShots/2019-08-27_22.14.22.png
Normal file
|
After Width: | Height: | Size: 675 KiB |
BIN
MinecraftScreenShots/2019-08-27_22.14.47.png
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
BIN
Presentation/SonarPresentation.pdf
Normal file
126
Presentation/SonarPresentation.tex
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
\documentclass[11pt,aspectratio=169]{beamer}
|
||||||
|
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage[T1]{fontenc}
|
||||||
|
\usepackage[french]{babel}
|
||||||
|
\usepackage[clean,pdf]{svg}
|
||||||
|
\usepackage{multimedia}
|
||||||
|
\usetheme{Madrid}
|
||||||
|
|
||||||
|
\hypersetup{pdfpagemode=FullScreen}
|
||||||
|
|
||||||
|
% Transition en fade-in par défaut
|
||||||
|
\addtobeamertemplate{background canvas}{\transfade[duration=0.4]}{}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\author{Samy AVRILLON - 24817}
|
||||||
|
\title{Le Sonar de l'infini}
|
||||||
|
\subtitle{Génération de fond marins informatisés aléatoires}
|
||||||
|
\logo{\includegraphics[width=.5cm]{bernardLogo}}
|
||||||
|
\institute{Lycée lafayette}
|
||||||
|
\date{Années 2018-2020}
|
||||||
|
%\subject{}
|
||||||
|
%\setbeamercovered{transparent}
|
||||||
|
%\setbeamertemplate{navigation symbols}{}
|
||||||
|
\frame[plain]{\maketitle}
|
||||||
|
|
||||||
|
%\iffalse
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Sommaire}
|
||||||
|
\pause
|
||||||
|
\tableofcontents[pausesections]
|
||||||
|
\end{frame}
|
||||||
|
%\fi
|
||||||
|
|
||||||
|
\section{Présentation du projet}
|
||||||
|
\begin{frame}
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[width=0.7\textwidth]{magicInstinctSoftware}
|
||||||
|
\caption{Capture d'écran du logiciel \textit{Magic Instinct Software}}
|
||||||
|
\end{figure}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
/media/mysaa/2761-7FF91/Sonar/Presentation/fond.pdf
|
||||||
|
/media/mysaa/2761-7FF91/Sonar/Presentation/fond.svg
|
||||||
|
/media/mysaa/2761-7FF91/Sonar/Presentation/minecraftOcean.jpg
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Différentes applications}
|
||||||
|
\pause
|
||||||
|
\begin{itemize}[<+->]
|
||||||
|
\item Jeu vidéo
|
||||||
|
\item Simulation océaniques
|
||||||
|
\item Entrainement d'IA de rover (\textit{Cf Quentin SOUVIGNET})
|
||||||
|
\item Graphisme
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\section{Cahier des charges}
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Liste des contraintes}
|
||||||
|
\pause
|
||||||
|
\begin{itemize}[<+->]
|
||||||
|
\item Infinité
|
||||||
|
\item Répétabilité
|
||||||
|
\item Modulabilité
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\section{Solutions de génération}
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Bruit de Perlin}
|
||||||
|
\pause
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[height=0.7\textheight]{perlin}
|
||||||
|
\caption{Heightmap créée par un bruit de perlin}
|
||||||
|
\end{figure}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Bruit Fractal}
|
||||||
|
\begin{columns}
|
||||||
|
\pause
|
||||||
|
\begin{column}{0.5\textwidth}
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[width=0.8\textwidth]{bfractal}
|
||||||
|
\caption{Bruit fractal avec peu de droites}
|
||||||
|
\end{figure}
|
||||||
|
\end{column}
|
||||||
|
\pause
|
||||||
|
\begin{column}{0.5\textwidth}
|
||||||
|
\begin{figure}
|
||||||
|
\includegraphics[width=0.8\textwidth]{hfractal}
|
||||||
|
\caption{Bruit fractal avec plus de droites}
|
||||||
|
\end{figure}
|
||||||
|
\end{column}
|
||||||
|
\end{columns}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\section{Un format de fichier}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Contraintes du format}
|
||||||
|
\pause
|
||||||
|
\begin{itemize}[<+->]
|
||||||
|
\item Liberté totale
|
||||||
|
\item Complexité spaciale
|
||||||
|
\item Référencabilité
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{La structure d'une carte}
|
||||||
|
\centering
|
||||||
|
\includesvg[height=0.85\textheight]{fond}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
% Derniere frame de fin
|
||||||
|
\bgroup
|
||||||
|
\setbeamercolor{background canvas}{bg=black}
|
||||||
|
\begin{frame}[plain]{}
|
||||||
|
\end{frame}
|
||||||
|
\egroup
|
||||||
|
|
||||||
|
\end{document}
|
||||||
BIN
Presentation/bernardLogo.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
69
Presentation/bernardLogo.svg
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
Presentation/bfractal.png
Normal file
|
After Width: | Height: | Size: 331 KiB |
665
Presentation/fond.svg
Normal file
@ -0,0 +1,665 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="171mm"
|
||||||
|
height="96mm"
|
||||||
|
viewBox="0 0 171 96.000002"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.1 r15371"
|
||||||
|
sodipodi:docname="fond.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="marker5549"
|
||||||
|
style="overflow:visible;"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path5547"
|
||||||
|
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||||
|
style="fill-rule:evenodd;stroke:#ffffff;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||||
|
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Sstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="Arrow1Sstart"
|
||||||
|
style="overflow:visible"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path4945"
|
||||||
|
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||||
|
style="fill-rule:evenodd;stroke:#ffffff;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||||
|
transform="scale(0.2) translate(6,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="Arrow1Send"
|
||||||
|
style="overflow:visible;"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path4948"
|
||||||
|
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||||
|
style="fill-rule:evenodd;stroke:#ffffff;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||||
|
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
style="overflow:visible"
|
||||||
|
id="DistanceStart"
|
||||||
|
refX="0.0"
|
||||||
|
refY="0.0"
|
||||||
|
orient="auto"
|
||||||
|
inkscape:stockid="DistanceStart"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<g
|
||||||
|
id="g2300"
|
||||||
|
style="stroke:#000000;stroke-opacity:1;fill:#ffffff;fill-opacity:1">
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;stroke:#000000;stroke-width:1.15;stroke-linecap:square;stroke-opacity:1;fill-opacity:1"
|
||||||
|
d="M 0,0 L 2,0"
|
||||||
|
id="path2306" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-opacity:1;fill-opacity:1"
|
||||||
|
d="M 0,0 L 13,4 L 9,0 13,-4 L 0,0 z "
|
||||||
|
id="path2302" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-opacity:1;fill-opacity:1"
|
||||||
|
d="M 0,-4 L 0,40"
|
||||||
|
id="path2304" />
|
||||||
|
</g>
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible;"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path4942"
|
||||||
|
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||||
|
style="fill-rule:evenodd;stroke:#ffffff;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||||
|
transform="scale(0.4) rotate(180) translate(10,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="Arrow2Lstart"
|
||||||
|
style="overflow:visible"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path4951"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#ffffff;stroke-opacity:1;fill:#ffffff;fill-opacity:1"
|
||||||
|
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||||
|
transform="scale(1.1) translate(1,0)" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.98994949"
|
||||||
|
inkscape:cx="545.48304"
|
||||||
|
inkscape:cy="160.38082"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
units="mm"
|
||||||
|
inkscape:pagecheckerboard="false"
|
||||||
|
inkscape:window-width="1366"
|
||||||
|
inkscape:window-height="709"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-200.99998)">
|
||||||
|
<rect
|
||||||
|
style="fill:#2e00d3;fill-opacity:1;stroke:none;stroke-width:0.79403234;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect4653"
|
||||||
|
width="170.6492"
|
||||||
|
height="95.87648"
|
||||||
|
x="0.17539978"
|
||||||
|
y="201.06174" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.5159505;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10"
|
||||||
|
width="5.0079031"
|
||||||
|
height="73.768311"
|
||||||
|
x="5.3582149"
|
||||||
|
y="218.42317" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.53897732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-6"
|
||||||
|
width="5.0171337"
|
||||||
|
height="80.351669"
|
||||||
|
x="10.361502"
|
||||||
|
y="211.85553" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.30675566;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-7"
|
||||||
|
width="5.0079031"
|
||||||
|
height="26.075878"
|
||||||
|
x="15.404671"
|
||||||
|
y="266.15738" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.28103706;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-5"
|
||||||
|
width="5.0079031"
|
||||||
|
height="21.886734"
|
||||||
|
x="20.412569"
|
||||||
|
y="270.34653" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.26525033;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-3"
|
||||||
|
width="5.0351334"
|
||||||
|
height="19.391466"
|
||||||
|
x="25.297941"
|
||||||
|
y="272.96432" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.24671662;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-56"
|
||||||
|
width="5.0351334"
|
||||||
|
height="16.776276"
|
||||||
|
x="30.333073"
|
||||||
|
y="275.57953" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.24395819;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-2"
|
||||||
|
width="5.1045647"
|
||||||
|
height="16.180122"
|
||||||
|
x="35.3335"
|
||||||
|
y="276.21039" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.23208007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-9"
|
||||||
|
width="5.0351334"
|
||||||
|
height="14.844803"
|
||||||
|
x="40.403351"
|
||||||
|
y="277.51099" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.21698384;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-1"
|
||||||
|
width="5.1315393"
|
||||||
|
height="12.732593"
|
||||||
|
x="45.390278"
|
||||||
|
y="279.67139" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.24474481;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-27"
|
||||||
|
width="5.0351334"
|
||||||
|
height="16.509188"
|
||||||
|
x="50.473614"
|
||||||
|
y="275.84659" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22369346;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-0"
|
||||||
|
width="5.0351334"
|
||||||
|
height="13.791304"
|
||||||
|
x="55.508751"
|
||||||
|
y="278.56448" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.19373304;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-93"
|
||||||
|
width="5.0351334"
|
||||||
|
height="10.344419"
|
||||||
|
x="60.543877"
|
||||||
|
y="282.01138" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.23857896;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-60"
|
||||||
|
width="5.0351334"
|
||||||
|
height="15.687835"
|
||||||
|
x="65.579018"
|
||||||
|
y="276.66797" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-62"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="70.614151"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-61"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="75.644226"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-8"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="80.674309"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-79"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="85.704399"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-20"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="90.734489"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-23"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="95.764587"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-75"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="100.79462"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-92"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="105.82474"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-28"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="110.85483"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-97"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="115.8849"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="120.91499"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-1"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="125.94507"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-2"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="130.97516"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-9"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="136.00525"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-3"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="141.03534"
|
||||||
|
y="278.25549" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.51674014;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-19"
|
||||||
|
width="5.0079031"
|
||||||
|
height="73.994278"
|
||||||
|
x="146.06543"
|
||||||
|
y="218.32138" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.52555859;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-19-4"
|
||||||
|
width="5.0079031"
|
||||||
|
height="76.541336"
|
||||||
|
x="151.07333"
|
||||||
|
y="215.77432" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.54030454;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-19-7"
|
||||||
|
width="5.0079031"
|
||||||
|
height="80.896736"
|
||||||
|
x="156.08124"
|
||||||
|
y="211.41893" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.52905655;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-19-8"
|
||||||
|
width="5.0079031"
|
||||||
|
height="77.563599"
|
||||||
|
x="161.08914"
|
||||||
|
y="214.75206" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.30675566;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-7-4"
|
||||||
|
width="5.0079031"
|
||||||
|
height="26.07588"
|
||||||
|
x="15.378635"
|
||||||
|
y="210.79721" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.28387639;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-3-5"
|
||||||
|
width="5.0351334"
|
||||||
|
height="22.210445"
|
||||||
|
x="25.470028"
|
||||||
|
y="206.0863" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.28517467;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-56-0"
|
||||||
|
width="5.0351334"
|
||||||
|
height="22.414066"
|
||||||
|
x="30.505161"
|
||||||
|
y="208.52849" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.31338966;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-2-3"
|
||||||
|
width="5.0351334"
|
||||||
|
height="27.068741"
|
||||||
|
x="35.540306"
|
||||||
|
y="206.51961" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.33414468;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-9-6"
|
||||||
|
width="5.0351334"
|
||||||
|
height="30.772858"
|
||||||
|
x="40.575436"
|
||||||
|
y="208.10709" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.32834858;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-1-1"
|
||||||
|
width="5.0351334"
|
||||||
|
height="29.714539"
|
||||||
|
x="45.610569"
|
||||||
|
y="205.46129" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.30311945;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-27-0"
|
||||||
|
width="5.0693293"
|
||||||
|
height="25.15283"
|
||||||
|
x="50.628605"
|
||||||
|
y="207.3943" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.2901814;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-0-6"
|
||||||
|
width="5.0351334"
|
||||||
|
height="23.208008"
|
||||||
|
x="55.680836"
|
||||||
|
y="208.2637" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.28728414;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-93-3"
|
||||||
|
width="5.0351334"
|
||||||
|
height="22.746889"
|
||||||
|
x="60.715961"
|
||||||
|
y="207.13734" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.31338966;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-60-2"
|
||||||
|
width="5.0351334"
|
||||||
|
height="27.068741"
|
||||||
|
x="65.751114"
|
||||||
|
y="204.93213" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.3009901;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-3-5-0"
|
||||||
|
width="5.047533"
|
||||||
|
height="24.907778"
|
||||||
|
x="20.422495"
|
||||||
|
y="208.15141" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.19651835;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-62-6"
|
||||||
|
width="5.0593157"
|
||||||
|
height="10.593125"
|
||||||
|
x="70.771629"
|
||||||
|
y="241.73154" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.20728494;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-61-1"
|
||||||
|
width="5.0485487"
|
||||||
|
height="11.810781"
|
||||||
|
x="75.807098"
|
||||||
|
y="244.00478" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-8-5"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="80.846413"
|
||||||
|
y="245.45027" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.27457732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-79-5"
|
||||||
|
width="4.9812565"
|
||||||
|
height="21.003906"
|
||||||
|
x="85.900917"
|
||||||
|
y="241.77057" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22912541;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-20-4"
|
||||||
|
width="5.0144625"
|
||||||
|
height="14.528869"
|
||||||
|
x="90.889984"
|
||||||
|
y="243.37294" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-23-7"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="95.842194"
|
||||||
|
y="246.47086" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.24984716;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-75-6"
|
||||||
|
width="5.014329"
|
||||||
|
height="17.2761"
|
||||||
|
x="100.88016"
|
||||||
|
y="245.42041" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-92-5"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="105.99683"
|
||||||
|
y="243.86279" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.23376569;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-28-6"
|
||||||
|
width="5.038465"
|
||||||
|
height="15.051262"
|
||||||
|
x="111.02273"
|
||||||
|
y="241.74196" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.27858368;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-97-9"
|
||||||
|
width="5.0064182"
|
||||||
|
height="21.51265"
|
||||||
|
x="116.06884"
|
||||||
|
y="237.88997" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.29652894;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-37"
|
||||||
|
width="4.9840579"
|
||||||
|
height="24.48278"
|
||||||
|
x="121.11011"
|
||||||
|
y="238.51682" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.30494329;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-1-4"
|
||||||
|
width="4.9643555"
|
||||||
|
height="25.994709"
|
||||||
|
x="126.15005"
|
||||||
|
y="239.5341" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.30701888;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-2-5"
|
||||||
|
width="4.9781718"
|
||||||
|
height="26.276651"
|
||||||
|
x="131.17323"
|
||||||
|
y="236.98726" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.33450949;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-9-2"
|
||||||
|
width="4.958868"
|
||||||
|
height="31.314398"
|
||||||
|
x="136.21298"
|
||||||
|
y="235.14709" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.3934584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-36-3-5"
|
||||||
|
width="4.9187098"
|
||||||
|
height="43.677338"
|
||||||
|
x="141.26314"
|
||||||
|
y="225.03587" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.28808108;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-62-4"
|
||||||
|
width="5.0459113"
|
||||||
|
height="22.824408"
|
||||||
|
x="70.778336"
|
||||||
|
y="206.51169" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.26175141;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-61-7"
|
||||||
|
width="4.9870887"
|
||||||
|
height="19.065166"
|
||||||
|
x="75.837822"
|
||||||
|
y="207.5735" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.25958091;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-8-4"
|
||||||
|
width="5.0300837"
|
||||||
|
height="18.590023"
|
||||||
|
x="80.846405"
|
||||||
|
y="206.26607" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.24191141;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-79-4"
|
||||||
|
width="5.0181313"
|
||||||
|
height="16.183794"
|
||||||
|
x="85.882469"
|
||||||
|
y="207.58391" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-20-3"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="90.906578"
|
||||||
|
y="208.1071" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-23-0"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="95.936684"
|
||||||
|
y="207.57793" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.22575018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-75-7"
|
||||||
|
width="5.0300837"
|
||||||
|
height="14.060173"
|
||||||
|
x="100.96672"
|
||||||
|
y="207.04877" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.21416378;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-92-8"
|
||||||
|
width="5.0300837"
|
||||||
|
height="12.653961"
|
||||||
|
x="105.99683"
|
||||||
|
y="206.33833" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.18696997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-28-68"
|
||||||
|
width="5.0200224"
|
||||||
|
height="9.6637945"
|
||||||
|
x="111.03195"
|
||||||
|
y="207.37691" />
|
||||||
|
<rect
|
||||||
|
style="fill:#b1b1b1;fill-opacity:1;stroke:#000000;stroke-width:0.14067207;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect10-97-8"
|
||||||
|
width="5.0300837"
|
||||||
|
height="5.4594669"
|
||||||
|
x="116.057"
|
||||||
|
y="209.82872" />
|
||||||
|
<path
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.75189924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker5549)"
|
||||||
|
d="M 3.7041667,292.4141 V 204.96278"
|
||||||
|
id="path4931"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:5.82004309px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14550108"
|
||||||
|
x="5.1185122"
|
||||||
|
y="209.7113"
|
||||||
|
id="text5934"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan5932"
|
||||||
|
x="5.1185122"
|
||||||
|
y="209.7113"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Linux Libertine Display O';-inkscape-font-specification:'Linux Libertine Display O';fill:#ffffff;fill-opacity:1;stroke-width:0.14550108">z=42m</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:5.82004309px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14550108"
|
||||||
|
x="4.907176"
|
||||||
|
y="295.92572"
|
||||||
|
id="text5934-7"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
x="4.907176"
|
||||||
|
y="295.92572"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Linux Libertine Display O';-inkscape-font-specification:'Linux Libertine Display O';fill:#ffffff;fill-opacity:1;stroke-width:0.14550108"
|
||||||
|
id="tspan5954">z=0m</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 28 KiB |
BIN
Presentation/hfractal.png
Normal file
|
After Width: | Height: | Size: 345 KiB |
BIN
Presentation/magicInstinctSoftware.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
Presentation/minecraftOcean.jpg
Normal file
|
After Width: | Height: | Size: 229 KiB |
BIN
Presentation/perlin.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
153
Python/data.py
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Created on Wed Aug 28 17:39:43 2019
|
||||||
|
|
||||||
|
Module contanant les classes générales structurant les données, ainsi que les
|
||||||
|
|
||||||
|
@author: mysaa
|
||||||
|
"""
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def appendeur(l1,l2):
|
||||||
|
"""
|
||||||
|
Effectue l1=l1+l2 de manière opti
|
||||||
|
"""
|
||||||
|
for l in l2:
|
||||||
|
l1.append(l)
|
||||||
|
|
||||||
|
class WorldChunk():
|
||||||
|
|
||||||
|
def getSize(self):
|
||||||
|
raise NotImplementedError("Vous avez fait un monde qui n'implemente pas cette méthode. Vous êtes bizzare vous savez ? Un monde sans taille !!!")
|
||||||
|
|
||||||
|
|
||||||
|
def getColumn(self,x,y):
|
||||||
|
raise NotImplementedError("Vous avez fait un monde qui n'implemente pas cette méthode. Vous êtes bizzare vous savez ?")
|
||||||
|
|
||||||
|
|
||||||
|
def asList(self):
|
||||||
|
return [ [self.getColumn(x,y) for y in range(self.size[1])] for x in range(self.size[0]) ]
|
||||||
|
|
||||||
|
def getIndexed(self,fullCoords=False,addZero=False):
|
||||||
|
points = []
|
||||||
|
pointIndexes = [0]
|
||||||
|
for pos in np.ndindex(self.getSize()):
|
||||||
|
col = self.getColumn(pos[0],pos[1])
|
||||||
|
if(addZero): col = np.insert(col,0,0)
|
||||||
|
if(fullCoords): col = [(pos[0],pos[1],c) for c in col]
|
||||||
|
appendeur(points,col)
|
||||||
|
pointIndexes.append(pointIndexes[-1]+len(col))
|
||||||
|
return points,pointIndexes
|
||||||
|
|
||||||
|
|
||||||
|
class CollageWorldChunk(WorldChunk):
|
||||||
|
|
||||||
|
def __init__(self,chunk,xp,yp,xy):
|
||||||
|
|
||||||
|
self.orgChunk,self.xp,self.yp,self.xy = chunk,xp,yp,xy
|
||||||
|
self.orgSize = chunk.getSize()
|
||||||
|
|
||||||
|
def getSize(self) : return (self.orgChunk.size[0]+1,self.orgChunk.size[1]+1)
|
||||||
|
|
||||||
|
def getColumn(self,x,y):
|
||||||
|
xout,yout = x>=self.orgSize[0],y>=self.orgSize[1]
|
||||||
|
if(xout and yout):
|
||||||
|
return self.xy.getColumn(x-self.orgSize[0],y-self.orgSize[1])
|
||||||
|
if(xout):
|
||||||
|
return self.xp.getColumn(x-self.orgSize[0],y)
|
||||||
|
if(yout):
|
||||||
|
return self.yp.getColumn(x,y-self.orgSize[1])
|
||||||
|
|
||||||
|
return self.orgChunk.getColumn(x,y)
|
||||||
|
|
||||||
|
class ArrayedWorldChunk(WorldChunk):
|
||||||
|
|
||||||
|
def fromList(liste):
|
||||||
|
size = len(liste),len(liste[0])
|
||||||
|
indexes=np.empty(size[0]*size[1]+1,dtype=np.uint32)
|
||||||
|
index = 0
|
||||||
|
data = []
|
||||||
|
for y in range(size[1]):
|
||||||
|
for x in range(size[0]):
|
||||||
|
indexes[x+size[0]*y]=index
|
||||||
|
data += liste[x][y]
|
||||||
|
index += len(liste[x][y])
|
||||||
|
indexes[size[0]*size[1]] = index
|
||||||
|
data = np.array(data,dtype=np.float)
|
||||||
|
return ArrayedWorldChunk(size,indexes,data)
|
||||||
|
|
||||||
|
def __init__(self,size,indexes,data):
|
||||||
|
self.size = size
|
||||||
|
self.indexes=indexes
|
||||||
|
self.data=data
|
||||||
|
|
||||||
|
|
||||||
|
def getColumn(self,x,y):
|
||||||
|
i0,i1 = self.indexes[x+self.size[0]*y],self.indexes[x+self.size[0]*y+1]
|
||||||
|
return self.data[i0:i1]
|
||||||
|
|
||||||
|
def getSize(self) : return self.size
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Noise:
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
"""
|
||||||
|
Cette fonction renvoie un array numpy de taille rx*ry correspondant au chunk x y avec le seed donné.
|
||||||
|
Cette fonction doit être déterministe (si les attributs de l'objets ne sont pas changés bien sur)
|
||||||
|
"""
|
||||||
|
raise NotImplementedError("Vous avez fait un bruit qui n'implemente pas cette méthode. Vous êtes bizzare vous savez ?")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def __add__(self,other):
|
||||||
|
|
||||||
|
def addedChunk(self,x,y,n):
|
||||||
|
return self.noise1.getChunk(x,y,n) + self.noise2.getChunk(x,y,n)
|
||||||
|
noise = Noise()
|
||||||
|
noise.noise1 = self
|
||||||
|
noise.noise2 = other
|
||||||
|
noise.getChunk = addedChunk
|
||||||
|
return noise
|
||||||
|
|
||||||
|
def __iadd__(self,other):
|
||||||
|
|
||||||
|
return self.__add__(other)
|
||||||
|
|
||||||
|
def __rmul__(self,other):
|
||||||
|
|
||||||
|
if type(other) in ['float','int']:
|
||||||
|
def mulChunk(self,x,y,n):
|
||||||
|
return self.prop*self.noise1.getChunk(x,y,n)
|
||||||
|
noise = Noise()
|
||||||
|
noise.noise1 = self
|
||||||
|
noise.prop = other
|
||||||
|
noise.getChunk = mulChunk
|
||||||
|
else:
|
||||||
|
def mulChunk(self,x,y,n):
|
||||||
|
return self.noise1.getChunk(x,y,n) * self.noise2.getChunk(x,y,n)
|
||||||
|
noise = Noise()
|
||||||
|
noise.noise1 = self
|
||||||
|
noise.noise2 = other
|
||||||
|
noise.getChunk = mulChunk
|
||||||
|
return noise
|
||||||
|
|
||||||
|
def __sub__(self,other):
|
||||||
|
|
||||||
|
def subChunk(self,x,y,n):
|
||||||
|
return self.noise1.getChunk(x,y,n) - self.noise2.getChunk(x,y,n)
|
||||||
|
noise = Noise()
|
||||||
|
noise.noise1 = self
|
||||||
|
noise.noise2 = other
|
||||||
|
noise.getChunk = subChunk
|
||||||
|
return noise
|
||||||
|
|
||||||
BIN
Python/filImage.png
Normal file
|
After Width: | Height: | Size: 982 KiB |
264
Python/guy.py
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
# -*- 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 #####
|
||||||
|
|
||||||
|
|
||||||
234
Python/guy2.py
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
# -*- 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 #####
|
||||||
|
|
||||||
|
|
||||||
22
Python/mcpi/.gitattributes
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
# Custom for Visual Studio
|
||||||
|
*.cs diff=csharp
|
||||||
|
*.sln merge=union
|
||||||
|
*.csproj merge=union
|
||||||
|
*.vbproj merge=union
|
||||||
|
*.fsproj merge=union
|
||||||
|
*.dbproj merge=union
|
||||||
|
|
||||||
|
# Standard to msysgit
|
||||||
|
*.doc diff=astextplain
|
||||||
|
*.DOC diff=astextplain
|
||||||
|
*.docx diff=astextplain
|
||||||
|
*.DOCX diff=astextplain
|
||||||
|
*.dot diff=astextplain
|
||||||
|
*.DOT diff=astextplain
|
||||||
|
*.pdf diff=astextplain
|
||||||
|
*.PDF diff=astextplain
|
||||||
|
*.rtf diff=astextplain
|
||||||
|
*.RTF diff=astextplain
|
||||||
33
Python/mcpi/.gitignore
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
*.py[cdo]
|
||||||
|
pythonhosted/
|
||||||
|
|
||||||
|
# Editor detritus
|
||||||
|
*.vim
|
||||||
|
*.swp
|
||||||
|
tags
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# Packaging detritus
|
||||||
|
*.egg
|
||||||
|
*.egg-info
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
eggs
|
||||||
|
parts
|
||||||
|
bin
|
||||||
|
var
|
||||||
|
sdist
|
||||||
|
develop-eggs
|
||||||
|
.installed.cfg
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
coverage
|
||||||
|
.coverage
|
||||||
|
.tox
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Generated documentation
|
||||||
|
docs/_build
|
||||||
10
Python/mcpi/CHANGELOG.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Change Log
|
||||||
|
|
||||||
|
## 2018-05-01 v1.1.0
|
||||||
|
|
||||||
|
+ packaged and released onto [PyPI](https://pypi.org)
|
||||||
|
+ it seemed ridiculous calling this v1.0.0 given the maturity of this library, so it has become v1.1.0
|
||||||
|
|
||||||
|
## in the past v1.0.0
|
||||||
|
|
||||||
|
+ the library was created it was used but never packaged.
|
||||||
5
Python/mcpi/LICENSE
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
46
Python/mcpi/README.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Minecraft: Pi edition API Python Library
|
||||||
|
|
||||||
|
`mcpi` Python library for communicating with [Minecraft: Pi edition](https://minecraft.net/en-us/edition/pi/) and [RaspberryJuice](https://github.com/zhuowei/RaspberryJuice).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
```
|
||||||
|
pip3 install mcpi
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux / MacOS
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo pip3 install mcpi
|
||||||
|
```
|
||||||
|
|
||||||
|
## History
|
||||||
|
|
||||||
|
The [Minecraft: Pi edition](https://minecraft.net/en-us/edition/pi/) Python library was originally created by Mojang and released with Minecraft: Pi edition.
|
||||||
|
|
||||||
|
Initial supported was provided for Python 2 only, but during a sprint at PyconUK 2014 it was migrated to Python 3 and [py3minepi](https://github.com/py3minepi/py3minepi) was created.
|
||||||
|
|
||||||
|
The ability to hack Minecraft from Python was very popular and the [RaspberryJuice](https://github.com/zhuowei/RaspberryJuice) plugin was created for Minecraft Java edition. RaspberryJuice also extended the API adding additional features.
|
||||||
|
|
||||||
|
This python library supports Python 2 & 3 and Minecraft: Pi edition and RaspberryJuice.
|
||||||
|
|
||||||
|
Documentation for the Minecraft: Pi edition and RaspberryJuice API's can be found at [www.stuffaboutcode.com/p/minecraft-api-reference.html](http://www.stuffaboutcode.com/p/minecraft-api-reference.html).
|
||||||
|
|
||||||
|
It was released onto [PyPI](https://pypi.org) in May 2018.
|
||||||
|
|
||||||
|
If you want some cool additional tools for modifying Minecraft, check out [minecraft-stuff](https://minecraft-stuff.readthedocs.io/en/latest/).
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
This library is a collection of the following sources:
|
||||||
|
|
||||||
|
+ [Minecraft: Pi edition](https://minecraft.net/en-us/edition/pi/)
|
||||||
|
+ [Python 3 Minecraft: Pi edition library](https://github.com/py3minepi/py3minepi)
|
||||||
|
|
||||||
|
## Licenses
|
||||||
|
|
||||||
|
+ mcpi - [LICENSE.txt](https://github.com/martinohanlon/mcpi/blob/master/LICENSE)
|
||||||
|
+ Minecraft: Pi edition LICENSE - [minecraft-pi-edition-LICENSE.txt](https://github.com/martinohanlon/mcpi/blob/master/minecraft-pi-edition-LICENSE.txt)
|
||||||
|
|
||||||
0
Python/mcpi/__init__.py
Normal file
97
Python/mcpi/block.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
class Block:
|
||||||
|
"""Minecraft PI block description. Can be sent to Minecraft.setBlock/s"""
|
||||||
|
def __init__(self, id, data=0):
|
||||||
|
self.id = id
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
def __cmp__(self, rhs):
|
||||||
|
return hash(self) - hash(rhs)
|
||||||
|
|
||||||
|
def __eq__(self, rhs):
|
||||||
|
return self.id == rhs.id and self.data == rhs.data
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return (self.id << 8) + self.data
|
||||||
|
|
||||||
|
def withData(self, data):
|
||||||
|
return Block(self.id, data)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
"""Allows a Block to be sent whenever id [and data] is needed"""
|
||||||
|
return iter((self.id, self.data))
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "Block(%d, %d)"%(self.id, self.data)
|
||||||
|
|
||||||
|
AIR = Block(0)
|
||||||
|
STONE = Block(1)
|
||||||
|
GRASS = Block(2)
|
||||||
|
DIRT = Block(3)
|
||||||
|
COBBLESTONE = Block(4)
|
||||||
|
WOOD_PLANKS = Block(5)
|
||||||
|
SAPLING = Block(6)
|
||||||
|
BEDROCK = Block(7)
|
||||||
|
WATER_FLOWING = Block(8)
|
||||||
|
WATER = WATER_FLOWING
|
||||||
|
WATER_STATIONARY = Block(9)
|
||||||
|
LAVA_FLOWING = Block(10)
|
||||||
|
LAVA = LAVA_FLOWING
|
||||||
|
LAVA_STATIONARY = Block(11)
|
||||||
|
SAND = Block(12)
|
||||||
|
GRAVEL = Block(13)
|
||||||
|
GOLD_ORE = Block(14)
|
||||||
|
IRON_ORE = Block(15)
|
||||||
|
COAL_ORE = Block(16)
|
||||||
|
WOOD = Block(17)
|
||||||
|
LEAVES = Block(18)
|
||||||
|
GLASS = Block(20)
|
||||||
|
LAPIS_LAZULI_ORE = Block(21)
|
||||||
|
LAPIS_LAZULI_BLOCK = Block(22)
|
||||||
|
SANDSTONE = Block(24)
|
||||||
|
BED = Block(26)
|
||||||
|
COBWEB = Block(30)
|
||||||
|
GRASS_TALL = Block(31)
|
||||||
|
WOOL = Block(35)
|
||||||
|
FLOWER_YELLOW = Block(37)
|
||||||
|
FLOWER_CYAN = Block(38)
|
||||||
|
MUSHROOM_BROWN = Block(39)
|
||||||
|
MUSHROOM_RED = Block(40)
|
||||||
|
GOLD_BLOCK = Block(41)
|
||||||
|
IRON_BLOCK = Block(42)
|
||||||
|
STONE_SLAB_DOUBLE = Block(43)
|
||||||
|
STONE_SLAB = Block(44)
|
||||||
|
BRICK_BLOCK = Block(45)
|
||||||
|
TNT = Block(46)
|
||||||
|
BOOKSHELF = Block(47)
|
||||||
|
MOSS_STONE = Block(48)
|
||||||
|
OBSIDIAN = Block(49)
|
||||||
|
TORCH = Block(50)
|
||||||
|
FIRE = Block(51)
|
||||||
|
STAIRS_WOOD = Block(53)
|
||||||
|
CHEST = Block(54)
|
||||||
|
DIAMOND_ORE = Block(56)
|
||||||
|
DIAMOND_BLOCK = Block(57)
|
||||||
|
CRAFTING_TABLE = Block(58)
|
||||||
|
FARMLAND = Block(60)
|
||||||
|
FURNACE_INACTIVE = Block(61)
|
||||||
|
FURNACE_ACTIVE = Block(62)
|
||||||
|
DOOR_WOOD = Block(64)
|
||||||
|
LADDER = Block(65)
|
||||||
|
STAIRS_COBBLESTONE = Block(67)
|
||||||
|
DOOR_IRON = Block(71)
|
||||||
|
REDSTONE_ORE = Block(73)
|
||||||
|
SNOW = Block(78)
|
||||||
|
ICE = Block(79)
|
||||||
|
SNOW_BLOCK = Block(80)
|
||||||
|
CACTUS = Block(81)
|
||||||
|
CLAY = Block(82)
|
||||||
|
SUGAR_CANE = Block(83)
|
||||||
|
FENCE = Block(85)
|
||||||
|
GLOWSTONE_BLOCK = Block(89)
|
||||||
|
BEDROCK_INVISIBLE = Block(95)
|
||||||
|
STONE_BRICK = Block(98)
|
||||||
|
GLASS_PANE = Block(102)
|
||||||
|
MELON = Block(103)
|
||||||
|
FENCE_GATE = Block(107)
|
||||||
|
GLOWING_OBSIDIAN = Block(246)
|
||||||
|
NETHER_REACTOR_CORE = Block(247)
|
||||||
63
Python/mcpi/connection.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import socket
|
||||||
|
import select
|
||||||
|
import sys
|
||||||
|
from .util import flatten_parameters_to_bytestring
|
||||||
|
|
||||||
|
""" @author: Aron Nieminen, Mojang AB"""
|
||||||
|
|
||||||
|
class RequestError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Connection:
|
||||||
|
"""Connection to a Minecraft Pi game"""
|
||||||
|
RequestFailed = "Fail"
|
||||||
|
|
||||||
|
def __init__(self, address, port):
|
||||||
|
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self.socket.connect((address, port))
|
||||||
|
self.lastSent = ""
|
||||||
|
|
||||||
|
def drain(self):
|
||||||
|
"""Drains the socket of incoming data"""
|
||||||
|
while True:
|
||||||
|
readable, _, _ = select.select([self.socket], [], [], 0.0)
|
||||||
|
if not readable:
|
||||||
|
break
|
||||||
|
data = self.socket.recv(1500)
|
||||||
|
e = "Drained Data: <%s>\n"%data.strip()
|
||||||
|
e += "Last Message: <%s>\n"%self.lastSent.strip()
|
||||||
|
sys.stderr.write(e)
|
||||||
|
|
||||||
|
def send(self, f, *data):
|
||||||
|
"""
|
||||||
|
Sends data. Note that a trailing newline '\n' is added here
|
||||||
|
|
||||||
|
The protocol uses CP437 encoding - https://en.wikipedia.org/wiki/Code_page_437
|
||||||
|
which is mildly distressing as it can't encode all of Unicode.
|
||||||
|
"""
|
||||||
|
|
||||||
|
s = b"".join([f, b"(", flatten_parameters_to_bytestring(data), b")", b"\n"])
|
||||||
|
|
||||||
|
self._send(s)
|
||||||
|
|
||||||
|
def _send(self, s):
|
||||||
|
"""
|
||||||
|
The actual socket interaction from self.send, extracted for easier mocking
|
||||||
|
and testing
|
||||||
|
"""
|
||||||
|
self.drain()
|
||||||
|
self.lastSent = s
|
||||||
|
|
||||||
|
self.socket.sendall(s)
|
||||||
|
|
||||||
|
def receive(self):
|
||||||
|
"""Receives data. Note that the trailing newline '\n' is trimmed"""
|
||||||
|
s = self.socket.makefile("r").readline().rstrip("\n")
|
||||||
|
if s == Connection.RequestFailed:
|
||||||
|
raise RequestError("%s failed"%self.lastSent.strip())
|
||||||
|
return s
|
||||||
|
|
||||||
|
def sendReceive(self, *data):
|
||||||
|
"""Sends and receive data"""
|
||||||
|
self.send(*data)
|
||||||
|
return self.receive()
|
||||||
45
Python/mcpi/event.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
from .vec3 import Vec3
|
||||||
|
|
||||||
|
class BlockEvent:
|
||||||
|
"""An Event related to blocks (e.g. placed, removed, hit)"""
|
||||||
|
HIT = 0
|
||||||
|
|
||||||
|
def __init__(self, type, x, y, z, face, entityId):
|
||||||
|
self.type = type
|
||||||
|
self.pos = Vec3(x, y, z)
|
||||||
|
self.face = face
|
||||||
|
self.entityId = entityId
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
sType = {
|
||||||
|
BlockEvent.HIT: "BlockEvent.HIT"
|
||||||
|
}.get(self.type, "???")
|
||||||
|
|
||||||
|
return "BlockEvent(%s, %d, %d, %d, %d, %d)"%(
|
||||||
|
sType,self.pos.x,self.pos.y,self.pos.z,self.face,self.entityId);
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def Hit(x, y, z, face, entityId):
|
||||||
|
return BlockEvent(BlockEvent.HIT, x, y, z, face, entityId)
|
||||||
|
|
||||||
|
class ChatEvent:
|
||||||
|
"""An Event related to chat (e.g. posts)"""
|
||||||
|
POST = 0
|
||||||
|
|
||||||
|
def __init__(self, type, entityId, message):
|
||||||
|
self.type = type
|
||||||
|
self.entityId = entityId
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
sType = {
|
||||||
|
ChatEvent.POST: "ChatEvent.POST"
|
||||||
|
}.get(self.type, "???")
|
||||||
|
|
||||||
|
return "ChatEvent(%s, %d, %s)"%(
|
||||||
|
sType,self.entityId,self.message);
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def Post(entityId, message):
|
||||||
|
return ChatEvent(ChatEvent.POST, entityId, message)
|
||||||
|
|
||||||
6
Python/mcpi/minecraft-pi-edition-LICENSE.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
*** The real license isn't finished yet, here's what goes in plain english ***
|
||||||
|
|
||||||
|
You may execute the minecraft-pi binary on a Raspberry Pi or an emulator
|
||||||
|
You may use any of the source code included in the distribution for any purpose (except evil)
|
||||||
|
|
||||||
|
You may not redistribute any modified binary parts of the distribution
|
||||||
210
Python/mcpi/minecraft.py
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
from .connection import Connection
|
||||||
|
from .vec3 import Vec3
|
||||||
|
from .event import BlockEvent, ChatEvent
|
||||||
|
from .block import Block
|
||||||
|
import math
|
||||||
|
from .util import flatten
|
||||||
|
|
||||||
|
""" Minecraft PI low level api v0.1_1
|
||||||
|
|
||||||
|
Note: many methods have the parameter *arg. This solution makes it
|
||||||
|
simple to allow different types, and variable number of arguments.
|
||||||
|
The actual magic is a mix of flatten_parameters() and __iter__. Example:
|
||||||
|
A Cube class could implement __iter__ to work in Minecraft.setBlocks(c, id).
|
||||||
|
|
||||||
|
(Because of this, it's possible to "erase" arguments. CmdPlayer removes
|
||||||
|
entityId, by injecting [] that flattens to nothing)
|
||||||
|
|
||||||
|
@author: Aron Nieminen, Mojang AB"""
|
||||||
|
|
||||||
|
""" Updated to include functionality provided by RaspberryJuice:
|
||||||
|
- getBlocks()
|
||||||
|
- getDirection()
|
||||||
|
- getPitch()
|
||||||
|
- getRotation()
|
||||||
|
- getPlayerEntityId()
|
||||||
|
- pollChatPosts() """
|
||||||
|
|
||||||
|
def intFloor(*args):
|
||||||
|
return [int(math.floor(x)) for x in flatten(args)]
|
||||||
|
|
||||||
|
class CmdPositioner:
|
||||||
|
"""Methods for setting and getting positions"""
|
||||||
|
def __init__(self, connection, packagePrefix):
|
||||||
|
self.conn = connection
|
||||||
|
self.pkg = packagePrefix
|
||||||
|
|
||||||
|
def getPos(self, id):
|
||||||
|
"""Get entity position (entityId:int) => Vec3"""
|
||||||
|
s = self.conn.sendReceive(self.pkg + b".getPos", id)
|
||||||
|
return Vec3(*list(map(float, s.split(","))))
|
||||||
|
|
||||||
|
def setPos(self, id, *args):
|
||||||
|
"""Set entity position (entityId:int, x,y,z)"""
|
||||||
|
self.conn.send(self.pkg + b".setPos", id, args)
|
||||||
|
|
||||||
|
def getTilePos(self, id):
|
||||||
|
"""Get entity tile position (entityId:int) => Vec3"""
|
||||||
|
s = self.conn.sendReceive(self.pkg + b".getTile", id)
|
||||||
|
return Vec3(*list(map(int, s.split(","))))
|
||||||
|
|
||||||
|
def setTilePos(self, id, *args):
|
||||||
|
"""Set entity tile position (entityId:int) => Vec3"""
|
||||||
|
self.conn.send(self.pkg + b".setTile", id, intFloor(*args))
|
||||||
|
|
||||||
|
def getDirection(self, id):
|
||||||
|
"""Get entity direction (entityId:int) => Vec3"""
|
||||||
|
s = self.conn.sendReceive(self.pkg + b".getDirection", id)
|
||||||
|
return Vec3(*map(float, s.split(",")))
|
||||||
|
|
||||||
|
def getRotation(self, id):
|
||||||
|
"""get entity rotation (entityId:int) => float"""
|
||||||
|
return float(self.conn.sendReceive(self.pkg + b".getRotation", id))
|
||||||
|
|
||||||
|
def getPitch(self, id):
|
||||||
|
"""get entity pitch (entityId:int) => float"""
|
||||||
|
return float(self.conn.sendReceive(self.pkg + b".getPitch", id))
|
||||||
|
|
||||||
|
def setting(self, setting, status):
|
||||||
|
"""Set a player setting (setting, status). keys: autojump"""
|
||||||
|
self.conn.send(self.pkg + b".setting", setting, 1 if bool(status) else 0)
|
||||||
|
|
||||||
|
|
||||||
|
class CmdEntity(CmdPositioner):
|
||||||
|
"""Methods for entities"""
|
||||||
|
def __init__(self, connection):
|
||||||
|
CmdPositioner.__init__(self, connection, b"entity")
|
||||||
|
|
||||||
|
|
||||||
|
class CmdPlayer(CmdPositioner):
|
||||||
|
"""Methods for the host (Raspberry Pi) player"""
|
||||||
|
def __init__(self, connection):
|
||||||
|
CmdPositioner.__init__(self, connection, b"player")
|
||||||
|
self.conn = connection
|
||||||
|
|
||||||
|
def getPos(self):
|
||||||
|
return CmdPositioner.getPos(self, [])
|
||||||
|
def setPos(self, *args):
|
||||||
|
return CmdPositioner.setPos(self, [], args)
|
||||||
|
def getTilePos(self):
|
||||||
|
return CmdPositioner.getTilePos(self, [])
|
||||||
|
def setTilePos(self, *args):
|
||||||
|
return CmdPositioner.setTilePos(self, [], args)
|
||||||
|
def getDirection(self):
|
||||||
|
return CmdPositioner.getDirection(self, [])
|
||||||
|
def getRotation(self):
|
||||||
|
return CmdPositioner.getRotation(self, [])
|
||||||
|
def getPitch(self):
|
||||||
|
return CmdPositioner.getPitch(self, [])
|
||||||
|
|
||||||
|
class CmdCamera:
|
||||||
|
def __init__(self, connection):
|
||||||
|
self.conn = connection
|
||||||
|
|
||||||
|
def setNormal(self, *args):
|
||||||
|
"""Set camera mode to normal Minecraft view ([entityId])"""
|
||||||
|
self.conn.send(b"camera.mode.setNormal", args)
|
||||||
|
|
||||||
|
def setFixed(self):
|
||||||
|
"""Set camera mode to fixed view"""
|
||||||
|
self.conn.send(b"camera.mode.setFixed")
|
||||||
|
|
||||||
|
def setFollow(self, *args):
|
||||||
|
"""Set camera mode to follow an entity ([entityId])"""
|
||||||
|
self.conn.send(b"camera.mode.setFollow", args)
|
||||||
|
|
||||||
|
def setPos(self, *args):
|
||||||
|
"""Set camera entity position (x,y,z)"""
|
||||||
|
self.conn.send(b"camera.setPos", args)
|
||||||
|
|
||||||
|
|
||||||
|
class CmdEvents:
|
||||||
|
"""Events"""
|
||||||
|
def __init__(self, connection):
|
||||||
|
self.conn = connection
|
||||||
|
|
||||||
|
def clearAll(self):
|
||||||
|
"""Clear all old events"""
|
||||||
|
self.conn.send(b"events.clear")
|
||||||
|
|
||||||
|
def pollBlockHits(self):
|
||||||
|
"""Only triggered by sword => [BlockEvent]"""
|
||||||
|
s = self.conn.sendReceive(b"events.block.hits")
|
||||||
|
events = [e for e in s.split("|") if e]
|
||||||
|
return [BlockEvent.Hit(*list(map(int, e.split(",")))) for e in events]
|
||||||
|
|
||||||
|
def pollChatPosts(self):
|
||||||
|
"""Triggered by posts to chat => [ChatEvent]"""
|
||||||
|
s = self.conn.sendReceive(b"events.chat.posts")
|
||||||
|
events = [e for e in s.split("|") if e]
|
||||||
|
return [ChatEvent.Post(int(e[:e.find(",")]), e[e.find(",") + 1:]) for e in events]
|
||||||
|
|
||||||
|
class Minecraft:
|
||||||
|
"""The main class to interact with a running instance of Minecraft Pi."""
|
||||||
|
def __init__(self, connection):
|
||||||
|
self.conn = connection
|
||||||
|
|
||||||
|
self.camera = CmdCamera(connection)
|
||||||
|
self.entity = CmdEntity(connection)
|
||||||
|
self.player = CmdPlayer(connection)
|
||||||
|
self.events = CmdEvents(connection)
|
||||||
|
|
||||||
|
def getBlock(self, *args):
|
||||||
|
"""Get block (x,y,z) => id:int"""
|
||||||
|
return int(self.conn.sendReceive(b"world.getBlock", intFloor(args)))
|
||||||
|
|
||||||
|
def getBlockWithData(self, *args):
|
||||||
|
"""Get block with data (x,y,z) => Block"""
|
||||||
|
ans = self.conn.sendReceive(b"world.getBlockWithData", intFloor(args))
|
||||||
|
return Block(*list(map(int, ans.split(","))))
|
||||||
|
|
||||||
|
def getBlocks(self, *args):
|
||||||
|
"""Get a cuboid of blocks (x0,y0,z0,x1,y1,z1) => [id:int]"""
|
||||||
|
s = self.conn.sendReceive(b"world.getBlocks", intFloor(args))
|
||||||
|
return map(int, s.split(","))
|
||||||
|
|
||||||
|
def setBlock(self, *args):
|
||||||
|
"""Set block (x,y,z,id,[data])"""
|
||||||
|
self.conn.send(b"world.setBlock", intFloor(args))
|
||||||
|
|
||||||
|
def setBlocks(self, *args):
|
||||||
|
"""Set a cuboid of blocks (x0,y0,z0,x1,y1,z1,id,[data])"""
|
||||||
|
self.conn.send(b"world.setBlocks", intFloor(args))
|
||||||
|
|
||||||
|
def getHeight(self, *args):
|
||||||
|
"""Get the height of the world (x,z) => int"""
|
||||||
|
return int(self.conn.sendReceive(b"world.getHeight", intFloor(args)))
|
||||||
|
|
||||||
|
def getPlayerEntityIds(self):
|
||||||
|
"""Get the entity ids of the connected players => [id:int]"""
|
||||||
|
ids = self.conn.sendReceive(b"world.getPlayerIds")
|
||||||
|
return list(map(int, ids.split("|")))
|
||||||
|
|
||||||
|
def getPlayerEntityId(self, name):
|
||||||
|
"""Get the entity id of the named player => [id:int]"""
|
||||||
|
return int(self.conn.sendReceive(b"world.getPlayerId", name))
|
||||||
|
|
||||||
|
def saveCheckpoint(self):
|
||||||
|
"""Save a checkpoint that can be used for restoring the world"""
|
||||||
|
self.conn.send(b"world.checkpoint.save")
|
||||||
|
|
||||||
|
def restoreCheckpoint(self):
|
||||||
|
"""Restore the world state to the checkpoint"""
|
||||||
|
self.conn.send(b"world.checkpoint.restore")
|
||||||
|
|
||||||
|
def postToChat(self, msg):
|
||||||
|
"""Post a message to the game chat"""
|
||||||
|
self.conn.send(b"chat.post", msg)
|
||||||
|
|
||||||
|
def setting(self, setting, status):
|
||||||
|
"""Set a world setting (setting, status). keys: world_immutable, nametags_visible"""
|
||||||
|
self.conn.send(b"world.setting", setting, 1 if bool(status) else 0)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create(address = "localhost", port = 4711):
|
||||||
|
return Minecraft(Connection(address, port))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
mc = Minecraft.create()
|
||||||
|
mc.postToChat("Hello, Minecraft!")
|
||||||
36
Python/mcpi/setup.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
__project__ = 'mcpi'
|
||||||
|
__desc__ = 'Python library for the Minecraft Pi edition and RaspberryJuice API'
|
||||||
|
__version__ = '1.1.0'
|
||||||
|
__author__ = "Martin O'Hanlon"
|
||||||
|
__author_email__ = 'martin@ohanlonweb.com'
|
||||||
|
__license__ = 'MIT'
|
||||||
|
__url__ = 'https://github.com/martinohanlon/mcpi'
|
||||||
|
|
||||||
|
__classifiers__ = [
|
||||||
|
"Development Status :: 5 - Production/Stable",
|
||||||
|
"Intended Audience :: Education",
|
||||||
|
"Intended Audience :: Developers",
|
||||||
|
"Topic :: Education",
|
||||||
|
"Topic :: Games/Entertainment",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Programming Language :: Python :: 2",
|
||||||
|
"Programming Language :: Python :: 2.7",
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"Programming Language :: Python :: 3.3",
|
||||||
|
"Programming Language :: Python :: 3.4",
|
||||||
|
"Programming Language :: Python :: 3.5",
|
||||||
|
"Programming Language :: Python :: 3.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
setup(name=__project__,
|
||||||
|
version = __version__,
|
||||||
|
description = __desc__,
|
||||||
|
url = __url__,
|
||||||
|
author = __author__,
|
||||||
|
author_email = __author_email__,
|
||||||
|
license = __license__,
|
||||||
|
packages = [__project__],
|
||||||
|
classifiers = __classifiers__,
|
||||||
|
zip_safe=False)
|
||||||
18
Python/mcpi/util.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import collections
|
||||||
|
|
||||||
|
def flatten(l):
|
||||||
|
for e in l:
|
||||||
|
if isinstance(e, collections.Iterable) and not isinstance(e, str):
|
||||||
|
for ee in flatten(e): yield ee
|
||||||
|
else: yield e
|
||||||
|
|
||||||
|
def flatten_parameters_to_bytestring(l):
|
||||||
|
return b",".join(map(_misc_to_bytes, flatten(l)))
|
||||||
|
|
||||||
|
def _misc_to_bytes(m):
|
||||||
|
"""
|
||||||
|
Convert an arbitrary object into a string encoded as a CP437 series of bytes.
|
||||||
|
|
||||||
|
See `Connection.send` for more details.
|
||||||
|
"""
|
||||||
|
return str(m).encode("cp437")
|
||||||
114
Python/mcpi/vec3.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
class Vec3:
|
||||||
|
def __init__(self, x=0, y=0, z=0):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.z = z
|
||||||
|
|
||||||
|
def __add__(self, rhs):
|
||||||
|
c = self.clone()
|
||||||
|
c += rhs
|
||||||
|
return c
|
||||||
|
|
||||||
|
def __iadd__(self, rhs):
|
||||||
|
self.x += rhs.x
|
||||||
|
self.y += rhs.y
|
||||||
|
self.z += rhs.z
|
||||||
|
return self
|
||||||
|
|
||||||
|
def length(self):
|
||||||
|
return self.lengthSqr() ** .5
|
||||||
|
|
||||||
|
def lengthSqr(self):
|
||||||
|
return self.x * self.x + self.y * self.y + self.z * self.z
|
||||||
|
|
||||||
|
def __mul__(self, k):
|
||||||
|
c = self.clone()
|
||||||
|
c *= k
|
||||||
|
return c
|
||||||
|
|
||||||
|
def __imul__(self, k):
|
||||||
|
self.x *= k
|
||||||
|
self.y *= k
|
||||||
|
self.z *= k
|
||||||
|
return self
|
||||||
|
|
||||||
|
def clone(self):
|
||||||
|
return Vec3(self.x, self.y, self.z)
|
||||||
|
|
||||||
|
def __neg__(self):
|
||||||
|
return Vec3(-self.x, -self.y, -self.z)
|
||||||
|
|
||||||
|
def __sub__(self, rhs):
|
||||||
|
return self.__add__(-rhs)
|
||||||
|
|
||||||
|
def __isub__(self, rhs):
|
||||||
|
return self.__iadd__(-rhs)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "Vec3(%s,%s,%s)"%(self.x,self.y,self.z)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter((self.x, self.y, self.z))
|
||||||
|
|
||||||
|
def _map(self, func):
|
||||||
|
self.x = func(self.x)
|
||||||
|
self.y = func(self.y)
|
||||||
|
self.z = func(self.z)
|
||||||
|
|
||||||
|
def __cmp__(self, rhs):
|
||||||
|
dx = self.x - rhs.x
|
||||||
|
if dx != 0: return dx
|
||||||
|
dy = self.y - rhs.y
|
||||||
|
if dy != 0: return dy
|
||||||
|
dz = self.z - rhs.z
|
||||||
|
if dz != 0: return dz
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def __eq__(self, rhs):
|
||||||
|
if self.x == rhs.x and self.y == rhs.y and self.z == rhs.z:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def iround(self): self._map(lambda v:int(v+0.5))
|
||||||
|
def ifloor(self): self._map(int)
|
||||||
|
|
||||||
|
def rotateLeft(self): self.x, self.z = self.z, -self.x
|
||||||
|
def rotateRight(self): self.x, self.z = -self.z, self.x
|
||||||
|
|
||||||
|
def testVec3():
|
||||||
|
# Note: It's not testing everything
|
||||||
|
|
||||||
|
# 1.1 Test initialization
|
||||||
|
it = Vec3(1, -2, 3)
|
||||||
|
assert it.x == 1
|
||||||
|
assert it.y == -2
|
||||||
|
assert it.z == 3
|
||||||
|
|
||||||
|
assert it.x != -1
|
||||||
|
assert it.y != +2
|
||||||
|
assert it.z != -3
|
||||||
|
|
||||||
|
# 2.1 Test cloning and equality
|
||||||
|
clone = it.clone()
|
||||||
|
assert it == clone
|
||||||
|
it.x += 1
|
||||||
|
assert it != clone
|
||||||
|
|
||||||
|
# 3.1 Arithmetic
|
||||||
|
a = Vec3(10, -3, 4)
|
||||||
|
b = Vec3(-7, 1, 2)
|
||||||
|
c = a + b
|
||||||
|
assert c - a == b
|
||||||
|
assert c - b == a
|
||||||
|
assert a + a == a * 2
|
||||||
|
|
||||||
|
assert a - a == Vec3(0,0,0)
|
||||||
|
assert a + (-a) == Vec3(0,0,0)
|
||||||
|
|
||||||
|
# Test repr
|
||||||
|
e = eval(repr(it))
|
||||||
|
assert e == it
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
testVec3()
|
||||||
69
Python/minecrafter.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Created on Fri Jun 14 14:16:11 2019
|
||||||
|
|
||||||
|
@author: savrillon
|
||||||
|
"""
|
||||||
|
|
||||||
|
from data import WorldChunk
|
||||||
|
import math
|
||||||
|
import numpy as np
|
||||||
|
import mcpi.minecraft as minecraft
|
||||||
|
import random
|
||||||
|
import mcpi.block as block
|
||||||
|
from perlin import CavernedNoise2
|
||||||
|
|
||||||
|
|
||||||
|
mc = minecraft.Minecraft.create()
|
||||||
|
mc.postToChat("Hello World !")
|
||||||
|
playerPos = mc.player.getPos()
|
||||||
|
tp = True
|
||||||
|
lights = True
|
||||||
|
chunk = (math.floor(playerPos.x/16),math.floor(playerPos.z/16))
|
||||||
|
|
||||||
|
noise = CavernedNoise2(456)
|
||||||
|
|
||||||
|
size = 64
|
||||||
|
for i in range(0,size):
|
||||||
|
for j in range(0,size):
|
||||||
|
cx,cy = chunk[0]+i,chunk[1]+j
|
||||||
|
print("Géneration de "+str(i)+","+str(j))
|
||||||
|
mc.postToChat("Géneration de "+str(i)+","+str(j))
|
||||||
|
if tp:
|
||||||
|
mc.player.setPos(cx*16+8,playerPos.y,cy*16+8)
|
||||||
|
data = noise.getChunk(cx,cy,(16,16))
|
||||||
|
#print(data)
|
||||||
|
#data = np.abs(data)
|
||||||
|
x0,z0 = cx*16,cy*16
|
||||||
|
x1,z1 = x0 + 15 , z0 + 15
|
||||||
|
y0,y1 = 4,128-1
|
||||||
|
h = y1-y0
|
||||||
|
|
||||||
|
mc.setBlocks(x0,y0,z0,x1,y1,z1,block.IRON_BLOCK)
|
||||||
|
|
||||||
|
for dx in range(0,16):
|
||||||
|
for dz in range(0,16):
|
||||||
|
x,z = x0+dx,z0+dz
|
||||||
|
boule = True
|
||||||
|
fm1 = y0
|
||||||
|
for f in sorted(data[dx][dz]):
|
||||||
|
if f < 0 :print(f)
|
||||||
|
mc.setBlocks(x,y0+fm1,z,x,y0+f,z,block.STONE if boule else block.AIR)
|
||||||
|
#mc.setBlock(x,y0+fm1,z,x,d,z,block.STONE if boule else block.AIR)
|
||||||
|
boule = not boule
|
||||||
|
fm1 = f
|
||||||
|
mc.setBlocks(x,y0+fm1,z,x,y1,z,block.AIR)
|
||||||
|
|
||||||
|
|
||||||
|
if(lights):
|
||||||
|
for _ in range(256*size**2):
|
||||||
|
x=random.randint(0,size*16)+chunk[0]*16
|
||||||
|
y=random.randint(y0,y1)
|
||||||
|
x=random.randint(0,size*16)+chunk[1]*16
|
||||||
|
if(mc.getBlock(x,y,z)==block.STONE.id):
|
||||||
|
mc.setBlock(x,y,z,block.GLOWSTONE_BLOCK)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print(chunk)
|
||||||
|
|
||||||
374
Python/objection.py
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Created on Thu Aug 22 19:46:36 2019
|
||||||
|
|
||||||
|
@author: mysaa
|
||||||
|
"""
|
||||||
|
import numpy as np
|
||||||
|
from data import CollageWorldChunk
|
||||||
|
from perlin import CavernedNoise2,TestNoise
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def getTriangles(x0,y0,chunk,xp,yp,xy):
|
||||||
|
|
||||||
|
|
||||||
|
nx,ny = chunk.size
|
||||||
|
newChunk = CollageWorldChunk(chunk,xp,yp,xy)
|
||||||
|
|
||||||
|
# pointIndexes = np.zeros((nx+1,ny+1),dtype=np.uint32)
|
||||||
|
# pointLengthes = np.zeros((nx+1,ny+1),dtype=np.uint32)
|
||||||
|
# points = []
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# pos = 0
|
||||||
|
# for j in range(ny):
|
||||||
|
# for i in range(nx):
|
||||||
|
# carotte = [(x0+i/nx,y0+j/ny,z) for z in sorted([0.]+list(chunk.getColumn(i,j)))]
|
||||||
|
# points += carotte
|
||||||
|
# pointLengthes[i,j] = len(carotte)
|
||||||
|
# pointIndexes[i,j] = pos
|
||||||
|
# pos+=len(carotte)
|
||||||
|
# carotte = [(x0+1,y0+j/ny,z) for z in sorted([0.]+list(xp.getColumn(0,j)))]
|
||||||
|
# points += carotte
|
||||||
|
# pointLengthes[nx,j]= len(carotte)
|
||||||
|
# pointIndexes[nx,j] = pos
|
||||||
|
# pos+=len(carotte)
|
||||||
|
# for i in range(nx):
|
||||||
|
# carotte = [(x0+i/nx,y0+1,z) for z in sorted([0.]+list(yp.getColumn(i,0)))]
|
||||||
|
# points += carotte
|
||||||
|
# pointLengthes[i,ny] = len(carotte)
|
||||||
|
# pointIndexes[i,ny] = pos
|
||||||
|
# pos+=len(carotte)
|
||||||
|
# carotte = [(x0+1,y0+1,z) for z in sorted([0.]+list(xy.getColumn(0,0)))]
|
||||||
|
# points += carotte
|
||||||
|
# pointLengthes[nx,ny] = len(carotte)
|
||||||
|
# pointIndexes[nx,ny] = pos
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
points,pointIndexes = newChunk.getIndexed(fullCoords=True,addZero=True)
|
||||||
|
|
||||||
|
points=[(p[0]/nx+x0,p[1]/ny+y0,p[2]) for p in points]
|
||||||
|
pointLengthes = np.reshape([pointIndexes[i+1]-pointIndexes[i] for i in range(len(pointIndexes)-1)],(nx+1,ny+1))
|
||||||
|
pointIndexes = np.reshape(pointIndexes[:-1],(nx+1,ny+1))
|
||||||
|
print(points,pointIndexes,pointLengthes)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
triangles = []
|
||||||
|
|
||||||
|
|
||||||
|
for x in range(nx*2):
|
||||||
|
for y in range(ny):
|
||||||
|
# On récupère les coordonées entières du triangle indicé (x,y)
|
||||||
|
if(x%2==0):
|
||||||
|
col0=(x//2 ,y )
|
||||||
|
col1=(x//2+1,y )
|
||||||
|
col2=(x//2 ,y+1)
|
||||||
|
else:
|
||||||
|
col0=(x//2+1,y+1)
|
||||||
|
col1=(x//2+1,y )
|
||||||
|
col2=(x//2 ,y+1)
|
||||||
|
|
||||||
|
# On récupère la liste des points dans la colonne
|
||||||
|
colonne0 = points[pointIndexes[col0[0],col0[1]]:pointIndexes[col0[0],col0[1]]+pointLengthes[col0[0],col0[1]]]
|
||||||
|
colonne1 = points[pointIndexes[col1[0],col1[1]]:pointIndexes[col1[0],col1[1]]+pointLengthes[col1[0],col1[1]]]
|
||||||
|
colonne2 = points[pointIndexes[col2[0],col2[1]]:pointIndexes[col2[0],col2[1]]+pointLengthes[col2[0],col2[1]]]
|
||||||
|
#print("colonne:",colonne1)
|
||||||
|
# st contient des triplets (numéro de colonne,index interne dans la colonne,coordonée z)
|
||||||
|
st = [(0,i,colonne0[i][2]) for i in range(len(colonne0))]
|
||||||
|
st += [(1,i,colonne1[i][2]) for i in range(len(colonne1))]
|
||||||
|
st += [(2,i,colonne2[i][2]) for i in range(len(colonne2))]
|
||||||
|
|
||||||
|
|
||||||
|
# On y trie par coordonée z
|
||||||
|
st = sorted(st,key=lambda c:c[2])
|
||||||
|
|
||||||
|
#Liste des coordonées des colonnes, pour pouvoir sélectionner les coordonées selon l'index de la colonne
|
||||||
|
cols = [col0,col1,col2]
|
||||||
|
# Là, tout est bon à peu près
|
||||||
|
|
||||||
|
i=0
|
||||||
|
try:
|
||||||
|
while i<len(st):
|
||||||
|
v1 = st[i] ; i+=1
|
||||||
|
v2 = st[i] ; i+=1
|
||||||
|
if v1[0]==v2[0]: continue #Cas où une colonne apparait puis disparaît
|
||||||
|
von = [v1,v2,None]
|
||||||
|
voff = [None,None,None]
|
||||||
|
while not None in von and voff!=[None,None,None]:
|
||||||
|
# On est dans la chaine aller-retour 2/1
|
||||||
|
v3 = st[i] ; i+=1
|
||||||
|
if voff[v3[0]]==None and von[v3[0]]!=None:
|
||||||
|
# Il s'agit d'un changement plein->vide
|
||||||
|
voff[v3[0]] = v3
|
||||||
|
else:
|
||||||
|
# Changement vide->plein
|
||||||
|
von[v3[0]] = v3
|
||||||
|
voff[v3[0]] = None
|
||||||
|
if not None in von and not None in voff:
|
||||||
|
# Les deux colonnes ont disparu
|
||||||
|
# On peut créer le rectangle entre les deux derniers à avoir disparu et leur point d'apparitions
|
||||||
|
v3,v4 = st[i],st[i-1]
|
||||||
|
v1,v2 = von[v3[0]],von[v4[0]]
|
||||||
|
triangle1 = [pointIndexes[cols[v[0]]] + v[1] for v in (v1,v2,v3)]
|
||||||
|
triangle2 = [pointIndexes[cols[v[0]]] + v[1] for v in (v1,v3,v4)]
|
||||||
|
triangles.append(triangle1)
|
||||||
|
triangles.append(triangle2)
|
||||||
|
break
|
||||||
|
|
||||||
|
else:
|
||||||
|
# On est dans le cas ou v1,v2,v3 correspondent à trois colonnes
|
||||||
|
# différentes (le cas (1,1,1) ayant déjà été filtré par la première condition)
|
||||||
|
|
||||||
|
# On ajoute le triangle en dessous
|
||||||
|
triangle = [pointIndexes[cols[v[0]]] + v[1] for v in (v1,v2,v3)]
|
||||||
|
triangles.append(triangle)
|
||||||
|
|
||||||
|
# On "attends" jusqu'à ce que les trois colonnes soient à nouveau vides
|
||||||
|
vs = [None,None,None]
|
||||||
|
while None in vs:
|
||||||
|
print("Quentin",st,i,vs)
|
||||||
|
v = st[i] ; i+=1
|
||||||
|
vs[v[0]] = v if vs[v[0]]==None else None
|
||||||
|
|
||||||
|
# Avec cette mthode, on déssine le triangle avec les derniers points étant apparus (les plus hauts)
|
||||||
|
triangle = [pointIndexes[cols[v[0]]] + v[1] for v in vs]
|
||||||
|
triangles.append(triangle)
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
# Une fin de liste a été atteinte, la colonne n'a pas été refermée: lance un warn
|
||||||
|
print("Attention ! Une colonne n'avait pas de toit. veuillez vérifier que vos colonnes aient un nombre impair de coordonées, merci !")
|
||||||
|
|
||||||
|
return points,triangles
|
||||||
|
########################################
|
||||||
|
# while i<len(st):
|
||||||
|
# #Plein
|
||||||
|
# v0 = st[i]
|
||||||
|
# i+=1
|
||||||
|
# v1 = st[i]
|
||||||
|
# i+=1
|
||||||
|
# if(v0[0] == v1[0]): # S'est la même colonne qui est apparu puis disparu
|
||||||
|
#
|
||||||
|
# print("Tribord")
|
||||||
|
# colz = cols[v0[0]]
|
||||||
|
# # Triangle sur les bords
|
||||||
|
# # Demis-points
|
||||||
|
# halfZ = (v0[2]+v1[2])/2
|
||||||
|
# #Les deux autres colonnes sont :
|
||||||
|
# cola = cols[(v0[0]+1)%3]
|
||||||
|
# colb = cols[(v0[0]+2)%3]
|
||||||
|
#
|
||||||
|
# zi1,zi2=pointIndexes[colz]+v0[1],pointIndexes[colz]+v1[1]
|
||||||
|
# print('OoOOoO',points[zi1],points[zi2])
|
||||||
|
#
|
||||||
|
## points.append( (x0+(cola[0])/nx,y0+(cola[1])/ny,halfZ) )
|
||||||
|
## points.append( (x0+(colb[0])/nx,y0+(colb[1])/ny,halfZ) )
|
||||||
|
##
|
||||||
|
## triangles.append([zi1,len(points)-1,len(points)-2])
|
||||||
|
## triangles.append([zi2,len(points)-1,len(points)-2])
|
||||||
|
# print("Tribord-fin")
|
||||||
|
# # print(points[-1],points[-2],points[zi1])
|
||||||
|
# #print(cola,colb,points[triangles[-1][0]-1],points[triangles[-1][1]-1],points[triangles[-1][2]-1])
|
||||||
|
#
|
||||||
|
# else: # Deux colonnes différentes ont apparus successivement
|
||||||
|
# # vs stoque les états des colonnes
|
||||||
|
# # vs[i] est l'état de la ième colonne, le point de st, dernier à apparaître si
|
||||||
|
# # cette colonne est présente, None sinon
|
||||||
|
# vs=[None,None,None]
|
||||||
|
# vs[v0[0]] = v0
|
||||||
|
# vs[v1[0]] = v1
|
||||||
|
# while None in vs and vs != [None,None,None]:# Tant qu'il y a une abscente ou une présente
|
||||||
|
# v2 = st[i]
|
||||||
|
# i+=1
|
||||||
|
# vs[v2[0]] = v2 if vs[v2[0]]==None else None
|
||||||
|
#
|
||||||
|
# if not None in vs:
|
||||||
|
# # Une face complète a été créée
|
||||||
|
# # Triangle complet
|
||||||
|
# # Face dessous (apparition de la colonne)
|
||||||
|
# triangle = [pointIndexes[cols[i]] + vs[i][1] for i in range(3)]
|
||||||
|
# triangles.append(triangle)
|
||||||
|
# #print("#",[points[triangle[i]] for i in range(0,3)])
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# # On inverse le sens de vs, et stoque les premiers points à apparaître
|
||||||
|
# vs = [None,None,None]
|
||||||
|
# while None in vs and i<len(st):
|
||||||
|
# v2 = st[i]
|
||||||
|
# i+=1
|
||||||
|
# vs[v2[0]] = v2 if vs[v2[0]]==None else None
|
||||||
|
#
|
||||||
|
# #Face dessus
|
||||||
|
# if not None in vs:
|
||||||
|
# triangle = [pointIndexes[cols[i]] + vs[i][1] for i in range(3)]
|
||||||
|
# triangles.append(triangle)
|
||||||
|
# #print("0",[points[triangle[i]] for i in range(3)])
|
||||||
|
# else:
|
||||||
|
# # Il faut placer un carré
|
||||||
|
# #########################################
|
||||||
|
# print(points)
|
||||||
|
# return points,triangles
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def getRectangles(x0,y0,chunk):
|
||||||
|
nx,ny = chunk.size
|
||||||
|
|
||||||
|
triangles = []
|
||||||
|
points = []
|
||||||
|
|
||||||
|
for x in range(nx) :
|
||||||
|
for y in range(ny):
|
||||||
|
for z in [0]+chunk.getColumn(x,y):
|
||||||
|
points.append([x/nx+x0,y/ny+y0,z])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0,z])
|
||||||
|
points.append([x/nx+x0,y/ny+y0+1/ny,z])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0+1/ny,z])
|
||||||
|
triangles.append([len(points)-4,len(points)-3,len(points)-2])
|
||||||
|
triangles.append([len(points)-3,len(points)-2,len(points)-1])
|
||||||
|
|
||||||
|
return points,triangles
|
||||||
|
|
||||||
|
def getRectCols(x0,y0,chunk):
|
||||||
|
nx,ny = chunk.size
|
||||||
|
|
||||||
|
triangles = []
|
||||||
|
points = []
|
||||||
|
e=0.3
|
||||||
|
|
||||||
|
for x in range(nx) :
|
||||||
|
for y in range(ny):
|
||||||
|
for z in [0]+chunk.getColumn(x,y):
|
||||||
|
points.append([x/nx+x0-e,y/ny+y0-e,z])
|
||||||
|
points.append([x/nx+x0+e,y/ny+y0-e,z])
|
||||||
|
points.append([x/nx+x0-e,y/ny+y0+e,z])
|
||||||
|
points.append([x/nx+x0+e,y/ny+y0+e/ny,z])
|
||||||
|
triangles.append([len(points)-4,len(points)-3,len(points)-2])
|
||||||
|
triangles.append([len(points)-3,len(points)-2,len(points)-1])
|
||||||
|
|
||||||
|
return points,triangles
|
||||||
|
|
||||||
|
|
||||||
|
def getFilled(x0,y0,chunk):
|
||||||
|
nx,ny = chunk.size
|
||||||
|
|
||||||
|
triangles = []
|
||||||
|
points = []
|
||||||
|
|
||||||
|
for x in range(nx) :
|
||||||
|
for y in range(ny):
|
||||||
|
boule = True
|
||||||
|
lz = 0
|
||||||
|
for z in sorted(chunk.getColumn(x,y)):
|
||||||
|
|
||||||
|
if boule:
|
||||||
|
points.append([x/nx+x0 ,y/ny+y0 ,z ])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0 ,z ])
|
||||||
|
points.append([x/nx+x0 ,y/ny+y0+1/ny,z ])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0+1/ny,z ])
|
||||||
|
points.append([x/nx+x0 ,y/ny+y0 ,lz])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0 ,lz])
|
||||||
|
points.append([x/nx+x0 ,y/ny+y0+1/ny,lz])
|
||||||
|
points.append([x/nx+x0+1/nx,y/ny+y0+1/ny,lz])
|
||||||
|
l = len(points)
|
||||||
|
triangles.append([l-4,l-2,l-1])
|
||||||
|
triangles.append([l-4,l-3,l-1])
|
||||||
|
triangles.append([l-4,l-2,l-6])
|
||||||
|
triangles.append([l-4,l-8,l-6])
|
||||||
|
triangles.append([l-4,l-3,l-7])
|
||||||
|
triangles.append([l-4,l-8,l-7])
|
||||||
|
triangles.append([l-5,l-1,l-2])
|
||||||
|
triangles.append([l-5,l-6,l-2])
|
||||||
|
triangles.append([l-5,l-6,l-8])
|
||||||
|
triangles.append([l-5,l-7,l-8])
|
||||||
|
triangles.append([l-5,l-7,l-3])
|
||||||
|
triangles.append([l-5,l-1,l-3])
|
||||||
|
|
||||||
|
boule = not boule
|
||||||
|
lz = z
|
||||||
|
|
||||||
|
|
||||||
|
return points,triangles
|
||||||
|
|
||||||
|
def printObject(file,name,delta,points,triangles):
|
||||||
|
file.write("o "+name+"\n\n")
|
||||||
|
|
||||||
|
sf = lambda x : "%.6f" % float(x)
|
||||||
|
si = lambda x : str(int(x+1)+delta)
|
||||||
|
|
||||||
|
for p in points:
|
||||||
|
file.write("v "+sf(p[0])+" "+sf(p[1])+" "+sf(np.array(p[2])/20.)+"\n")
|
||||||
|
|
||||||
|
file.write("\n")
|
||||||
|
|
||||||
|
for t in triangles:
|
||||||
|
file.write("f "+" ".join([si(tp) for tp in t])+"\n")
|
||||||
|
|
||||||
|
|
||||||
|
def writeMap(filePath,noise,x0,y0,sx,sy,cx,cy,objType='triangle',log=print):
|
||||||
|
log("Génération de la carte")
|
||||||
|
generated = {}
|
||||||
|
formatter='\rÉcriture du chunk {};{} '+" "*(sx//10+sy//10)
|
||||||
|
for i in range(x0,sx+x0+(1 if objType=='triangle' else 0)):
|
||||||
|
for j in range(y0,sy+y0+(1 if objType=='triangle' else 0)):
|
||||||
|
log(formatter.format(i,j), end='\r')
|
||||||
|
generated[(i,j)] = noise.getChunk(i,j,(cx,cy))
|
||||||
|
log("Génération des objets")
|
||||||
|
file = open(filePath,"w+")
|
||||||
|
file.write("g carte\n")
|
||||||
|
delta=0
|
||||||
|
for i in range(x0,sx+x0):
|
||||||
|
for j in range(y0,sy+y0):
|
||||||
|
log(formatter.format(i,j), end='\r')
|
||||||
|
if objType=='triangle':
|
||||||
|
points,triangles = getTriangles(i,j,generated[(i,j)],generated[(i+1,j)],generated[(i,j+1)],generated[(i+1,j+1)])
|
||||||
|
elif objType=='rectangle':
|
||||||
|
points,triangles = getRectangles(i,j,generated[(i,j)])
|
||||||
|
elif objType=='filled':
|
||||||
|
points,triangles = getFilled(i,j,generated[(i,j)])
|
||||||
|
elif objType=='rectcols':
|
||||||
|
points,triangles = getRectCols(i,j,generated[(i,j)])
|
||||||
|
else:
|
||||||
|
raise ValueError("Je en connais pas le type d'objet "+objType)
|
||||||
|
printObject(file,"chunk_"+objType+"_"+str(i)+"-"+str(j),delta,points,triangles)
|
||||||
|
file.write("\n\n")
|
||||||
|
delta+=len(points)
|
||||||
|
log("\nTerminé ! "+" "*(sx//10+sy//10))
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
noise = CavernedNoise2(93152)
|
||||||
|
|
||||||
|
size = 12
|
||||||
|
taille=16
|
||||||
|
|
||||||
|
#writeMap("gros.obj",noise,-size//2+1,-size//2+1,size,size,taille,taille,'triangle')
|
||||||
|
#writeMap("carte.obj",noise,2,1,1,1,16,16,'triangle')
|
||||||
|
writeMap("carteTri.obj",noise,-8,-8,16,16,16,16,'triangle')
|
||||||
|
#writeMap("carteRec.obj",noise,-8,-8,16,16,16,16,'rectangle')
|
||||||
|
#writeMap("carteFil.obj",noise,-8,-8,16,16,16,16,'filled')
|
||||||
|
#writeMap("carteRCo.obj",noise,-8,-8,16,16,16,16,'rectcols')
|
||||||
|
|
||||||
|
#xy0=-taille*size
|
||||||
|
#for x in range(2*taille):
|
||||||
|
# for y in range(2*taille):
|
||||||
|
#
|
||||||
|
# writeMap("render2/carte"+str(x)+","+str(y)+".obj",noise,xy0-size//2+x*size,xy0-size//2+y*size,size,size,'rectangle')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
Python/perlin-valeurs.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
461
Python/perlin.py
Normal file
@ -0,0 +1,461 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Created on Fri Mar 8 15:13:12 2019
|
||||||
|
|
||||||
|
Ce module contient de nombreuses implémentations de Noise, permetant en les assemblant de créer des mondes
|
||||||
|
|
||||||
|
@author: mysaa
|
||||||
|
"""
|
||||||
|
|
||||||
|
from data import ArrayedWorldChunk,Noise
|
||||||
|
import random as r
|
||||||
|
import numpy as np
|
||||||
|
from math import sqrt,floor,ceil,pi
|
||||||
|
|
||||||
|
|
||||||
|
##### Paramètres #####
|
||||||
|
G = 4.5
|
||||||
|
F = 5.2
|
||||||
|
|
||||||
|
|
||||||
|
class RandNoise(Noise):
|
||||||
|
"""
|
||||||
|
Ce bruit renvoie une carte de vecteurs complexes (2d) du cercle trigonométrique (de module 1)
|
||||||
|
"""
|
||||||
|
seed = None
|
||||||
|
f = None
|
||||||
|
|
||||||
|
def __init__(self,seed,f=lambda r : r.random()):
|
||||||
|
self.seed = seed
|
||||||
|
self.f = f
|
||||||
|
|
||||||
|
def getRandomly(self,xg,yg):
|
||||||
|
"""
|
||||||
|
Cette fonction renvoie un nombre complexe aléatoire du cercle
|
||||||
|
trigonométrique, uniformément distribué selon l'argument.
|
||||||
|
Cette fonction est déterministe pour un même seed demandé.
|
||||||
|
"""
|
||||||
|
s = ((self.seed & 0xFFFFFFFFFFFFFFFF) << 64) | ((int(xg) & 0xFFFFFFFF) << 32) | (int(yg) & 0xFFFFFFFF)
|
||||||
|
r.seed(s)
|
||||||
|
return self.f(r)
|
||||||
|
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
"""
|
||||||
|
x,y sont les coordonées du chunk à considérer (boucle au bout de 4294967296=2^32) java:int
|
||||||
|
n est un couple ou une liste d'aumoins deux éléments contenant la précision suivant x et y du chunk
|
||||||
|
"""
|
||||||
|
randomizer = lambda i,j : self.getRandomly(x+i,y+j)
|
||||||
|
|
||||||
|
return np.fromfunction(np.vectorize(randomizer),(n[0],n[1]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class RandLinNoise(RandNoise):
|
||||||
|
|
||||||
|
y0 = 0
|
||||||
|
y1 = 1
|
||||||
|
|
||||||
|
def __init__(self,seed,y0,y1):
|
||||||
|
super().__init__(seed,lambda r : (y1-y0)*r.random() + y0)
|
||||||
|
|
||||||
|
class RandTrigNoise(RandNoise):
|
||||||
|
|
||||||
|
def __init__(self,seed):
|
||||||
|
super().__init__(seed,lambda r : np.exp(1j*2*pi*r.random()))
|
||||||
|
|
||||||
|
class DroiteNoise(Noise):
|
||||||
|
|
||||||
|
seed = None
|
||||||
|
F,D = 0,0
|
||||||
|
|
||||||
|
def __init__(self,seed,F,D):
|
||||||
|
self.seed = seed
|
||||||
|
self.F,self.D = F,D
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n=None):
|
||||||
|
|
||||||
|
return self.getLoadedDroites(x,y)
|
||||||
|
|
||||||
|
# randomizer = lambda i,j : self.getRandomGradient(x+i,y+j)
|
||||||
|
#
|
||||||
|
# return np.fromfunction(np.vectorize(randomizer),(n,))
|
||||||
|
|
||||||
|
def getLoadedDroites(self,x,y):
|
||||||
|
"""
|
||||||
|
Cette fonction renvoie la liste des droites devant être considérées dans la génération du chunk x,y. Cela permet d'effectuer la génération procédurale.
|
||||||
|
"""
|
||||||
|
def dst(x0,x1,y0,y1):
|
||||||
|
"""
|
||||||
|
Cette fonction renvoie la ditance eucildienne 2D entre les points (x0,y0) et (x1,y1)
|
||||||
|
"""
|
||||||
|
return sqrt( (x1-x0)**2 + (y1-y0)**2 )
|
||||||
|
|
||||||
|
F = self.F
|
||||||
|
x0 = floor(x-F)
|
||||||
|
x1 = floor(x+F+1)
|
||||||
|
y0 = floor(y-F)
|
||||||
|
y1 = floor(y+F+1)
|
||||||
|
# print(x0,x1,y0,y1)
|
||||||
|
drts = []
|
||||||
|
for i in range(x0,x1+1):
|
||||||
|
for j in range(y0,y1+1):
|
||||||
|
for d in self.getDroitesOnChunk(i,j):
|
||||||
|
# Tester si la droite sera utile
|
||||||
|
dx = d[0]+i
|
||||||
|
dy = d[1]+j
|
||||||
|
if (x <= dx <= x+1 and y-F <= dy <= y+F+1) or (y <= dy <= y+1 and x-F <= dx <= x+F+1) or (min(dst(x,dx,y,dy),dst(x+1,dx,y,dy),dst(x+1,dx,y+1,dy),dst(x,dx,y+1,dy)) <= F):
|
||||||
|
drts.append((dx,dy,d[2]))
|
||||||
|
# print(len(drts))
|
||||||
|
return drts
|
||||||
|
|
||||||
|
|
||||||
|
def getDroitesOnChunk(self,xg,yg):
|
||||||
|
s = ((self.seed & 0xFFFFFFFFFFFFFFFF) << 64) | ((int(xg) & 0xFFFFFFFF) << 32) | (int(yg) & 0xFFFFFFFF)
|
||||||
|
r.seed(s)
|
||||||
|
L = []
|
||||||
|
for i in range(self.D):
|
||||||
|
lx = r.random()
|
||||||
|
ly = r.random()
|
||||||
|
theta = r.random()*2*pi
|
||||||
|
L.append((lx,ly,theta))
|
||||||
|
return L
|
||||||
|
|
||||||
|
|
||||||
|
class PerlinNoise(Noise):
|
||||||
|
|
||||||
|
G = None
|
||||||
|
randomizer = None
|
||||||
|
interpol = None
|
||||||
|
wrapper = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self,G,randomizer,interpol=lambda a,b,w : (b-a)*w**2*6*(1/2-w/3)+a,wrapper = lambda x : np.tanh(x*3.8622)): # Par défaut, un banale interpolation linéaire
|
||||||
|
self.G = G
|
||||||
|
if type(randomizer) == int:
|
||||||
|
randomizer = RandTrigNoise(randomizer)
|
||||||
|
self.randomizer = randomizer
|
||||||
|
self.interpol = interpol
|
||||||
|
self.wrapper = wrapper
|
||||||
|
|
||||||
|
def getChunkGradients(self,x,y):
|
||||||
|
G=self.G # Python de merde !
|
||||||
|
x0 = floor(x/G)
|
||||||
|
x1 = ceil((x+1)/G)
|
||||||
|
y0 = floor(y/G)
|
||||||
|
y1 = ceil((y+1)/G)
|
||||||
|
nx = x1-x0+1
|
||||||
|
ny = y1-y0+1
|
||||||
|
# grads = np.fromfunction(np.vectorize(lambda x,y : self.getPerlinGradient(x+x0,y+y0)),(nx,ny))
|
||||||
|
grads = self.randomizer.getChunk(x0,y0,(nx,ny))
|
||||||
|
return grads,x0,y0
|
||||||
|
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
|
||||||
|
G = self.G
|
||||||
|
chunk = np.zeros(n) # Initialise la sortie
|
||||||
|
|
||||||
|
gradients,x0,y0 = self.getChunkGradients(x,y)
|
||||||
|
|
||||||
|
def dotGridGradient(ix, iy, tx, ty):
|
||||||
|
dx = tx - ix
|
||||||
|
dy = ty - iy
|
||||||
|
return (np.conj(gradients[ix-x0][iy-y0])*(dx+1j*dy)).real
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(n[0]):
|
||||||
|
for j in range(n[1]):
|
||||||
|
#C------------D#
|
||||||
|
#| |#
|
||||||
|
#| |#
|
||||||
|
#| |#
|
||||||
|
#| x M |#
|
||||||
|
#| |#
|
||||||
|
#A------------B#
|
||||||
|
posx = x + i/n[0]
|
||||||
|
posy = y + j/n[1]
|
||||||
|
xx = posx / G
|
||||||
|
yy = posy / G
|
||||||
|
xx0 = floor(xx)
|
||||||
|
yy0 = floor(yy)
|
||||||
|
xx1 = xx0 + 1
|
||||||
|
yy1 = yy0 + 1
|
||||||
|
|
||||||
|
|
||||||
|
gA = dotGridGradient(xx0, yy0, xx, yy);
|
||||||
|
gB = dotGridGradient(xx1, yy0, xx, yy);
|
||||||
|
gC = dotGridGradient(xx0, yy1, xx, yy);
|
||||||
|
gD = dotGridGradient(xx1, yy1, xx, yy);
|
||||||
|
haut = self.interpol(gA, gB, xx - xx0);
|
||||||
|
bas = self.interpol(gC, gD, xx - xx0);
|
||||||
|
valeur = self.interpol(haut, bas, yy - yy0);
|
||||||
|
|
||||||
|
chunk[i,j] = valeur
|
||||||
|
|
||||||
|
return self.wrapper(chunk)
|
||||||
|
|
||||||
|
class FractalNoise(Noise):
|
||||||
|
|
||||||
|
F = None
|
||||||
|
D = None
|
||||||
|
epsilon = None
|
||||||
|
interpol = None
|
||||||
|
droiteMaker = None
|
||||||
|
|
||||||
|
def interpolizer(n,F):
|
||||||
|
"""
|
||||||
|
Retourne une fonction polynomiale réelle sur [-F,F] et nulle autre part, s'annule en F et -F, vaut 1 en 0 et a comme dérivée 0 en -F,0 et F. n+1 est le degré de la racine 0.
|
||||||
|
"""
|
||||||
|
return lambda x : 0 if abs(x)>F else 1 + (2*n**2+6*n+4)/(F**(2*n+4)) * ((x**2)/(2*n+4)-(F**2)/(2*n+2))*abs(x)**(2*n+2)
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self,F,D,epsilon,droiteMaker,n = 1):
|
||||||
|
self.F = F
|
||||||
|
self.D = D
|
||||||
|
self.epsilon = epsilon
|
||||||
|
if type(droiteMaker) == int:
|
||||||
|
droiteMaker = DroiteNoise(droiteMaker,F,D)
|
||||||
|
self.droiteMaker = droiteMaker
|
||||||
|
self.interpol = FractalNoise.interpolizer(n,F)
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
drts = self.droiteMaker.getChunk(x,y)
|
||||||
|
chunk = np.zeros(n)
|
||||||
|
epsilon = self.epsilon
|
||||||
|
interpol = self.interpol
|
||||||
|
|
||||||
|
def dst(x0,x1,y0,y1):
|
||||||
|
return sqrt( (x1-x0)**2 + (y1-y0)**2 )
|
||||||
|
|
||||||
|
def kelkote(drt,x,y):
|
||||||
|
dx = drt[0]
|
||||||
|
dy = drt[1]
|
||||||
|
#print(x,y,dx,dy)
|
||||||
|
return 1 if (np.exp(1j*(drt[2]+pi/2)) * ((x-dx)+(dy-y)*1j)).real >= 0 else -1
|
||||||
|
|
||||||
|
# FractalNoise(0.7,511,0.01,42).getChunk(3,3,(16,16))
|
||||||
|
#33.8 s ± 72.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
|
||||||
|
for d in drts:
|
||||||
|
drteffect = lambda i,j : interpol(dst(d[0],i/n[0] + x,d[1],j/n[1] + y))*kelkote(d,i/n[0] + x,j/n[1] + y)*epsilon
|
||||||
|
chunk += np.fromfunction(np.vectorize(drteffect),n)
|
||||||
|
|
||||||
|
# FractalNoise(0.7,511,0.01,42).getChunk(3,3,(16,16))
|
||||||
|
#28.9 s ± 344 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
|
||||||
|
# for i in range(n[0]):
|
||||||
|
# for j in range(n[1]):
|
||||||
|
# posx = i/n[0] + x
|
||||||
|
# posy = j/n[1] + y
|
||||||
|
# value = 0
|
||||||
|
## print(i,j)
|
||||||
|
# for d in drts:
|
||||||
|
# value += interpol(dst(d[0],posx,d[1],posy))*kelkote(d,posx,posy)*epsilon
|
||||||
|
# chunk[i,j] = value
|
||||||
|
return chunk
|
||||||
|
|
||||||
|
|
||||||
|
class TestNoise(Noise):
|
||||||
|
|
||||||
|
nn = PerlinNoise
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
|
||||||
|
indexes = np.array([i for i in range(n[0]*n[1]+1)])
|
||||||
|
data = np.ones((n[0]*n[1]))
|
||||||
|
return WorldChunk(n,indexes,data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CavernedNoise(Noise):
|
||||||
|
|
||||||
|
perlinSurface = None
|
||||||
|
perlinGrotte = None
|
||||||
|
perlinFond = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.perlinSurface = PerlinNoise(.5,64)
|
||||||
|
self.perlinGrotte = PerlinNoise(7 ,77)
|
||||||
|
self.perlinFond = PerlinNoise(.3 ,23)
|
||||||
|
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
chk = self.perlinSurface.getChunk(x,y,n)
|
||||||
|
fond = self.perlinFond.getChunk(x,y,n)
|
||||||
|
grotte=self.perlinGrotte.getChunk(x,y,n)
|
||||||
|
|
||||||
|
out = []
|
||||||
|
|
||||||
|
for i in range(n[0]):
|
||||||
|
lig = []
|
||||||
|
for j in range(n[1]):
|
||||||
|
if(grotte[i,j]>.2): # Pas de grotte
|
||||||
|
lig.append([chk[i,j]])
|
||||||
|
elif(grotte[i,j]>0):
|
||||||
|
lig.append([fond[i,j]])
|
||||||
|
else:
|
||||||
|
lig.append([fond[i,j],chk[i,j]-0.1*abs(grotte[i,j]),chk[i,j]])
|
||||||
|
out.append(lig)
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
class CavernedNoise2(Noise):
|
||||||
|
|
||||||
|
perlinCielH = None
|
||||||
|
perlinGHaut = None
|
||||||
|
perlinGH = None
|
||||||
|
perlinGHp = None
|
||||||
|
perlinGBas = None
|
||||||
|
|
||||||
|
#-x^(4)+4x^(3)-6x^(2)+4x
|
||||||
|
|
||||||
|
def __init__(self,seed):
|
||||||
|
self.perlinCielH = PerlinNoise(7 ,seed)
|
||||||
|
self.perlinGHaut = PerlinNoise(5 ,seed)
|
||||||
|
self.perlinGH = PerlinNoise(25 ,seed)
|
||||||
|
self.perlinGHp = PerlinNoise(1 ,seed)
|
||||||
|
self.perlinGBas = PerlinNoise(5 ,seed)
|
||||||
|
|
||||||
|
|
||||||
|
def getChunk(self,x,y,n):
|
||||||
|
gtTransform = np.vectorize(lambda x : 0 if x<0 else sqrt(2*x-x**2)**1.5)
|
||||||
|
transform=lambda M,a,b : M*b+a
|
||||||
|
cielH = transform(self.perlinCielH.getChunk(x,y,n),28,28)
|
||||||
|
gHaut = transform(self.perlinGHaut.getChunk(x,y,n),60,20)
|
||||||
|
ghp = transform(self.perlinGHp.getChunk(x,y,n) ,0.005,0.005)
|
||||||
|
ghh = transform(self.perlinGHp.getChunk(x,y,n) ,0.5,0.5)
|
||||||
|
gBas = transform(self.perlinGBas.getChunk(x,y,n),10,10)
|
||||||
|
gh = gtTransform(ghp+ghh)
|
||||||
|
|
||||||
|
toit = 128
|
||||||
|
|
||||||
|
out = []
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(n[0]):
|
||||||
|
lig = []
|
||||||
|
for j in range(n[1]):
|
||||||
|
ch = cielH[i,j] # la hauteur entre la surface et le ciel
|
||||||
|
ght = gHaut[i,j] # haut limite de la grotte
|
||||||
|
gbs = gBas[i,j] # bas limite de la grotte
|
||||||
|
hauteur=gh[i,j] # pourcentage de hauteur de la grotte
|
||||||
|
grh = (ght+gbs +hauteur*(ght-gbs))/2 # vrai plafond de la grotte
|
||||||
|
grb = (ght+gbs -hauteur*(ght-gbs))/2 # vrai sol de la grotte
|
||||||
|
if(ght<=40):print(ght)
|
||||||
|
if hauteur==0:
|
||||||
|
# Pas de grotte
|
||||||
|
lig.append([toit-ch])
|
||||||
|
elif(grh+ch>=toit):
|
||||||
|
# La grotte est ouverte sur la surface
|
||||||
|
lig.append([grb])
|
||||||
|
else:
|
||||||
|
# Grotte souterraine et surface
|
||||||
|
lig.append([grb,grh,toit-ch])
|
||||||
|
|
||||||
|
out.append(lig)
|
||||||
|
|
||||||
|
return ArrayedWorldChunk.fromList(out)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#for c in cmaps:
|
||||||
|
# pp.figure()
|
||||||
|
# print(c)
|
||||||
|
# pp.imshow(I, cmap=c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#sys.exit()
|
||||||
|
####### Fenêtre graphique #######
|
||||||
|
#from PyQt5.QtWidgets import QVBoxLayout,QHBoxLayout,QPushButton,QWidget,QApplication,QFormLayout,QLabel,QTextEdit,QDial
|
||||||
|
#
|
||||||
|
#app = QApplication([])
|
||||||
|
#
|
||||||
|
#class ExplorerWidget(QWidget):
|
||||||
|
#
|
||||||
|
# def __init__():
|
||||||
|
# print('wow')
|
||||||
|
#
|
||||||
|
##### Control Panel ####
|
||||||
|
#seedSelector = QTextEdit()
|
||||||
|
#ndroitesSelector = QDial()
|
||||||
|
#
|
||||||
|
#cPanel = QFormLayout()
|
||||||
|
#cPanel.addWidget(QLabel("Seed : "))
|
||||||
|
#cPanel.addWidget(seedSelector)
|
||||||
|
#cPanel.addWidget(QLabel("Nombre de droites :"))
|
||||||
|
#cPanel.addWidget(ndroitesSelector)
|
||||||
|
#
|
||||||
|
#globalL = QHBoxLayout()
|
||||||
|
#globalL.addStretch(1)
|
||||||
|
#globalL.addLayout(cPanel)
|
||||||
|
#
|
||||||
|
#window = QWidget()
|
||||||
|
#window.setLayout(globalL)
|
||||||
|
#window.show()
|
||||||
|
#
|
||||||
|
#app.exec_()
|
||||||
|
|
||||||
|
#
|
||||||
|
#(x0,x1,y0,y1) = (0,4,0,4)
|
||||||
|
#n = 100
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#x = np.linspace(x0,x1,n)
|
||||||
|
#y = np.linspace(y0,y1,n)
|
||||||
|
#x00 = int(x0)-1
|
||||||
|
#y00 = int(y0)-1
|
||||||
|
#x11 = int(x1)+1
|
||||||
|
#y11 = int(y1)+1
|
||||||
|
#gradient = np.exp(np.random.rand(x11-x00+1,y11-y00+1)*2*np.pi*1j)
|
||||||
|
#X,Y = np.meshgrid(x,y)
|
||||||
|
##print(gradient)
|
||||||
|
#
|
||||||
|
#def lerp(a0, a1, w):
|
||||||
|
# return a0 + (a1-a0)*(-2*w*w*w+3*w*w)
|
||||||
|
#
|
||||||
|
#def dotGridGradient(ix, iy, x, y):
|
||||||
|
# dx = x - ix
|
||||||
|
# dy = y - iy
|
||||||
|
# return (np.conj(gradient[iy-y00][ix-x00])*(dx+1j*dy)).real
|
||||||
|
#
|
||||||
|
#def bruit(x,y):
|
||||||
|
# (x0,y0) = (int(x),int(y))
|
||||||
|
# (x1,y1) = (x0+1,y0+1)
|
||||||
|
#
|
||||||
|
# sx = x - x0;
|
||||||
|
# sy = y - y0;
|
||||||
|
#
|
||||||
|
# n0 = dotGridGradient(x0, y0, x, y);
|
||||||
|
# n1 = dotGridGradient(x1, y0, x, y);
|
||||||
|
# ix0 = lerp(n0, n1, sx);
|
||||||
|
# n0 = dotGridGradient(x0, y1, x, y);
|
||||||
|
# n1 = dotGridGradient(x1, y1, x, y);
|
||||||
|
# ix1 = lerp(n0, n1, sx);
|
||||||
|
# return lerp(ix0, ix1, sy);
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#Z = np.zeros((n,n))
|
||||||
|
#for i in range(n):
|
||||||
|
# for j in range(n):
|
||||||
|
# Z[i,j] = bruit(x[i],y[j])
|
||||||
|
#
|
||||||
|
#pp.imshow(Z,cmap='autumn')
|
||||||
|
#
|
||||||
|
#fig = pp.figure()
|
||||||
|
#ax = pp.axes(projection='3d')
|
||||||
|
#
|
||||||
|
#ax.view_init(80, 42)
|
||||||
|
#ax.plot_surface(X,Y,Z, rstride=1, cstride=1,
|
||||||
|
# cmap='autumn', edgecolor='none')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
Python/recImage.png
Normal file
|
After Width: | Height: | Size: 229 KiB |
23
Python/sanstitre0.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Created on Thu Nov 21 11:49:30 2019
|
||||||
|
|
||||||
|
@author: savrillon
|
||||||
|
"""
|
||||||
|
|
||||||
|
from perlin import PerlinNoise
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
graine = 42
|
||||||
|
zoom=0.2
|
||||||
|
pos = np.random.randint(0,0xFFFFFFF,(2,))
|
||||||
|
taille=(100,100)
|
||||||
|
P = PerlinNoise(zoom,graine)
|
||||||
|
chunk = P.getChunk(pos[0],pos[1],taille)
|
||||||
|
|
||||||
|
chunk -= (chunk<0)*chunk
|
||||||
|
chunk *= 1000
|
||||||
|
chunk = chunk.astype(int)
|
||||||
|
|
||||||
|
print(chunk)
|
||||||
|
|
||||||
35
Python/testPerlin.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Created on Thu Aug 29 23:53:47 2019
|
||||||
|
|
||||||
|
@author: mysaa
|
||||||
|
"""
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as pp
|
||||||
|
import random as rnd
|
||||||
|
import perlin
|
||||||
|
|
||||||
|
|
||||||
|
N = 42
|
||||||
|
values = []
|
||||||
|
pp.xlabel('valeur')
|
||||||
|
pp.ylabel('compte')
|
||||||
|
pp.title('Valeur du bruit de perlin')
|
||||||
|
|
||||||
|
#tt = np.vectorize(lambda x : x//0.01)
|
||||||
|
|
||||||
|
noise = perlin.PerlinNoise(2.3,42)#,wrapper = lambda x : np.tanh(x*3.8622))
|
||||||
|
while True:
|
||||||
|
#print("\r{}".format(i), end='\r')
|
||||||
|
for _ in range(N):
|
||||||
|
chunk = noise.getChunk(rnd.randint(0,167342),rnd.randint(0,941132),(16,16))
|
||||||
|
values += np.reshape(chunk, (1,256))[0].tolist()
|
||||||
|
[n,X, V]=pp.hist(values,range=(-1,1),bins=201,log=True, color = '#2aff00',edgecolor = 'black')
|
||||||
|
pp.draw()
|
||||||
|
pp.pause(0.1)
|
||||||
|
|
||||||
|
#pp.figure()
|
||||||
|
#X = np.linspace(-1,1,2000)
|
||||||
|
#pp.plot(X,X)
|
||||||
14
Python/tmf.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Module contant les fonctions permettant de lire et écrire des fichiers dans le format TMF
|
||||||
|
|
||||||
|
@author: mysaa
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class WorldSaver():
|
||||||
|
|
||||||
|
def __init__():
|
||||||
|
regSize=0
|
||||||
BIN
Python/triImage.png
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
SonarDeLInfini.pdf
Normal file
91
SonarDeLInfini.tex
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
\documentclass[10pt,a4paper]{article}
|
||||||
|
|
||||||
|
\usepackage[margin=2.5cm]{geometry}
|
||||||
|
\usepackage[francais]{babel}
|
||||||
|
\usepackage{lmodern}
|
||||||
|
\usepackage[latin1]{inputenc}
|
||||||
|
\usepackage[T1]{fontenc}
|
||||||
|
\usepackage{amsmath}
|
||||||
|
\usepackage{amsfonts}
|
||||||
|
\usepackage{amssymb}
|
||||||
|
\usepackage{graphicx}
|
||||||
|
|
||||||
|
|
||||||
|
\author{Mysaa (Samy AVRILLON)}
|
||||||
|
\title{Le sonar de l'infini}
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
\maketitle
|
||||||
|
|
||||||
|
\tableofcontents
|
||||||
|
|
||||||
|
\newpage
|
||||||
|
|
||||||
|
|
||||||
|
\part{Problèmatique}
|
||||||
|
|
||||||
|
L'objectif de ce TIPE est de générer des fonds marins aléatoires, réalistes ou au moins 'utiles'. Les applications possibles seraient, par exemple
|
||||||
|
\begin{itemize}
|
||||||
|
\item La générations de photographies de synthèse de paysages aléatoires, dans le cinéma par exemple. Les paramètres seront ainsi déterminés de manière à créer les paysages les plus réaliste possible, ou modifiés pour servir un message artistique (par exemple, demander un sol plus imparfait).
|
||||||
|
|
||||||
|
\item De la génération procédurale dans des jeux vidéos. L'exemple le plus pertinent est le jeu vidéo \textit{Minecraft}, où le joueur évolue dans un monde généré aléatoirement grâce à une graine (\textit{seed} en anglais) de manière déterministe (deux mondes générés avec une même graine seront rigoureusement identiques). De plus, le moteur de génération est géré de manière à ce que l'on puisse lui demander de générer une zone 'loin' sans qu'il n'ait à générer toutes les zones à partir de l'origine. Enfin, la carte générée est potentiellement infinie (limité bien sur par la taille de stockage allouée aux entiers et aux flottants).
|
||||||
|
|
||||||
|
\item De la génération de fonds pour des tests en simulation d'IA de robot sous-marin (voir projet de Quentin SOUVIGNET) ou pour tester des simulations de tsunami.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
De ces possibles application, je tire un \og Cahier des charges \fg de mon générateur :
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item Laisser accès au plus de paramètres possible, pour une meilleure personnalisation.
|
||||||
|
|
||||||
|
\item Permettre une génération procédurale, déterministe et non liée à l'origine.
|
||||||
|
|
||||||
|
\item Limiter la complexité en temps du programme, éventuellement la complexité spatiale.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\part{Génération}
|
||||||
|
|
||||||
|
Je vais présenter dans cette partie les différents algorithmes implémentés, leurs applications possibles, leurs caractéristiques.
|
||||||
|
|
||||||
|
\section{Bruit de Perlin}
|
||||||
|
|
||||||
|
Il s'agit d'un bruit très flou (voir Figure \ref{perlinExample}). Il peut être utilisé pour la génération d'une carte grande échelle, indiquant les variations globales du terrain.
|
||||||
|
\begin{figure}[h]
|
||||||
|
\centering
|
||||||
|
\includegraphics[height = 8cm]{"perlin"}
|
||||||
|
\caption{Exemple de génération d'un bruit de Perlin sur une zone de 5x5}
|
||||||
|
\label{perlinExample}
|
||||||
|
\end{figure}
|
||||||
|
Je vais maintenant donner une description simplifiée de fonctionnement de l'algorithme : Il génère d'abord une carte de gradients 2D de norme unitaire de direction et sens aléatoires (vecteurs du cercle trigonométrique), positionnés en chaque noeud entier. Ensuite, il \og lance une nappe \fg qui va prendre une forme imposée par les gradients. L'algorithme met en jeu une fonction d'interpolation pour déterminer les valeurs hors des noeuds, ce qui peut être un paramètre sur lequel agir.
|
||||||
|
|
||||||
|
L'avantages de cet algorithme est sa rapidité et sa faible complexité spatiale.
|
||||||
|
|
||||||
|
\section{Bruit fractal}
|
||||||
|
|
||||||
|
Cet algorithme génère des droites de manière aléatoires, ce qui sépare pour chaque droite le plan en deux, et surélève l'un des deux cotés. Ce bruit est beaucoup plus \og granuleux \fg que le brut de perlin, et semble par conséquent plus réaliste. Le problème est que cette méthode est incompatible avec l'infinité de la map. On ne peux en effet pas charger l'infinité des droites du plan pour générer un carré (une célèbre équation annonce que $ \forall x \in \mathbb{R} \;,\; x < +\infty$). J'ai donc modifié l'algorithme en restreignant l'action des droites progressivement (grâce à une fonction d'interpolation, paramétrable elle aussi) Voir Figure \ref{fractExample} pour deux exemples avec plus ou moins de droites par region. L'inconvenient de cette methode est qu'elle devient vite coûteuse lorsque l'on augmente le nombre de droites.
|
||||||
|
|
||||||
|
\begin{figure}[h]
|
||||||
|
\centering
|
||||||
|
\includegraphics[height = 7cm]{"bfractal"}
|
||||||
|
\includegraphics[height = 7cm]{"hfractal"}
|
||||||
|
\caption{Bruit fractal avec peu à gauche et beaucoup à droite de droites par chunk}
|
||||||
|
\label{fractExample}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\part{Définition des paramètres et de presets}
|
||||||
|
|
||||||
|
A faire ...
|
||||||
|
|
||||||
|
\part{Ouverture}
|
||||||
|
|
||||||
|
Je vais ici lister différents extensions pouvant être apportées à l'étude, si le sujet devient complètement traité.
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item Créer un moteur de générations d'images des fonds marins générés précédemment, notamment avec la technique du ray-tracing.
|
||||||
|
\item Textures de l'eau aléatoires, des coraux aléatoires, avec une texture ayant l'air organique ...
|
||||||
|
\item Créer un moteur physique simplifié permettant à un joueur virtuel de se déplacer dans l'océan virtuel. Déterminer le meilleur rapport coût algorithmique/réalisme
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\end{document}
|
||||||
BIN
bfractal.png
Normal file
|
After Width: | Height: | Size: 331 KiB |
BIN
hfractal.png
Normal file
|
After Width: | Height: | Size: 345 KiB |
BIN
perlin.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
3173
tipe_tests.svg
Normal file
|
After Width: | Height: | Size: 224 KiB |
BIN
tipe_tests.svg.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |