2016-03-21 26 views
1

üzerinde duracak şekilde nasıl hesaplayabilirim? Bilinen bir X eşgüdümüne sahip olan ve bilinen bir noktaya (pembe içinde daire içine alınmış) sahibim Y eşgüdümü ancak Y koordinatı yanlıştır. Halihazırda hedef bezier eğrisinin (beyaz bir kare içinde eğri) iki nokta arasında bir çizgi olsaydı, üzerinde durduğu nokta üzerinde durmaktadır. Benim yuvarlak noktam için doğru Y koordinatını hesaplamalıyım, böylece kırmızı haç üzerinde biter.Bir X koordinatı verildiğinde, Y koordinatını, bir Bezier Eğrisi

enter image description here

Bir C# programcı değil bu cevabı o zaman bu benim için anlamı çok olacağını kodunda veya denklemin katılan her parametresi hakkında açıklama ile ifade edilip edilemeyeceğini yüzden matematikçi değilim. Eğer daha sonra cevap bulabilirsem, Blender'ı bu amaçla bir Python betiğiyle genişletebilirim.

UPDATE: Sorunu daha iyi ifade etmek için soruyu ve görüntüsünü değiştirdim. Ben sadece Y koordinatının kırmızı haçta ne olduğunu bulmak için bir araç istiyorum. Bunu düşündüğümüzde trigonometri olabilir ve bezier eğrileri ile ilgisi yoktur, ancak sadece ilk segmentte değil, bu eğrinin herhangi bir noktasında bulunan bir işaretleyici için Y koordinatını belirleme ihtiyacım olacak onun çizgisi.

+0

biraz daha fazla bilgi gereklidir - farklı bir "y" değeri vermek istediğiniz bir noktanız (x, y) var mı yoksa bir * eğri var mı? (x, y) üzerinde durur ve * tüm eğriyi * değiştirmek istersiniz, böylece en azından sizin (x, y) koordinatınız için, “y” koordinatı istenen hedef değere sahip olur mu? Çünkü ilk durum çok anlamlı görünmüyor, ikinci durumda ise eğrinin ne tür bir eğri olduğu, hedef eğrisinin ne tür bir eğri olduğu, daha fazla noktanın sıraya girip girmeyeceği vb. Hakkında biraz daha fazla ayrıntı gerektiriyor. –

+0

İhtiyacım olan ilk dava; pembe daire içindeki nokta '(1, -0.6)' 'olması gereken '' (1,?)' dır ama 'Y''''nün ne olduğunu bilmiyorum. Neden bu anlamlı değil? Bu noktalardan oluşan bir dizi var, zaten bir yaratığımın alt yarısını yapmak için aynı şeyi yapmaya ihtiyacım var. – Sphynx

cevap

1

Doğru matematik yanıtı: Eğer kesin cevaplar istiyorsanız, matematik, sonuna ihtiyacınız var; Bezier eğrileri parametrik eğrilerdir ve tek bir x değeri için birden fazla y değerine sahip olabilir (ve tam tersi), bu yüzden ne yaptığınızı tam olarak anlamadan bunları bulamayacaksınız.

bir programlama egzersiz basitçe her eğri için (örneğin {t=0 -> {x:...,y:...}, t=0.01 -> {x:...y:...}, ...}) L de bakınız U p T ables koordinat inşa etmek olduğu gibi, kesin olmayan şekilde Bunu yapmak ve bunu basitçe bir için LUT aramak için daha kolay bir yolu x veya y değerine karşılık gelen (muhtemelen çoklu) karşılık gelen y veya x değerlerini vermek için verilen değer. Bazı x için y değerlerine ihtiyacınız varsa, LUT'nizi x'a göre sıralayın ve ardından en iyi eşleşmeleri bulmak için ikili arama yapın. Bazı y için x'a ihtiyacınız varsa, y'a göre sıralayın ve aynısını yapın.

Güzel ve basit. Eğer bir programcı olarak gerçekten önemsemeliyiz hassas çözümler, isterseniz

Ama, o zaman ne istediğiniz "çizgi" boyunca eğri yönünü etmektir yapabilirsiniz (örneğin, değerlerini bulmaya çalışıyorsanız, "Bazı x için tüm y değerleri", eğri ile (x=a, y=-inf)--(x=a,y=inf) arasındaki tüm kesişimleri aradığınız anlamına gelir ve daha sonra kesişme algılaması yaparken elde ettiğiniz t değerlerini kontrol edersiniz.

Burada gerçek gerçek cevapları istiyorsanız, intersection detection between curves and lines üzerindeki Bezier Eğrileri bölümünde bu Primer'e bir göz atın (bu da sırasıyla root finding bölümüne dayanmaktadır). Eğer küp eğrileri ile uğraşıyorsanız, align curves'un nasıl olduğunu anlamanız gerekir, böylece kavşakları bulmak kök bulmaya indirgenir, daha sonra Cardano'nun algoritmasını çalıştırmak için (muhtemelen üç) değeri bulmak için çalıştırmanız gerekir.

+0

"Bezier eğrileri parametrik eğrilerdir ve tek bir x değeri için birden çok y değerine sahip olabilir" dediğinizde, bezier eğrilerinin bir çözünürlüğü olduğundan (eğrim 16 noktalı bir çizgi) mi?Yani, sabit bir çözünürlük göz önüne alındığında, x değeri için sadece 1 y değerinde olmayacak mı? – Sphynx

+0

Hayır, çünkü onlar * parametrik fonksiyonlardır *. [Bu açıklama] 'ya bir bakın (http://pomax.github.io/bezierinfo/#explanation), fakat buradaki veriler, parametrik fonksiyonlarda bir 'x' değeri ve bir' y' değeri arasında doğrudan bir ilişki olmamasıdır. hiç de öyle ki, bir "x" değeri için "y" değerini almayı soramayız. Bir, iki, üç, hatta sonsuz sayıda olabilir. En basit durum, 'x = cos (t)' ve 'y = sin (t)' nin olduğu bir çemberdir. X = 0' için "y" değeri nedir? Bir tane yok. İki tane. Aynı, ama daha da aşırı, Bezier eğrilerini tutar: üç 'y' değerine sahip olabilirsiniz. –

+0

Örneğimde 'x == 0' ise' y == 0'; Daha önce hesaplanmış ve değişmeyecek olan bir eğri üzerinde birden fazla değerin nasıl olabileceğini anlamıyorum. Eğer eğrimdeki ilk açılı nokta '1, -0.2' koordinatlarına sahip olsaydı ve taşımaya çalıştığım nokta '1' değerine sahipti, o zaman doğru 'y' değeri olurdu -0.2 Çünkü o zaman eğrinin çizgisinde direk uzanacaktı. Bu mantığa başka ne verilebilir ki? – Sphynx

0

Bezier eğrileri, t parametre (x()t,y(t)) Bezier eğri üzerindeki noktadır

x(t)=fx(t) 
y(t)=fy(t) 

ve fx(),fy() polinom fonksiyonu olan parametre bulunmaktadır.

Bu, Bezier eğrilerinin zorunlu olarak işlevleri olmadığı anlamına gelir (tek başına y değerlerine sahip olabilir (x). Bu nedenle için t parametrelerini x0 -koordinatınız olarak bulmanız gerekir.

onun cevabını siz LUT kullanabilir veya cebirsel fx(t)-x0=0 polinomun köklerini hesaplayabilir bahsedildi @ Mike 'Po max' Kamermans gibi.

Ayrıca approximation search (ikili aramaya benzer, ancak monoton olmayan fonksiyonlarda da kullanılabilir) kullanımı ile çok daha basit bir matematiksel seçenek gerektirmeyen (ancak daha yavaş olan) daha basit bir seçenek de vardır. Bu C++ kodu gibi örnek bir şey için: o zaman tüm olası puan gerekirse yeni bulunan çözüm sağlanıncaya kadar

double x0,y0;   // your point x0 valid y0 not yet 
double ax0,ax1,ax2,ax3; // cubic Bezier fx() polynomial coefficients 
double ay0,ay1,ay2,ay3; // cubic Bezier fy() polynomial coefficients 
double ee,x,t,tt,ttt; 
approx aa; 
for (aa.init(0.0,1.0,0.025,6,&ee); !aa.done; aa.step()) // search t 
{ 
    t = aa.a; 
    tt = t*t; 
    ttt = tt*t; 
    x = ax0 + ax1*t + ax2*tt + ax3*ttt; // compute the x=fx(t) 
    ee = fabs(x-x0);    // compute error of solution for the approximation search 
} 
// here aa.a holds found `t0` 
t = aa.a; 
tt = t*t; 
ttt = tt*t; 
y0 = ay0 + ay1*t + ay2*tt + ay3*ttt; // compute the final y0=fx(t0) 

özyinelemeli <0.0,t0) ve (t0,1.0> arama aralığını t=<0.0,1.0> bölmek gerekir.

[edit1] 2D Bezier eğrilerinin olarak (Mike 'Pomax' Kamermans tarafından istenen) biraz daha fazla bilgi

fonksiyonları koordinat tek x daha y değerler olabilir zorunlu değildir. Bu örnekte olduğu gibi:

example

sayılı mavi noktalar hale 2D Bezier eğrisinin kontrol noktalarıdır. Sarı olanlar yukarıda açıklanan özyineli çözüm buldu. Bunun İşte bazı C++ örnek: orada çözümlerin sonsuz sayıda olduğundan

double x0;    // input x coordinate 
List<double> y0;  // output y coordinates 

double ax0,ax1,ax2,ax3; // cubic coefficients 
double ay0,ay1,ay2,ay3; 
double px0,px1,px2,px3; // control points 
double py0,py1,py2,py3; 
//--------------------------------------------------------------------------- 
bool find_point(double t0,double t1,int layer) 
    { 
    approx aa; 
    double ee,x,y,t,tt,ttt,dt; 
    const double _zero=1e-4;  
    dt=0.025*(t1-t0); // approximation search step 
    if (dt<=_zero) return false; // stop if too small interval to search to avoid stack overflows 
    if (layer>10) return false; // stop if too high recursion layer to avoid stack overflows (this also limits the max found solutions 
    for (aa.init(t0,t1,dt,6,&ee); !aa.done; aa.step()) // search t 
     { 
     t = aa.a; 
     tt = t*t; 
     ttt= tt*t; 
     x = ax0 + ax1*t + ax2*tt + ax3*ttt; // compute the x=fx(t) 
     ee = fabs(x-x0);      // compute error of solution for the approximation search 
     } 
    // check the error of found solution 
    if (aa.e0>_zero) return false; 
    // here aa.aa holds found `t0` 
    t = aa.aa; 
    // check bounds can cross the border a bit 
    if (t<t0) return false; 
    if (t>t1) return false; 
    // add new solution 
    tt = t*t; 
    ttt= tt*t; 
    y = ay0 + ay1*t + ay2*tt + ay3*ttt;  // compute the final y0=fx(t0) 
    y0.add(y);         // add to list of solutions 
    // recursion to check for other solutions by dividing the interval by found solution 
    if (t0<t-dt) find_point(t0,t-dt,layer+1); 
    if (t1>t+dt) find_point(t+dt,t1,layer+1); 
    } 
//--------------------------------------------------------------------------- 
// here usage 
void test() 
{ 
// just compute the Bezier cubic polynomials from control points 
ax0=        ( px0); 
ax1=     (3.0*px1)-(3.0*px0); 
ax2=   (3.0*px2)-(6.0*px1)+(3.0*px0); 
ax3=( px3)-(3.0*px2)+(3.0*px1)-( px0); 
ay0=        ( py0); 
ay1=     (3.0*py1)-(3.0*py0); 
ay2=   (3.0*py2)-(6.0*py1)+(3.0*py0); 
ay3=( py3)-(3.0*py2)+(3.0*py1)-( py0); 
// Find the points from mouse x0 coordinate 
y0.num=0;    // clear found solutions list 
find_point(0.0,1.0,0); // recursively found solutions on interval t=<0,1> ,as highest recursion level 0 
} 

Bu dikey çizgiler ile ilgili bir sorun var ... yerine bunlardan sadece birkaç bulundu edecektir. Aksi halde kullanılması güvenlidir. (sorunsuz bir şekilde çalışması için birçok kontrol ekledi)

+0

Bu kod, aa.init() 'in ne yaptığını, iterasyon değişkeninin ne olduğunu, ne yaptığını ve ne olduğunu (aa.step()) neyin tam olarak açıkladığı gibi bazı açıklamalara ihtiyaç duyabilir. Bu kodu biraz tekrar yazmak iyi bir fikir olur, böylece minimum ve eksiksiz olur. Ve bu çözümün çalışmadığı zaman açıklamanız gerekebilir, çünkü bu kodun tüm çözümleri bulamayacağı sonsuz sayıda eğri vardır, çünkü iki veya üç olsa bile, yalnızca bir tane bulabilir. –

+0

@ Mike'Pomax'Kamermans yaklaşık iç işleyiş hakkında bir soru bağlantılı soruda açıklanmaktadır. Ve ayrıca son cümleyi okursanız, diğer noktaları nasıl elde edeceğinizi açıklar. Ama haklısın, daha net bir şey yapmalıyım. Son zamanlarda çok fazla başvuruda bulunduğum için, yaklaşık olarak arama motoruyla ilgili ** QA ** eklemeyi düşünüyorum. – Spektre

+0

Konuyla ilgili bir web sayfası olarak yanıtlamak için bu soruyu ve düzenlemelerinizi yeniden düzenlemek isteyebilirsiniz ("yakınlaştırma araması" kolay bir şekilde atanan bir terim değildir), böylece insanları çevrelerine ve etrafındakilere bağlayabilir ve ardından oradaki kişileri gönderebilirsiniz (https://pomax.github.io/bezierinfo nasıl doğdu). Bu cevabı biraz daha açık hale getirmek, özellikle python ve C++ arasındaki farklar göz önüne alındığında oldukça değerli olacaktır (python yazan birisinin, C++ 'da bir işaretçi/referans-ağır bit içinde neler olduğunu anladığı konusunda makul bir beklenti yoktur) –

İlgili konular