Graficando Vectores con GD+PHP (2da parte)
Después de tanto hacerme pato con mi proyecto de física (Ni tan solo, se supone era en equipo.), 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 al mero estilo Microsoft parchando mi aplicación… obteniendo así un chilaquil medio funcional :P
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(