Foros del Web » Programación para mayores de 30 ;) » Programación General »

SVG y librería grafica

Estas en el tema de SVG y librería grafica en el foro de Programación General en Foros del Web. Hola qué tal: Estuve trasteando con SVG hace poco y se me ocurrió hacer una libreria grafica sencilla para poder crear graficos con javascript y ...
  #1 (permalink)  
Antiguo 08/09/2006, 14:12
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 21 años, 3 meses
Puntos: 45
SVG y librería grafica

Hola qué tal:

Estuve trasteando con SVG hace poco y se me ocurrió hacer una libreria grafica sencilla para poder crear graficos con javascript y modificarlos dinamicamente (con DOM).

Lo primero que hice fue crear las funciones para crear rectas

Código PHP:
<g id="contenedor"></g
Código PHP:
var contenddocument.getElementById('contenedor');

function 
recta(x1,y1,x2,y2,color) {
    
this.x1=x1this.y1=y1this.x2=x2this.y2=y2this.color=color;
    var 
r=document.createElement("line");
    
r.setAttribute("x1"x1); r.setAttribute("y1"y1);
    
r.setAttribute("x2"x2); r.setAttribute("y2"y2);
    
r.setAttribute("style""stroke:"+color);
    
this.setId=function(cual) {
        
this.setAttribute("id",cual);
    }
    return 
contend.appendChild(r);

alargarlas hasta una longitud bastante practica
Código PHP:
function alargar(idr) {
    
x1=parseInt(getAtr(idr,"x1")); x2=parseInt(getAtr(idr,"x2")); y1=parseInt(getAtr(idr,"y1")); y2=parseInt(getAtr(idr,"y2"));
    
avanzaX=x2-x1avanzaY=y2-y1;
    
n=1000;
    
recta(x1-avanzaX*ny1-avanzaY*nx2+avanzaX*ny2+avanzaY*n);

y crear circulos:
Código PHP:
function circulo(cx,cy,r,color,fill,op) {
    var 
c=document.createElement("circle");
    
c.setAttribute("cx"cx);
    
c.setAttribute("cy"cy);
    
c.setAttribute("r"r);
    
c.setAttribute("style""stroke: "+(color?color:"black")+"; fill:"+(fill?fill:"none")+"; opacity: "+(op==null?1:op));
    
    return 
contend.appendChild(c);

Y por ultimo marcar puntos con un aspa:
Código PHP:
function pto(xycolor) {
    var 
point1document.createElement('line'); var point2document.createElement('line');
    
point1.setAttribute('x1'x-5); point2.setAttribute('x1'x-5);
    
point1.setAttribute('y1'y-5); point2.setAttribute('y1'y+5);
    
point1.setAttribute('x2'x+5); point2.setAttribute('x2'x+5);
    
point1.setAttribute('y2'y+5); point2.setAttribute('y2'y-5);
    
point1.setAttribute("stroke-width","1"); point2.setAttribute("stroke-width","1");
    
point1.setAttribute("style""stroke:"+color); point2.setAttribute("style""stroke:"+color);
    
    
contend.appendChild(point1); contend.appendChild(point2);
    return [
x,y];

Visto esto parecia que podia crear cualquier forma SVG con javascript. Ahora viene lo mas complicado.

Me supuse que podia obtener la intersección de dos rectas que tenia dibujadas, y marcarlas por un punto. Eso no fue complicado, es un poquito de matematicas. Extrayendo la ecuacion de la recta que pasa por dos puntos de la forma y=Mx+N por cada recta, y luego tomando las y ó las x iguales se resuelve un sistema de dos incognitas y dos ecuaciones. El punto sale perfecto. Por cierto, defini cuatro funciones tontas para auxiliarme:
Código PHP:
function getAtr(id,atr) { return document.getElementById(id).getAttribute(atr); }
function 
setAtr(id,atr,val) { document.getElementById(id).setAttribute(atr,val); }
function 
p(x,n) { return Math.pow(x,n) }
function 
cuad(x) { return p(x,2); } 
Código PHP:
function i_r_r(id1,id2) {
    var 
x,y,x1,x2,y1,y2,X1,X2,Y1,Y2;
    
x1=parseInt(getAtr(id1,"x1")); x2=parseInt(getAtr(id1,"x2")); y1=parseInt(getAtr(id1,"y1")); y2=parseInt(getAtr(id1,"y2"));
    
X1=parseInt(getAtr(id2,"x1")); X2=parseInt(getAtr(id2,"x2")); Y1=parseInt(getAtr(id2,"y1")); Y2=parseInt(getAtr(id2,"y2"));
    
= (Y1*X2 Y2*X1)/((X2-X1)*((y2-y1)/(x2-x1) - (Y2-Y1)/(X2-X1))) - (y1*x2 y2*x1)/((x2-x1)*((y2-y1)/(x2-x1) - (Y2-Y1)/(X2-X1)));
    
= ((y2-y1)/(x2-x1))*+ (y1*x2 y2*x1)/(x2-x1);
    return [
x,y];

El punto de intersección se marca perfecto. Podemos hacer:
Código PHP:
rec=recta(200,300,800,500"orange");
rec2=recta(500,200,400,600"blue");
rec.setId("recta1");
rec2.setId("recta2");
elPto=i_r_r("recta1","recta2");
pto(elPto[0],elPto[1],"red"); 
Es sencillo. Creamos una recta (rec) y otra (rec2). Necesitaremos ponerles id's para pasarselo a la funcion i_r_r, asi que se los ponemos. elPto es una matriz con el punto de interseccion (elPto[0] es el X y elPto[1] es el Y). Luego dibujamos el punto.




Hasta ahí todo bien...


Ahora quería hacer lo mismo un poco mas complicado, intersección de recta y circunferencia.

Según las matematicas (hasta donde yo sé):
Código:
RECTA:
	((y2-y1)/(x2-x1))*x + (y1*x2 - y2*x1)/(x2-x1) = y
CIRCUNFERENCIA: 
	(x-X1)²+(y-Y1)²=R²
	x²+y²+Dx+Ey+F=0
		siendo D=-2*X1; E=-2*Y1; F=X1²+Y1²-R²
	
y como las y=Y y x=X sustituimos una en otra...
x²+(((y2-y1)/(x2-x1))*x + (y1*x2 - y2*x1)/(x2-x1))²+Dx+E*(((y2-y1)/(x2-x1))*x + (y1*x2 - y2*x1)/(x2-x1))+F=0
ahora solo tenemos que resolver esa ecuacion, sacando unas x que satisfagan la ec:
M=(y2-y1)/(x2-x1);
N=(y1*x2 - y2*x1)/(x2-x1);
x²+(M*x + N)²+Dx+E*(M*x + N)+F=0
x²+M²*x²+2*M*x*N+N²+Dx+E*M*x+E*N+F=0
(M²+1)*x² + (2*M*N+D+E*M)*x + (N²+E*N+F) = 0

ecuacion de 2º grado, 2 soluciones:
A=(M²+1);
B=(2*M*N+D+E*M);
C=(N²+E*N+F);
x=(-B+-sqrt(B²-4AC))/2A:
x_1=(-B+sqrt(B²-4AC))/2A; x_2=(-B-sqrt(B²-4AC))/2A;

y las y que correspondan ser. A x_1 le corresponde una y_1 y a x_2 le corresponde y_2 de 
((y2-y1)/(x2-x1))*x + (y1*x2 - y2*x1)/(x2-x1) = y
Así que en teoría es sencillo. Bueno pues en mi funcion (i_r_c) no funciona, da dos puntos bastante alejados del circulo (eso sí, pertenecen a la recta).
Código PHP:
function i_r_c(idr,idc) {
    var 
x1,x2,y1,y2,X1,Y1,RA,B,C,D,E,F,M,Nx_1x_2y_1y_2;
    
x1=parseInt(getAtr(idr,"x1")); x2=parseInt(getAtr(idr,"x2")); y1=parseInt(getAtr(idr,"y1")); y2=parseInt(getAtr(idr,"y2"));
    
X1=parseInt(getAtr(idc,"cx")); Y1=parseInt(getAtr(idc,"cy")); R=parseInt(getAtr(idc,"r"));
    
//C
    
D=-2*X1
    
E=-2*Y1
    
F=Math.sqrtcuad(X1)+cuad(Y1)-cuad(R) );
    
//R
    
M=(y2-y1)/(x2-x1); //if(x2-x1==0) M=0;
    
N=(y1*x2 y2*x1)/(x2-x1); //if(x2-x1==0) N=0;
    // ec grad 2
    
A=1+cuad(M);
    
B=2*M*N+E*M+D;
    
C=cuad(N)+E*N+F;
    
// resolucion:
    
x_1= (-B+Math.sqrt(cuad(B)-4*A*C))/(2*A);
    
y_1=M*x_1 N;
    
ptox_1y_1"red");
    
x_2= (-B-Math.sqrt(cuad(B)-4*A*C))/(2*A);
    
y_2=M*x_2 N;
    
ptox_2y_2"red");

No es tan complicada la funcion, pero he utilizado muchas letras, se hace mucho mas legible.


Pero el problema es que no da donde tiene que dar, da mucho mas lejos, haga lo que haga.
ejemplo:
Código PHP:
circ=circulo(300,300,150);
pto(300,300,"blue");
rec=recta(300,300,200,105"orange");
circ.setAttribute("id","miCirc");
rec.setAttribute("id","miRec");
alargar("miRec");
var 
choque=i_r_c("miRec","miCirc"); 


Espero que hayan entendido todo, alguna duda me comentan, y si encuentran la solución, algún método alternativo, o algo que me pueda interesar ya saben.


Un saludo y gracias.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 2 personas (incluyéndote)




La zona horaria es GMT -6. Ahora son las 12:52.