You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
550 lines
14 KiB
550 lines
14 KiB
|
|
// -------------------- Fonctions des outils --------------------
|
|
|
|
|
|
// Permet d'afficher la valeur en "y" pour un point donné en "x"
|
|
function calculerPoint() {
|
|
x = document.getElementById("inputX").value;
|
|
document.getElementById("outputX").innerHTML = " f(x) = "+fct.list[editeur.idFct].f(x)+"";
|
|
//alert("Si x = "+x+" \nf(x) = "+eval(fonction)+"")
|
|
}
|
|
|
|
|
|
// Historique
|
|
|
|
var historique = {
|
|
liste : [],
|
|
|
|
actualiser : function(){
|
|
var texteHistorique = ""
|
|
for(var i=0; i<this.liste.length; i++){
|
|
texteHistorique += '<span class="survol" onclick="historique.use('+i+'); actualiserGraph()">';
|
|
texteHistorique += this.liste[i].readableText();
|
|
texteHistorique += '</span> <br/>';
|
|
}
|
|
document.getElementById("spanHistorique").innerHTML = texteHistorique
|
|
document.getElementById("divHistorique").scrollTop = 0
|
|
},
|
|
|
|
use : function(index){
|
|
fct.add(this.liste[index]);
|
|
},
|
|
|
|
ajouter : function(func){
|
|
if(func.fct == ""){
|
|
return;
|
|
}
|
|
for(var i=0; i<this.liste.length; i++){
|
|
if(this.liste[i].fct == func.fct){
|
|
this.liste.splice(i, 1);
|
|
}
|
|
}
|
|
var newFunction = fct.functionFromObject(func.get());
|
|
this.liste.unshift(newFunction);
|
|
this.actualiser();
|
|
saveOptions();
|
|
},
|
|
|
|
get: function(){
|
|
var list = [];
|
|
for(var i=0; i<this.liste.length; i++){
|
|
list.push(this.liste[i].get());
|
|
}
|
|
return list;
|
|
},
|
|
|
|
set: function(obj){
|
|
for(var i=0; i<obj.length; i++){
|
|
this.liste.push(fct.functionFromObject(obj[i]));
|
|
}
|
|
this.actualiser();
|
|
}
|
|
}
|
|
|
|
|
|
// Outils de la souris
|
|
|
|
var outil = {
|
|
//
|
|
idAffichage : "affichageOutils",
|
|
|
|
// Outil sélectionné
|
|
actuel : "point",
|
|
|
|
// Canvas
|
|
canvas : null,
|
|
ctx : null,
|
|
|
|
width: 0,
|
|
height: 0,
|
|
|
|
// Liste des éléments à dessiner
|
|
liste : [],
|
|
|
|
// Fonction d'initialisation
|
|
init : function(width, height){
|
|
var element = document.getElementById(this.idAffichage);
|
|
if(element.hasChildNodes()){
|
|
while(element.childNodes.length >= 1 ){
|
|
element.removeChild(element.firstChild);
|
|
}
|
|
}
|
|
|
|
this.width = width || element.clientWidth;
|
|
this.height = height || element.clientHeight;
|
|
|
|
// element.style.width = affichage.largeur +"px";
|
|
// element.style.height = affichage.hauteur +"px";
|
|
// element.style.left = document.getElementById(affichage.id).offsetLeft+1 +"px";
|
|
// element.style.top = document.getElementById(affichage.id).offsetTop+1 +"px";
|
|
|
|
this.canvas = document.createElement("canvas");
|
|
this.canvas.width = this.width;
|
|
this.canvas.height = this.height;
|
|
element.appendChild(this.canvas);
|
|
this.ctx = this.canvas.getContext('2d');
|
|
},
|
|
|
|
// Permet de changer d'outil et de faire différentes actions lors du choix de l'outil
|
|
choisir : function(nom){
|
|
document.getElementById("pointTool").className = "toolButton";
|
|
document.getElementById("moveTool").className = "toolButton";
|
|
document.getElementById("tangentTool").className = "toolButton";
|
|
switch(nom){
|
|
case 'point':
|
|
document.getElementById("pointTool").className += " selectedTool";
|
|
break;
|
|
case 'deplacement':
|
|
document.getElementById("moveTool").className += " selectedTool";
|
|
break;
|
|
case 'tangente':
|
|
document.getElementById("tangentTool").className += " selectedTool";
|
|
break;
|
|
}
|
|
if(nom == 'deplacement'){
|
|
document.getElementById("eventAffichage").style.cursor = "move";
|
|
}
|
|
else{
|
|
document.getElementById("eventAffichage").style.cursor = "auto";
|
|
}
|
|
this.dessinerListe();
|
|
this.actuel = nom;
|
|
saveOptions();
|
|
},
|
|
|
|
// Gestion des événements reçus de l'objet souris
|
|
move : function(x, y, xInit, yInit, active){
|
|
switch(this.actuel){
|
|
case "deplacement":
|
|
if(active){
|
|
this.deplacement(x, y, xInit, yInit);
|
|
}
|
|
break;
|
|
case "point":
|
|
this.point(x, y);
|
|
break;
|
|
case "tangente":
|
|
this.tangente(x, y);
|
|
break;
|
|
}
|
|
},
|
|
|
|
down : function(x, y){
|
|
switch(this.actuel){
|
|
case "point":
|
|
this.point(x, y, true)
|
|
break;
|
|
case "tangente":
|
|
this.tangente(x, y, true);
|
|
break;
|
|
}
|
|
},
|
|
|
|
// Fonctions des outils
|
|
deplacement : function(x, y, xInit, yInit){
|
|
var valeurX = (x-xInit)/affichage.multX;
|
|
var valeurY = (yInit-y)/affichage.multY;
|
|
if(Math.round(Math.abs(valeurX)) > 0){
|
|
if(fonction3D){
|
|
affichage.deplacerX(Math.round(2*valeurX)/2);
|
|
}
|
|
else{
|
|
affichage.deplacerX(-Math.round(2*valeurX)/2);
|
|
}
|
|
souris.xInit = x;
|
|
}
|
|
if(Math.round(Math.abs(valeurY)) > 0){
|
|
affichage.deplacerY(-Math.round(2*valeurY)/2);
|
|
souris.yInit = y;
|
|
}
|
|
},
|
|
|
|
point : function(sourisX, sourisY, ajouterDansListe){
|
|
var ctx = new Object();
|
|
ctx = this.ctx;
|
|
|
|
// Dessiner les points et tangentes supplémentaires
|
|
this.dessinerListe();
|
|
|
|
for(var i=0; i<fct.list.length; i++){
|
|
var func = fct.list[i];
|
|
if(!func || func == ""){
|
|
continue;
|
|
}
|
|
|
|
// Position de la souris par rapport au coin supérieur gauche de l'affichage
|
|
var posX = sourisX - affichage.offsetLeft - 2;
|
|
|
|
// Valeur de la coordonnée x et y sous la souris
|
|
var t = posX / affichage.multX + affichage.xGauche;
|
|
if("startAngle" in func){
|
|
if(t < func.startAngle || t > func.endAngle){
|
|
continue;
|
|
}
|
|
}
|
|
var x = func.getX(t);
|
|
var y = func.getY(t);
|
|
|
|
// Afficher les coordonnées et le point sous la souris
|
|
if(!isNaN(x) && !isNaN(y)){
|
|
if(ajouterDansListe){
|
|
this.ajouterPoint(x, y, func.couleur);
|
|
}
|
|
this.dessinerPoint(x, y, func.couleur);
|
|
}
|
|
}
|
|
},
|
|
dessinerPoint : function(x, y, couleur){
|
|
var ctx = new Object();
|
|
ctx = this.ctx;
|
|
|
|
// Conversion des coordonnées
|
|
var posX = coordToPosX(x) + 1;
|
|
var posY = coordToPosY(y) + 1;
|
|
|
|
ctx.shadowColor = couleur;
|
|
ctx.shadowBlur = 4;
|
|
|
|
// Texte
|
|
var txtPos = "("+Math.round(x*100)/100+";"+Math.round(y*100)/100+")";
|
|
ctx.fillStyle = "rgba(255,255,255,0.5)";
|
|
try{
|
|
ctx.bulle(posX+7, posY-7, txtPos.length*5.5, 20);
|
|
}
|
|
catch(err){
|
|
ctx.fillRect(posX+7, posY-27, txtPos.length*5.5, 20);
|
|
}
|
|
|
|
ctx.fillStyle = "black";
|
|
ctx.shadowColor = "black";
|
|
ctx.shadowOffsetX = 1;
|
|
ctx.shadowOffsetY = 1;
|
|
ctx.shadowBlur = 2;
|
|
ctx.fillText(txtPos, posX+8+txtPos.length/4, posY-13);
|
|
|
|
// Rond
|
|
ctx.beginPath();
|
|
ctx.arc(posX, posY, 4, 0, 2*Math.PI, true);
|
|
|
|
ctx.shadowColor = couleur;
|
|
ctx.shadowOffsetX = 0;
|
|
ctx.shadowOffsetY = 0;
|
|
ctx.shadowBlur = 4;
|
|
|
|
ctx.fillStyle = "rgba(0,0,0,1)";
|
|
ctx.strokeStyle = "rgba(255,255,255,0.8)";
|
|
ctx.lineWidth = 1;
|
|
ctx.fill()
|
|
ctx.stroke();
|
|
},
|
|
|
|
tangente : function(sourisX, sourisY, ajouterDansListe){
|
|
var delta = 0.001;
|
|
|
|
var ctx = new Object();
|
|
ctx = this.ctx;
|
|
|
|
// Dessiner les points et tangentes supplémentaires
|
|
this.dessinerListe();
|
|
|
|
// Dessiner les tangentes des fonctions
|
|
for(var i=0; i<fct.list.length; i++){
|
|
var func = fct.list[i];
|
|
// Vérifier la fonction sur laquelle doit s'appliquer l'outil
|
|
if(!func || func == ""){
|
|
continue;
|
|
}
|
|
|
|
// Position de la souris par rapport au coin supérieur gauche de l'affichage
|
|
var posX = sourisX - affichage.offsetLeft - 2;
|
|
|
|
// Valeur de la coordonnée x sous la souris
|
|
var t = posX / affichage.multX + affichage.xGauche;
|
|
if("startAngle" in func){
|
|
if(t < func.startAngle || t > func.endAngle){
|
|
continue;
|
|
}
|
|
}
|
|
var t1 = t + delta;
|
|
var x = func.getX(t);
|
|
var x1 = func.getX(t1);
|
|
// Calcul de deux valeurs y et de la pente
|
|
var y = func.getY(t);
|
|
var y1 = func.getY(t1);
|
|
var pente;
|
|
if(x1 != x){
|
|
pente = (y1-y)/(x1-x);
|
|
}
|
|
else{
|
|
pente = Number.POSITIVE_INFINITY;
|
|
}
|
|
|
|
// Dessiner la pente;
|
|
if(!isNaN(x) && !isNaN(y) && !isNaN(y1)){
|
|
if(ajouterDansListe){
|
|
this.ajouterTangente(x, y, pente, func.couleur);
|
|
}
|
|
this.dessinerTangente(x, y, pente, func.couleur);
|
|
}
|
|
}
|
|
},
|
|
dessinerTangente : function(x, y, pente, couleur){
|
|
var ctx = new Object();
|
|
ctx = this.ctx;
|
|
|
|
// Conversion des coordonnées
|
|
var posX = coordToPosX(x) + 1;
|
|
var posY = coordToPosY(y) + 1;
|
|
|
|
// Carré
|
|
ctx.shadowColor = couleur;
|
|
ctx.shadowBlur = 4;
|
|
|
|
ctx.fillStyle = "white";
|
|
ctx.fillRect(posX-3, posY-3, 6, 6);
|
|
|
|
// Pente
|
|
ctx.strokeStyle = "white";
|
|
ctx.lineWidth = 2;
|
|
ctx.beginPath();
|
|
var pente2 = pente * (affichage.hauteur/affichage.largeur) * (affichage.xDroite-affichage.xGauche)/(affichage.yHaut-affichage.yBas);
|
|
ctx.moveTo(0, posY+posX*pente2);
|
|
ctx.lineTo(affichage.largeur, posY+posX*pente2-affichage.largeur*pente2);
|
|
ctx.stroke();
|
|
|
|
// Texte
|
|
var txtPente;
|
|
if(isFinite(pente)){
|
|
txtPente = pente.toFixed(2);
|
|
}
|
|
else{
|
|
txtPente = "∞"
|
|
}
|
|
ctx.fillStyle = "rgba(255,255,255,0.5)";
|
|
try{
|
|
ctx.bulle(posX+7, posY-7, txtPente.length*5.5+1, 20);
|
|
}
|
|
catch(err){
|
|
ctx.fillRect(posX+7, posY-27, txtPente.length*5.5, 20);
|
|
}
|
|
|
|
ctx.fillStyle = "black";
|
|
ctx.shadowColor = "black";
|
|
ctx.shadowOffsetX = 1;
|
|
ctx.shadowOffsetY = 1;
|
|
ctx.shadowBlur = 2;
|
|
ctx.fillText(txtPente, posX+8+txtPente.length/4, posY-13);
|
|
},
|
|
|
|
ajouterPoint : function(x, y, couleur){
|
|
var newPoint = {
|
|
x : x,
|
|
y : y,
|
|
couleur : couleur,
|
|
dessiner : function(){
|
|
outil.dessinerPoint(this.x, this.y, this.couleur);
|
|
}
|
|
};
|
|
this.liste.push(newPoint);
|
|
},
|
|
ajouterTangente : function(x, y, pente, couleur){
|
|
var newTangente = {
|
|
x : x,
|
|
y : y,
|
|
pente : pente,
|
|
couleur : couleur,
|
|
dessiner : function(){
|
|
outil.dessinerTangente(this.x, this.y, this.pente, this.couleur);
|
|
}
|
|
};
|
|
this.liste.push(newTangente);
|
|
},
|
|
dessinerListe : function(){
|
|
if(!this.ctx){
|
|
return;
|
|
}
|
|
this.ctx.clearRect(0,0,affichage.largeur*2,affichage.hauteur*2);
|
|
for(var i=0; i<this.liste.length; i++){
|
|
this.liste[i].dessiner();
|
|
}
|
|
this.actualiserListe();
|
|
},
|
|
actualiserListe : function(){
|
|
var element = document.getElementById("divSuppOutil");
|
|
element.innerHTML = "";
|
|
|
|
for(var i=0; i<this.liste.length; i++){
|
|
var posX = Math.floor(coordToPosX(this.liste[i].x, true)+9);
|
|
var posY = Math.floor(coordToPosY(this.liste[i].y, true)-28);
|
|
if(posX > affichage.largeur+affichage.offsetLeft || posX < affichage.offsetLeft || posY > affichage.hauteur+affichage.offsetTop || posX < affichage.offsetTop){
|
|
continue;
|
|
}
|
|
var txt = '<div style="left:'
|
|
txt += posX +'px;';
|
|
txt += 'top:'
|
|
txt += posY +'px;" ';
|
|
txt += 'onclick="'
|
|
txt += 'outil.supprimer('+i+')';
|
|
txt += '">x</div>';
|
|
// alert(txt);
|
|
element.innerHTML += txt;
|
|
}
|
|
},
|
|
supprimer : function(id){
|
|
outil.liste.splice(id, 1);
|
|
outil.dessinerListe();
|
|
// alert(id)
|
|
}
|
|
};
|
|
|
|
// Evènements du clavier
|
|
function keyPress(event){
|
|
switch(event.keyCode){
|
|
case 27:
|
|
// widget.resetState()
|
|
break
|
|
case 37:
|
|
if(event.ctrlKey){
|
|
affichage.deplacerX(-1)
|
|
}
|
|
break
|
|
case 38:
|
|
if(event.ctrlKey){
|
|
affichage.deplacerY(1)
|
|
}
|
|
break
|
|
case 39:
|
|
if(event.ctrlKey){
|
|
affichage.deplacerX(1)
|
|
}
|
|
break
|
|
case 40:
|
|
if(event.ctrlKey){
|
|
affichage.deplacerY(-1)
|
|
}
|
|
break
|
|
default:
|
|
//alert(event.keyCode+" ; "+event.ctrlKey)
|
|
}
|
|
}
|
|
|
|
|
|
// ---- Aire sous la fonction (intégrale) ----
|
|
function AireSousFct(fct, a, b, n){
|
|
var aire, largeurRect, gaucheRect, droiteRect, millieuRect, hauteurRect, aireRect;
|
|
var f = new Function("x", "return "+fct);
|
|
aire = 0;
|
|
largeurRect = (b-a)/n;
|
|
for(var i=0; i<n; i++){
|
|
gaucheRect = a + i*largeurRect;
|
|
droiteRect = a + (i+1)*largeurRect;
|
|
millieuRect = (gaucheRect+droiteRect) / 2;
|
|
hauteurRect = f(millieuRect);
|
|
aireRect = largeurRect * hauteurRect;
|
|
aire = aire + aireRect;
|
|
}
|
|
//alert("a="+a+";b="+b+";n="+n+";A="+aire)
|
|
return aire;
|
|
}
|
|
|
|
function calculerAire(){
|
|
var fonction = fct.remplacer(fct.verifier(fct.list[editeur.idFct].fct));
|
|
var a = parseInt(document.getElementById("aireG").value);
|
|
var b = parseInt(document.getElementById("aireD").value);
|
|
var n = 50;
|
|
var arrondi = Math.round(AireSousFct(fonction, a, b, n)*1000)/1000;
|
|
document.getElementById("outputAire").innerHTML = "A = " + arrondi;
|
|
actualiserGraph();
|
|
}
|
|
|
|
// ---- Sauvegarde du graphique ----
|
|
var backgroundSauvegarde = "rgba(0,0,0,0.5)";
|
|
|
|
function saveGraph(){
|
|
var userWidth = parseInt(document.getElementById("saveWidth").value);
|
|
var userHeight = parseInt(document.getElementById("saveHeight").value);
|
|
if(userWidth <= 0 || userHeight <= 0){
|
|
userWidth = affichage.width;
|
|
userHeight = affichage.height;
|
|
}
|
|
if(fonction3D){
|
|
var background = display3D.background;
|
|
display3D.background = backgroundSauvegarde;
|
|
|
|
display3D.init(userWidth, userHeight);
|
|
display3D.draw();
|
|
|
|
var dataURL;
|
|
if(document.getElementById("selectSaveType").value == "jpg"){
|
|
dataURL = display3D.canvas.toDataURL("image/jpeg");
|
|
}
|
|
else{
|
|
dataURL = display3D.canvas.toDataURL();
|
|
}
|
|
document.getElementById("saveImageContent").innerHTML = '<img src="' + dataURL + '"/>';
|
|
afficherMenu('menuSaveImage');
|
|
|
|
display3D.background = background;
|
|
setTimeout(function(){
|
|
display3D.init();
|
|
display3D.draw();
|
|
}, 1);
|
|
}
|
|
else{
|
|
if(affichage.methode == "canvas"){
|
|
var l = affichage.largeur;
|
|
var h = affichage.hauteur;
|
|
var c = affichage.couleurFond;
|
|
|
|
affichage.largeur = parseInt(document.getElementById("saveWidth").value);
|
|
affichage.hauteur = parseInt(document.getElementById("saveHeight").value);
|
|
affichage.couleurFond = backgroundSauvegarde;
|
|
|
|
var newDiv = document.createElement("div");
|
|
affichage.init(newDiv, userWidth, userHeight);
|
|
|
|
outil.init();
|
|
outil.dessinerListe();
|
|
affichage.ctx.drawImage(outil.canvas,0,0);
|
|
|
|
var dataURL;
|
|
if(document.getElementById("selectSaveType").value == "jpg"){
|
|
dataURL = affichage.canvas.toDataURL("image/jpeg");
|
|
}
|
|
else{
|
|
dataURL = affichage.canvas.toDataURL();
|
|
}
|
|
document.getElementById("saveImageContent").innerHTML = '<img src="' + dataURL + '"/>';
|
|
afficherMenu('menuSaveImage');
|
|
|
|
affichage.largeur = l;
|
|
affichage.hauteur = h;
|
|
affichage.couleurFond = c;
|
|
affichage.init();
|
|
outil.init();
|
|
}
|
|
else if(affichage.methode == "svg"){
|
|
window.open("JavaScript/AffichageSVG.svg");
|
|
}
|
|
}
|
|
}
|
|
|