Graficando Vectores con GD+PHP (2da parte)
Después de tanto hacerme pato con mi proyecto de física, lo he terminado. Aunque, no literalmente, faltaron muchos detalles. No sabía que tuviera que presentarlo tan pronto, así que tuve que realizar alguna que otra acrobacia, llenando de parches aquí y allá la aplicación… y con eso de que no tengo buenas prácticas pues quedó un chilaquil ahí dos tres funcional...
Agradezco sus comentarios. De antemano, muchas gracias!
A la aplicación solo se le da dos vectores, se elige forma en que el vector se introducirá, o sea modulo-ángulo, o simplemente por coordenadas y luego de esto darle en el botón intentar.
El formulario es un asco, lo hice exactamente dos horas antes de la presentación en público, jeje. Así que no acepto muchas críticas en esta parte jeje… En el código de la aplicación pues, valla que si duré bastante trabajando (Como cuatro sesiones creo).
Les dejo el código para que critiquen, y de igual forma la versión de demostración para apreciar bien el detalle final :D
- El formulario para ingreso de datos.
El archivo que genera el plano cartesiano y tira los vectores.
- header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
- header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
- header('Content-type: image/png');
- //header("content-type: text/html");
- #Lax X son pares
- #Las Y son impares
- if(isset($_GET['V']))
- $V = $_GET['V'];
- if(!isset($_GET['angulo']) and !isset($_GET['modulo']) and !isset($_GET['V'])){
- $V[]=0;
- $V[]=0;
- }
- if(isset($_GET['modulo']) and isset($_GET['angulo']))//Si hay un angulo o módulo
- if(count($_GET['modulo'])!=count($_GET['angulo']))//deben coincidir en cantidad
- exit;//si no, termina la ejecución de la aplicación.
- //Evaluamos los vectores cuando estos vienen en la forma modulo angulo.
- if(isset($_GET['angulo']) and isset($_GET['modulo']))
- foreach($_GET['angulo'] as $k => $teta)
- if(!empty($teta)||!empty($_GET['modulo'][$k])){
- $V[]= sprintf("%.1f",$_GET['modulo'][$k]*cos(deg2rad($teta)));//x
- $V[]= sprintf("%.1f",$_GET['modulo'][$k]*sin(deg2rad($teta)));//y
- }
- /* Evaluamos la resultante */
- if(isset($_GET['operacion']) and $_GET['operacion']=="sumar"){
- $resultante_x=0;
- $resultante_y=0;
- foreach($V as $k => $v){
- if($k%2==0)
- $resultante_x += $v;
- if($k%2!=0)
- $resultante_y += $v;
- }
- $V[]=$resultante_x;
- $V[]=$resultante_y;
- }
- if(isset($_GET['operacion']) and $_GET['operacion']=="multiplicar"){
- if(count($V)>=2 and isset($_GET['valor']) and is_numeric($_GET['valor'])){
- $resultante_x=$V[0]*$_GET['valor'];
- $resultante_y=$V[1]*$_GET['valor'];
- $V[]=$resultante_x;
- $V[]=$resultante_y;
- }
- }
- //Agregamos un nuevo vector, que es la resultante.
- //Valores por default
- $ancho = 500;//Anchura de la imagen en pixeles
- $alto = 500;//Altura de la imagen en pixeles
- $d = 20;//Desplazamiento para el marco
- $cuadros_min = 5;//Cantidad mÃnima de cuadros permitiada.
- $ttf=1;//Tipo de fuente
- //Cantidad de cuadros por cada lado del plano cartesiano.
- $mayor_x = 0;
- $mayor_xn = 0;
- $mayor_y = 0;
- $mayor_yn = 0;
- //Obtenemos los valores de los extremos de cada lado del plano
- foreach($V as $k => $v){
- //Las X
- if($k%2==0){
- if($v>0 and $v>$mayor_x)
- $mayor_x = $v;
- if($v<0 and $v< $mayor_xn)
- $mayor_xn = $v;
- }
- //Las Y
- if($k%2!=0){
- if($v>0 and $v>$mayor_y)
- $mayor_y = $v;
- if($v<0 and $v< $mayor_yn)
- $mayor_yn = $v;
- }
- }
- $mayor_xn = abs($mayor_xn);//Mayor en X negativo
- $mayor_yn = abs($mayor_yn);//Mayor en Y negativo
- $img = imagecreatetruecolor($ancho,$alto);
- $img_ucol= imagecreatefromgif("aguila.gif");
- //Colores
- $blanco = imagecolorallocate($img,0xff,0xff,0xff);
- $negro = imagecolorallocate($img,0x0,0x0,0x0);
- //$gris = imagecolorallocate($img,0xe7,0xe7,0xe7);
- $gris = imagecolorallocate($img,0xdf,0xdf,0xdf);
- $rojo = imagecolorallocate($img,0xff,0x00,0x00);
- $dark_gray = imagecolorallocate($img,0xc5,0xc5,0xc5);
- //Creamos fondo de color blanco
- imagefilledrectangle($img,0,0,$ancho-1, $alto-1, $blanco);
- imagestring($img,2,$ancho-52,i(100),"Matus",$dark_gray);
- imagestring($img,2,$ancho-52,i(90),"Noemi",$dark_gray);
- imagestring($img,2,$ancho-70,i(80),"Renteria",$dark_gray);
- imagestring($img,2,$ancho-65,i(70),"Antonio",$dark_gray);
- imagestring($img,2,$ancho-64,i(60),"Roberto",$dark_gray);
- imagestring($img,2,$ancho-76,i(50),"Alexander",$dark_gray);
- imagestring($img,2,$ancho-60,i(40),"Victor",$dark_gray);
- //Si la orientación del mayor es en X (ox=true), tomamos comom referencia el ancho, si no, lo alto.
- if(($mayor_x+$mayor_xn)>($mayor_y+$mayor_yn))
- $ox = true;
- else
- $ox = false;
- if($ox){//Orientación en X
- $cuadros = $mayor_x+$mayor_xn;//Cantidad de cuadros
- if($cuadros != 0)
- if($cuadros > $cuadros_min)
- $cuadro_w = ($ancho-($d*2))/$cuadros;//Dimensiones por cuadro
- else
- $cuadro_w = ($ancho-$d*2)/$cuadros_min;
- else//Si solo hubiese un punto y en la coordenada 0,0 ocurrirÃa un error de tipo "división by zero".
- $cuadro_w = ($ancho-$d)/$cuadros_min;
- }else{
- $cuadros = $mayor_y+$mayor_yn;//Cantidad de cuadros
- if($cuadros != 0)
- if($cuadros > $cuadros_min)
- $cuadro_w = ($alto-($d*2))/$cuadros;//Dimensiones por cuadro
- else
- $cuadro_w = ($alto-$d*2)/$cuadros_min;
- else//Si solo hubiese un punto y en la coordenada 0,0 ocurrirÃa un error de tipo "división by zero".
- $cuadro_w = ($alto-$d)/$cuadros_min;
- }
- $cuadro_w = floor($cuadro_w); //Entre más pequeño mejor.
- //LÃneas verticales
- for($x=0;$x< $ancho;$x++)
- if($x%$cuadro_w==0)
- imageline($img,/*x1,y1*/$x+$d,i($alto),/*x2,y2*/$x+$d,i(1+$d),$gris);
- //LÃneas horizontales
- for($y=0;$y<$alto;$y++)
- if($y%$cuadro_w==0)
- imageline($img,/*x1,y1*/1+$d,i($y+$d),/*x2,y2*/$ancho,i($y+$d),$gris);
- //GuÃas horizontales
- for($x=($mayor_xn*$cuadro_w*-1);$x<$ancho;$x++)
- if($x%$cuadro_w==0)
- imageline($img,/*x1,y1*/$x+$d,i(0+($mayor_yn*$cuadro_w)-2+$d),/*x2,y2*/$x+$d,i(2+($mayor_yn*$cuadro_w)+$d),$negro);
- //GuÃas verticales
- for($y=($mayor_yn*$cuadro_w*-1);$y<$alto;$y++)
- if($y%$cuadro_w==0)
- imageline($img,/*x1,y1*/0+($mayor_xn*$cuadro_w)-2+$d,i($y+$d),/*x2,y2*/2+($mayor_xn*$cuadro_w)+$d,i($y+$d),$negro);
- //Se dibuja Plano cartesiano
- //Eje de Y
- imageline($img,/*x1,y1*/0+($mayor_xn*$cuadro_w)+$d,i(0+$d),/*x2,y2*/0+($mayor_xn*$cuadro_w)+$d,i($alto),$negro);
- //Eje de X
- imageline($img,/*x1,y1*/0+$d,i(0+$d)-($mayor_yn*$cuadro_w),/*x2,y2*/$ancho,i(0+$d)-($mayor_yn*$cuadro_w),$negro);
- //Cuadro de relleno para tapar Abajo e Izquierda.
- imagefilledrectangle($img,0,0,$d,$alto,$blanco);//izquierda
- imagefilledrectangle($img,0,$alto-$d,$ancho,$alto,$blanco);//abajo
- //Numeración vertical
- for($x=($mayor_xn*$cuadro_w*-1);$x<$ancho;$x++)
- if($x%$cuadro_w==0)
- if(floor($x/$cuadro_w)>=0)
- imagestring($img,$ttf,$x+($mayor_xn*$cuadro_w)-imagefontwidth($ttf)*strlen(floor($x/$cuadro_w))+$d,i(($mayor_yn*$cuadro_w)-1+$d),floor($x/$cuadro_w),$negro);
- else
- imagestring($img,$ttf,$x+($mayor_xn*$cuadro_w)-2+$d,i(($mayor_yn*$cuadro_w)-1+$d),floor($x/$cuadro_w),$negro);
- //Numeración horizontal
- for($y=($mayor_yn*$cuadro_w*-1);$y< $alto;$y++)
- if($y%$cuadro_w==0)
- if(floor($y/$cuadro_w)>0)
- imagestring($img,$ttf,($mayor_xn*$cuadro_w)+$d-imagefontwidth($ttf)*strlen(floor($y/$cuadro_w)),i($y+$d)-($mayor_yn*$cuadro_w)+1,floor($y/$cuadro_w),$negro);
- elseif(floor($y/$cuadro_w)<0)
- imagestring($img,$ttf,($mayor_xn*$cuadro_w)+$d-imagefontwidth($ttf)*strlen(floor($y/$cuadro_w)),i($y+$d+10)-($mayor_yn*$cuadro_w)+1,floor($y/$cuadro_w),$negro);
- //Cuadro de relleno para tapar arriba y derecha.
- imagefilledrectangle($img,0,0,$ancho,$d,$blanco);//arriba
- imagefilledrectangle($img,$ancho-$d,$d,$ancho,$alto,$blanco);//derecha
- imageline($img,$d,$d,$ancho-$d,$d,$negro);//arriba
- imageline($img,$d,$alto-$d,$ancho-$d,$alto-$d,$negro);//abajo
- imageline($img,$ancho-$d,$d,$ancho-$d,$alto-$d,$negro);//derecha
- imageline($img,$d,$d,$d,$alto-$d,$negro);//izquierda
- //Tiramos los vectores
- foreach($V as $k => $v){
- if($k%2==0)
- $x=$v;
- if($k%2!=0)
- vector($x,$v,$negro);
- }
- //Tiramos lÃneas del paralelogramo
- if(isset($_GET['operacion']) and $_GET['operacion']=="sumar" and isset($V[5])){
- linea($V[0],$V[1],$V[4],$V[5],$gris);
- linea($V[2],$V[3],$V[4],$V[5],$gris);
- }
- if(isset($_GET['operacion']) and $_GET['operacion']=="restar" and count($V)>=4){
- linea($V[0],$V[1],$V[2],$V[3],$negro,true);
- }
- //resultante
- if(isset($_GET['operacion']) and $_GET['operacion']=="sumar")
- linea(0,0,$resultante_x,$resultante_y,$negro,true);
- if(isset($_GET['operacion']) and $_GET['operacion']=="multiplicar")
- if(isset($_GET['valor']) and is_numeric($_GET['valor']))
- linea(0,0,$resultante_x,$resultante_y,$negro,true);
- else{
- $rosa = imagecolorallocate($img,0xff,0xd7,0xff);
- imagefilledrectangle($img,30,240,470,274,$rosa);
- imagestring($img,3,40,250,"Para multiplicar, es necesario un solo vector, y un escalar.",$rojo);
- }
- //Nombre aleatoreo para la imagen
- $imagen = "img/".time()."-".rand(100,999).".png";
- $imagen = "temp.png";
- imagefilter($img,IMG_FILTER_NEGATE);
- //Logotipo de la Universidad de Colima
- imagecopyresampled($img,$img_ucol,$ancho-36,8,0,0,30,30,268,267);
- //imagepng($img,$imagen);//Para el Historial
- imagepng($img);//La mostramos
- imagedestroy($img);//Liberamos la memoria
- function vectores($V){
- foreach($V as $k => $v){
- if($k%2==0)
- echo "(";
- if($k%2==0)
- echo "<span style='color:#f00;'>$v</span>";
- else
- echo "$v";
- if($k%2==0)
- echo ",";
- else
- echo ")<br />";
- }
- }
- function ordenar($V){
- $N = count($V)-1;
- for($i=1;$i< =$N;$i++){
- if($i%2!=0)continue;//si es Y, continue;
- //Solo X
- for($j=$N;$j>=$i;$j--){
- if($j%2!=0)continue;//si es Y, continue;
- //Solo X
- if($V[$j-2]>$V[$j]){
- $aux = $V[$j-2];
- $aux2 = $V[$j-1];
- $V[$j-2] = $V[$j];
- $V[$j-1] = $V[$j+1];
- $V[$j] = $aux;
- $V[$j+1] = $aux2;
- }
- }
- }
- return $V;
- }
- function i($x){//Invierte los valores
- global $alto;
- return $alto-$x;
- }
- function vector($x,$y,$color=""){//Tira un Vector en el plano
- global $img, $cuadro_w, $mayor_xn, $d, $mayor_yn, $negro;
- $blanco = imagecolorallocatealpha($img,0xff,0xff,0xff,40);
- $ttf = 2;//Tamaño de la fuente
- if(empty($color)){
- $r = rand(0,200);
- $g = rand(0,250);
- $b = rand(0,200);
- $color = imagecolorallocate($img,$r,$g,$b);
- }
- $Acolor = $color;//imagecolorallocate($img,$b,0,$r);
- //Equivalente a Coordenada 0
- $x0 = $cuadro_w * $mayor_xn + $d;
- $y0 = $cuadro_w * $mayor_yn + $d;
- //Punto donde termina el vector
- $xf = $x0 + ($cuadro_w * $x);
- $yf = $y0 + ($cuadro_w * $y);
- $A="($x,$y)";
- $Aw = imagefontwidth($ttf) * strlen($A);
- $Ah = imagefontheight($ttf);
- //Tiramos LÃnea
- imageline($img,$x0,i($y0),$xf,i($yf),$color);
- //angulo del vector
- //Dibujamos las coordenadas
- if(!($x==0||$y==0)){
- if($x>0 and $y>0){
- imagefilledrectangle($img,$xf-$Aw,i($yf),$xf-$Aw+$Aw-1,i($yf)+$Ah-1,$blanco);
- imagestring($img,$ttf,$xf-$Aw,i($yf),$A,$negro);
- }
- if($x<0 and $y>0){
- imagefilledrectangle($img,$xf+imagefontwidth($ttf)* 2,i($yf),$xf+imagefontwidth($ttf)*2+$Aw-1,i($yf)+$Ah-1,$blanco);
- imagestring($img,$ttf,$xf+imagefontwidth($ttf)* 2,i($yf),$A,$Acolor);
- }
- if($x<0 and $y<0){
- imagefilledrectangle($img,$xf+imagefontwidth($ttf)* 2,i($yf+$Ah),$xf+imagefontwidth($ttf)*2+$Aw-1,i($yf+$Ah)+$Ah-1,$blanco);
- imagestring($img,$ttf,$xf+imagefontwidth($ttf)* 2,i($yf+$Ah),$A,$Acolor);
- }
- if($x>0 and $y<0){
- imagefilledrectangle($img,$xf-$Aw-imagefontwidth($ttf)* 2,i($yf+$Ah),$xf-$Aw-imagefontwidth($ttf)*2+$Aw-1,i($yf+$Ah)+$Ah-1,$blanco);
- imagestring($img,$ttf,$xf-$Aw-imagefontwidth($ttf)* 2,i($yf+$Ah),$A,$Acolor);
- }
- }else{
- if($y==0 and $x>0){
- imagefilledrectangle($img,$xf+imagefontwidth($ttf),i($yf+$Ah),$xf+imagefontwidth($ttf)+$Aw-1,i($yf+$Ah)+$Ah-1,$blanco);
- imagestring($img,$ttf,$xf+imagefontwidth($ttf),i($yf+$Ah),$A,$Acolor);
- }
- if($x==0 and $y>0){
- imagefilledrectangle($img,$xf+imagefontwidth($ttf),i($yf),$xf+imagefontwidth($ttf)+$Aw-1,i($yf)+$Ah-1,$blanco);
- imagestring($img,$ttf,$xf+imagefontwidth($ttf),i($yf),$A,$Acolor);
- }
- if($y==0 and $x<0){
- imagefilledrectangle($img,$xf+imagefontwidth($ttf),i($yf+$Ah),$xf+imagefontwidth($ttf)+$Aw-1,i($yf+$Ah)+$Ah-1,$blanco);
- imagestring($img,$ttf,$xf+imagefontwidth($ttf),i($yf+$Ah),$A,$Acolor);
- }
- if($x==0 and $y<0){
- imagefilledrectangle($img,$xf+imagefontwidth($ttf),i($yf+$Ah),$xf+imagefontwidth($ttf)+$Aw-1,i($yf+$Ah)+$Ah-1,$blanco);
- imagestring($img,$ttf,$xf+imagefontwidth($ttf),i($yf+$Ah),$A,$Acolor);
- }
- if($x==0 and $y==0){
- imagefilledrectangle($img,$xf+imagefontwidth($ttf),i($yf+$Ah),$xf+imagefontwidth($ttf)+$Aw-1,i($yf+$Ah)+$Ah-1,$blanco);
- imagestring($img,$ttf,$xf+imagefontwidth($ttf),i($yf+$Ah),$A,$Acolor);
- }
- }
- //Punta de la LÃnea
- imagefilledellipse($img,$xf,i($yf),6,6,$color);
- }
- function linea($x,$y,$x2,$y2,$color="",$style=false){//Tira una linea en el plano
- global $img, $cuadro_w, $mayor_xn, $d, $mayor_yn;
- $ttf = 2;//Tamaño de la fuente
- if(empty($color))
- $color = imagecolorallocate($img,0,0,0);
- $blanco = imagecolorallocate($img,0xff,0xff,0xff);
- //Equivalente a Coordenada 0
- $x0 = $cuadro_w * $mayor_xn + $d;
- $y0 = $cuadro_w * $mayor_yn + $d;
- //Punto donde inicia la linea
- $xi = $x0 + ($cuadro_w * $x);
- $yi = $y0 + ($cuadro_w * $y);
- //Punto donde termina la linea
- $xf = $x0 + ($cuadro_w * $x2);
- $yf = $y0 + ($cuadro_w * $y2);
- //Tiramos LÃnea
- if($style){
- $style = array(
- $color,$color,
- $blanco,$blanco,$blanco,$blanco,
- );
- imagesetstyle($img, $style);
- imageline($img,$xi,i($yi),$xf,i($yf),IMG_COLOR_STYLED);
- }else
- imageline($img,$xi,i($yi),$xf,i($yf),$color);
- //Punta de la Línea
- imagefilledellipse($img,$xi,i($yi),4,4,$color);
- imagefilledellipse($img,$xf,i($yf),6,6,$color-100);
- }
- La hoja de estilo CSS
- MooTools para los efectos horribles que le puse :S
- Graficando Vectores con GD+PHP (1era parte)
Angeltc
2007-10-23 16:42:46
Interesante tu código, yo tengo mi versión un poquito mas cortita ( sólo suma vectores y no me molesté en hacer un formulario, mas bien lo cargo todo desde un .txt ).
En fin, que el comentario era nada mas para preguntar sobre la licencia del código, es usable libremente?
Saludos.
Franklin arellan
2008-09-20 08:32:22
muy buen ejemplo de vectores bastante interesante
Victor De la Rocha
2009-05-08 02:51:03
Todo el contenido que puedas tomar de aquí, lo puedes re-utilizar respetando mi crédito como es debido.
Felipe R.
2010-01-26 09:58:46
¿y dónde está la url de la primera parte?
Victor
2010-06-02 20:22:00
buena pregunta jeje, aquí está la primera parte:
http://mis-algoritmos.com/graficando-vectores-con-gdphp