2012-01-26 26 views
6

Ben aşağıdaki bilgileri:hesaplayın merkezi

  • radiusX (rx)
  • radiusY (ry)
  • x1
  • y1
  • x2
  • y2

SVG özellikleri tanımlamanıza olanak tanır yarıçapını ve başlangıç ​​ve bitiş noktalarını belirterek bir yay. Başlangıç ​​noktasının bitiş noktasına nasıl ulaşacağını tanımlamanıza yardımcı olan large-arc-flag ve sweep-flag gibi başka seçenekler de vardır. More details here.

Matematiksel olarak eğimli değilim, bu nedenle all of this'un anlaşılması imkansızdır.

Sanırım SVG'nin ark komutu tarafından kabul edilen tüm argümanlar verilen centerX ve centerY değerlerini bilmemle sonuçlanan basit bir denklem arıyorum.

Herhangi bir yardım için teşekkür ederiz.

Stackoverflow'ta arama yaptım ve yanıtların hiçbiri sade ingilizcede çözümü açıklamıyor gibi görünüyor.

cevap

1

I x-ekseni rotasyon başlangıç ​​ve bitiş noktaları için = 0 Denklemler durum göz önünde ediyorum:

X1 = Cx + RX * cos (StartAngle)

y1 = cy + Ry * sin (StartAngle)

x2 = Cx + rX * cos (EndAngle)

y2 = cy + ry * sin (EndAngle) denklemi pa

hariç açıları

ry^2 * (x1-cx)^2 + RX^2 * (y1-CY)^2, RX^2 * Ry^2

Ry^2 * (X2-: irs bize sunduğu cx)^2 + rx^2 * (y2-cy)^2 = rx^2 * ry^2

Bu denklem sistemi analitik olarak (cx, cy) el ile veya matematik paketlerinin yardımıyla çözülebilir (Akçaağaç, Mathematica vb. İkinci dereceden denklemin iki çözümü vardır (büyük ark bayrak ve süpürme-bayrak kombinasyonu nedeniyle).

+0

Teşekkür ama ben o denklemi çözmek için yok nasıl itiraf etmeliyim. – James

2

Hesaplamak için bu javascript işlevini kullanabilirsiniz.

// svg : [A | a] (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ 

/* x1 y1 x2 y2 fA fS rx ry φ */ 
function radian(ux, uy, vx, vy) { 
    var dot = ux * vx + uy * vy; 
    var mod = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy)); 
    var rad = Math.acos(dot/mod); 
    if(ux * vy - uy * vx < 0.0) rad = -rad; 
    return rad; 
} 
//conversion_from_endpoint_to_center_parameterization 
//sample : convert(200,200,300,200,1,1,50,50,0,{}) 
function convert(x1, y1, x2, y2, fA, fS, rx, ry, phi) { 
     var cx,cy,theta1,delta_theta; 

     if(rx == 0.0 || ry == 0.0) return -1; // invalid arguments 

     var s_phi = Math.sin(phi); 
     var c_phi = Math.cos(phi); 
     var hd_x = (x1 - x2)/2.0; // half diff of x 
     var hd_y = (y1 - y2)/2.0; // half diff of y 
     var hs_x = (x1 + x2)/2.0; // half sum of x 
     var hs_y = (y1 + y2)/2.0; // half sum of y 

     // F6.5.1 
     var x1_ = c_phi * hd_x + s_phi * hd_y; 
     var y1_ = c_phi * hd_y - s_phi * hd_x; 

     var rxry = rx * ry; 
     var rxy1_ = rx * y1_; 
     var ryx1_ = ry * x1_; 
     var sum_of_sq = rxy1_ * rxy1_ + ryx1_ * ryx1_; // sum of square 
     var coe = Math.sqrt((rxry * rxry - sum_of_sq)/sum_of_sq); 
     if(fA == fS) coe = -coe; 

     // F6.5.2 
     var cx_ = coe * rxy1_/ry; 
     var cy_ = -coe * ryx1_/rx; 

     // F6.5.3 
     cx = c_phi * cx_ - s_phi * cy_ + hs_x; 
     cy = s_phi * cx_ + c_phi * cy_ + hs_y; 

     var xcr1 = (x1_ - cx_)/rx; 
     var xcr2 = (x1_ + cx_)/rx; 
     var ycr1 = (y1_ - cy_)/ry; 
     var ycr2 = (y1_ + cy_)/ry; 

     // F6.5.5 
     theta1 = radian(1.0, 0.0, xcr1, ycr1); 

     // F6.5.6 
     delta_theta = radian(xcr1, ycr1, -xcr2, -ycr2); 
     var PIx2 = Math.PI * 2.0; 
     while(delta_theta > PIx2) delta_theta -= PIx2; 
     while(delta_theta < 0.0) delta_theta += PIx2; 
     if(fS == false) delta_theta -= PIx2; 

     var outputObj = { /* cx, cy, theta1, delta_theta */ 
      cx : cx, 
      cy : cy, 
      theta1 : theta1, 
      delta_theta : delta_theta 
     } 
     console.dir(outputObj); 

     return outputObj; 
} 
+1

Bu, başvurulan SVG ekinin iyi bir uygulamasıdır. Ne yazık ki, her durumda işe yaramıyor. "Coe" hesaplanırken sqrt içindeki değerin negatif olduğu bazı (çok nadir olmayan) kenar durumları vardır. Http://svn.apache.org/repos/asf/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/geom/ExtendedGeneralPath.java adresindeki 'computeArc 'bölümüne bakın. Değer negatif ise, bu uygulama merkez noktası alır (0,0), benim için işe yarıyor gibi görünüyor. Bir örnek, rx = ry = 60 (0, 100) ila (100, 0) arasındaki bir yaydır. – brianmearns