07-04-2009, 08:37 PM
(Modification du message : 07-04-2009, 08:52 PM par jo_link_noir.)
Bonjour,
J'ai refait le code pour qu'il puisse s'utiliser avec n'importe quel taille d'image, de colonne et de ligne.
Y ajuste n, x, y, et L qui sont à modifier (l.126) et peut-être un décalage à effectué (l.195)
Par contre y a un petit décalage quand le tableau est trop, il ne trouve pas les coordonnées exacte. J'ai juste réajusté de quelques pixels mais faudrait le faire selon les valeurs en x et y, petit calcul que j'ai pas fait.
J'ai refait le code pour qu'il puisse s'utiliser avec n'importe quel taille d'image, de colonne et de ligne.
Y ajuste n, x, y, et L qui sont à modifier (l.126) et peut-être un décalage à effectué (l.195)
Par contre y a un petit décalage quand le tableau est trop, il ne trouve pas les coordonnées exacte. J'ai juste réajusté de quelques pixels mais faudrait le faire selon les valeurs en x et y, petit calcul que j'ai pas fait.
Code PHP :
<?php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<head>
<title>carte hexagone</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta lang="fr" name="description" content="trouver les coordonnées x/y avec la sourie sur une carte isométrique hexagonale" />
</head>
<body>
<div id="carte" style="z-index:1;"></div>
<div stle="position:fixed;z-index:90;">
<div>X/Y réel: <span id="reel">? / ?</span></div>
<div>X/Y modifier: <span id="modifier">? / ?</span></div>
<div>X/Y contre iso: <span id="contreiso">? / ?</span></div>
<div>Carte: <span id="info">-</span></div>
</div>
<div style="position:fixed;right:0px;top:0px;z-index:100;">
<form onsubmit="return initCarte(this)">
<p>
<label for="ligne">Ligne : </label><input type="numeric" name="ligne" id="ligne"/><br />
<label for="colonne">Colonne : </label><input type="numeric" name="colonne" id="colonne"/>
</p>
<p><input type="submit" /></p>
</div>
<script type="text/javascript"><!--
function sindeg(deg)
{
return Math.sin(deg/180*Math.PI);
}
function angleRad(x,y)
{
return Math.acos(x / Math.sqrt(x*x + y*y)) - Math.PI/4;
}
function modulo(x,y)
{
return Math.sqrt(x*x + y*y);
}
function y_non_iso(x,y)
{
return Math.floor(Math.sin(angleRad(x,y))*modulo(x,y));
}
function x_non_iso(x,y)
{
return Math.floor(Math.cos(angleRad(x,y))*modulo(x,y));
}
n = 98;
nbLignes = 3;
nbColonnes = 4;
function creeCarte()
{
var carte = '';
for (var l=0; l<nbLignes; l++) {
for (var c=0; c<nbColonnes; c++) {
var X = c*(sindeg(75)+sindeg(45))*n - (l+Math.ceil(c/2))*(sindeg(15) + sindeg(75))*n + (nbLignes-1)*(sindeg(15)+sindeg(75))*n;
var Y = (l+Math.ceil(c/2))*(sindeg(75)+sindeg(15))*n/2 + c*sindeg(13.5)*n;
carte += '<img src="../images/Hexagone_iso.png" style="position:absolute;left:'+X+'px;top:'+(Y-1)+'px;"/><span style="position:absolute;left:'+(X+85)+'px;top:'+(Y+40)+'px;">'+c+" / "+l+'</span>';
}
}
document.getElementById("carte").innerHTML = carte;
}
function initCarte(frm)
{
nbLignes = parseInt(frm.elements["ligne"].value);
nbColonnes = parseInt(frm.elements["colonne"].value);
creeCarte();
return false;
}
creeCarte();
// Variables de la gestion de l'evenement
var Mouse = {"x":0,"y":0};
// Demande de gestion de l'evenement à NetScape
if(navigator.appName.substring(0,3) == "Net") {
document.captureEvents(Event.MOUSEMOVE);
}
// Gestion de l'evenement
var OnMouseMoveEventHandler=function() {}
var OnMouseMove = function (e)
{
Mouse.x = (navigator.appName.substring(0,3) == "Net") ? e.pageX : event.x+document.body.scrollLeft;
Mouse.y = (navigator.appName.substring(0,3) == "Net") ? e.pageY : event.y+document.body.scrollTop;
if (Mouse.x < 0) {Mouse.x=0;}
if (Mouse.y < 0) {Mouse.y=0;}
OnMouseMoveEventHandler(e)
}
try {
document.attachEvent("onmousemove", OnMouseMove, true);
} catch (ex) {
document.addEventListener("mousemove", OnMouseMove, true);
}
/*
A partirdu tuto de Harparine
http://wiki.jeuweb.org/tutoprog/3d_iso_et_tuiles_hexagonales
*/
var moveHandler = function()
{
var c= nbColonnes-1, l = nbLignes-1;
//Fonctionne pour les hexagones avec des trait perpendiculaire à l'axe y
//n = taille d'un segment
//x = position x de la case 1/0 = 150 (n*1.5)
//le même que dans le php (148)
//y = position y de la case 0/0 = 86.5 (sin(60) * n)
//L = (largeurImage - tailleSegmentX) / 2 |OU| 2n-x = 50
//c'est valeur sont à réajuster car les images peuvent ce superposer lors de leurs positionnement
var n=98, x=150, y=86.5, L=50;
var X,Y,Xd,Yd;
document.getElementById("reel").innerHTML = Mouse.x+" / "+Mouse.y;
//on s'immule une contre isométrie des points
//les 2 calcules trouve les coordonnées du point d'origine (Xo=346 et Yo=204)
/*graphiquement
Xo = (Xmax+Xmin)/2
Yo = (Ymax+Ymin)/2
*/
/*Par calcul avec : c = nombreColonne -1 et l = nombreLigne - 1.
Xo = ceil(
(
n * (
c * (sin(75) + sin(45))
- ceil(c/2) * (sin(15) + sin(75))
+ l * (sin(15) + sin(75))
)
+ largeurImage
) / 2
- décalageX
)
Yo = ceil(
n * (
(l + ceil(c/2)) * (sin(75) + sin(15)) / 2
+ c * sin(13.5)
+ 1
) / 2
- décalageY
)
*/
var Xo = Math.ceil((n * (c * (sindeg(75) + sindeg(45)) - Math.ceil(c/2) * (sindeg(15) + sindeg(75)) + l * (sindeg(15) + sindeg(75))) + n+2*L) / 2);
var Yo = Math.ceil(n * ((l+Math.ceil(c/2))*(sindeg(75)+sindeg(15)) / 2 + c*sindeg(13.5) + 1) / 2);
Mouse.x += Xo;
Mouse.y = (Mouse.y + Yo)*2;
var x_contre_iso = x_non_iso(Mouse.x, Mouse.y);
var y_contre_iso = y_non_iso(Mouse.x, Mouse.y);
//on réajuste les points pour que la carte isométrique et son point d'origine soit positionner sur celui d'une carte non isométrique (faut imaginer la carte non iso et iso positionner l'un sur l'autre mais avec le point haut-gauche du carrer qui les contient confondu... ><)
//trouver en comparant le même point sur les 2 cartes avec le curseur
/*graphiquement /!\ prendre le resultat de la sourie suivant :
document.getElementById("modifier").innerHTML = Math.floor(sindeg(angle)*module)+" / "+Math.floor(Math.cos(angle)*module);
Par position de sourie nettement plus rapide/pratique même si il peut y avoir quelques pixel de différence. Dans ce cas il suffi de savoir dans quel axe et donc ajouter à x et y le nombre en conséquence
Mouse.y = Math.floor(Math.cos(angle)*module) - sommet_le_plus_haut (ou point extreme droite de l'axe x /!\ à l'isométrie)
Mouse.x = Math.floor(Math.cos(angle)*module) - sommet_à_droite_du_plus_haut (ou point extreme gauche de l'axe y /!\ à l'isométrie)
*/
/*Par calcul. Math.floor(sindeg(Mangle)*Mmodule) et Math.floor(Math.cos(Mangle)*Mmodule) sont par raport au nombre de ligne et de colonne. Pas le peine de faire le calcule à chaque fois
Mx = n * (sindeg(15/180*Math.PI)+sindeg(75/180*Math.PI)) * (l + 1) + Xo;
My = Yo * 2 ;
Mangle = Math.acos(Mx / Math.sqrt(Mx*Mx + My*My)) - Math.PI/4;
Mmodule = Math.sqrt(Mx*Mx + My*My) - 10;
Mouse.y = Math.floor(sindeg(angle)*module) - Math.floor(sindeg(Mangle)*Mmodule);
Mx = n * (sindeg(15/180*Math.PI) + l * (sindeg(15/180*Math.PI)+sindeg(75/180*Math.PI))) + Xo;
My = (n * sindeg(15/180*Math.PI)/2 + 1 + Yo) * 2 ;
Mangle = Math.acos(Mx / Math.sqrt(Mx*Mx + My*My)) - Math.PI/4;
Mmodule = Math.sqrt(Mx*Mx + My*My);
Mouse.x = Math.floor(Math.cos(angle)*module) - Math.floor(Math.cos(Mangle)*Mmodule);
*/
document.getElementById("modifier").innerHTML = x_contre_iso+" / "+y_contre_iso;
Mouse.y = y_contre_iso - y_non_iso(n * (sindeg(15)+sindeg(75)) * (l + 1) + Xo, Yo * 2);
Mouse.x = x_contre_iso - x_non_iso(n * (sindeg(15) + l * (sindeg(15)+sindeg(75))) + Xo, (n * sindeg(15)/2 + 1 + Yo) * 2);
//décalage
Mouse.y += 2;
Mouse.x -= 1;
document.getElementById("contreiso").innerHTML = Math.floor(Mouse.x)+" / "+Math.floor(Mouse.y);
//calcule les positions aproximatif de la case (X ; Y)
//hexagone transformer en carré de même hauteur et de largeur du point le plus à gauche au point en haut à droite
//---------------------------------------------------------
//calcule les positions réel de la case (Xd ; Yd)
//distance du point par rapport à l'haxagone
X = Math.floor(Mouse.x/x);
Xd= n - (Mouse.x - X*x);
if(X%2 == 1)
{
Y = Math.floor((Mouse.y - y)/(y*2));
Yd= Mouse.y - Y*(y*2) - (y*2);
}
else
{
Y = Math.floor(Mouse.y/(y*2));
Yd= Mouse.y - Y*(y*2) - y;
}
//le point est situer dans la partie du carré qui superpose l'hexagone (à ça gauche)
//et le point est à l'exterieur du cercle inscrit
//et on déplace le point sur l'axe x et on vérifie ça longueur (52/86.5 est la pente de x par y)
if(Xd >= L
&& y < Math.sqrt(Xd*Xd + Yd*Yd)
&& n <= Xd + Math.abs(Yd)*L/y)
{
if(X%2 == 1 && Yd>0) ++Y;
if(X%2 == 0 && Yd<0) --Y;
--X;
}
//curseur à l'exterieur de la carte
document.getElementById("info").innerHTML = X+" / "+Y+ ": "+(Y<3 && X<4 && Y>=0 && X>=0 ? "OUI" : "NON");
};
document.onmousemove = moveHandler;
--></script>
</body>
</html>