2011-04-15 33 views
7

में शंकु/वेज आकार यह सरल ज्यामिति का थोड़ा सा होना चाहिए: मैं नीचे दिए गए कोड में रेखाओं को आकर्षित करने के लिए बिंदुओं की गणना कैसे करूं ताकि यह 2 डी शंकु या वेज आकार बना सके?एक बिंदु से एक रेखा से विपरीत सर्कल पर एक रेखा खींचें? AS3

import flash.geom.Point; 

//draw circle 
var mc=new Sprite() 
mc.graphics.lineStyle(0,0) 
mc.graphics.drawCircle(0,0,30) 
mc.x=mc.y=Math.random()*300+100 
addChild(mc) 

//draw lines: 
graphics.lineStyle(0,0) 
var p=new Point(Math.random()*500,Math.random()*400) 
graphics.moveTo(p.x, p.y) 
graphics.lineTo(mc.x,mc.y) // << should be point on edge of circle 
graphics.moveTo(p.x, p.y) 
graphics.lineTo(mc.x,mc.y) // << should be point on opposite edge of circle 

अद्यतन:
धन्यवाद दोस्तों, मैं उल्लेख किया जाना चाहिए था मेरे उद्देश्य एक पच्चर आकार आकर्षित करने के लिए है, लेकिन किसी मौजूदा मंडली के किनारे करने के लिए एक यादृच्छिक बिंदु से एक लाइन आकर्षित करने के लिए नहीं है।

यदि आप एक्शनस्क्रिप्ट से बीजगणित के साथ अधिक सहज हैं, तो हो सकता है कि आप इस ग्राफिक को देख सकें और मेरे लिए फॉर्मूला पोस्ट कर सकें? tangents

+0

+1 महान प्रश्न। मैं वास्तव में इसे – Chris

+0

पर काम करने की कोशिश कर रहा था, मुझे पता था कि कोई इसका आनंद लेगा! यह मेरा सिर कर रहा था: डी सरल समाधान के लिए धन्यवाद एक टन। – cronoklee

+0

कोई समस्या नहीं है। प्रोजेक्ट – Chris

उत्तर

2

आपका प्रश्न इस बारे में है थाल्स प्रमेय (देखें http://en.wikipedia.org/wiki/Thales%27_theorem)।

निम्नलिखित प्रमेय एएस 3 के साथ काम करने के लिए थोड़ा संशोधित है।

आयात flash.geom.Point;

// The radius of the circle 
var r1:Number = 30; 
// The center point of the circle 
var cp:Number = Math.random() * 300+100; 
var c:Point = new Point(cp, cp); 

// draw circle 
var mc=new Sprite(); 
mc.graphics.lineStyle(0,0); 
mc.graphics.drawCircle(0,0,r1); 
mc.x = mc.y = cp; 
addChild(mc); 

// The point 
var p = new Point(Math.random() * 500, Math.random() * 400); 

// Calculate points for intesecting circle 
var c2:Point = Point.interpolate(c, p, 0.5); 
var r2:Number = Point.distance(c2, c); 
var d:Number = Point.distance(c, c2); 

// Remove comment below to see intersecting circle 
//graphics.beginFill(0xFF0000, 0.25); 
//graphics.drawCircle(c2.x, c2.y, r2); 

var a:Number = (r1*r1 - r2*r2 + d*d)/(2*d); 
var p2x:Number = c.x + a * (c2.x - c.x)/d; 
var p2y:Number = c.y + a * (c2.y - c.y)/d; 
var h:Number = Math.sqrt(r1*r1 - a*a); 

var d1x:Number = p2x + h * (c2.y - c.y)/d; 
var d1y:Number = p2y - h * (c2.x - c.x)/d; 
var d2x:Number = p2x - h * (c2.y - c.y)/d; 
var d2y:Number = p2y + h * (c2.x - c.x)/d; 

// Draw lines 
graphics.lineStyle(1, 0xFF00FF, 0.5); 
graphics.moveTo(p.x, p.y); 
graphics.lineTo(d1x, d1y); 
graphics.moveTo(p.x, p.y); 
graphics.lineTo(d2x, d2y); 

अंतिम उत्पाद:

enter image description here

तैयार दूसरे चक्र के साथ

(आप वास्तव में आप सिर्फ अपने केंद्र बिंदु और त्रिज्या की जरूरत है, दूसरे चक्र में आकर्षित करने के लिए की जरूरत नहीं है)

enter image description here

कार्रवाई में देखने के लिए निम्नलिखित एसडब्ल्यूएफ चेकआउट करें (विभिन्न यादृच्छिक मंडलियों को देखने के लिए ताज़ा करें):

http://megaswf.com/serve/1097652

0

graphics.curveTo(controlX,ControlY,endX,endY);

नियंत्रण (एक्स, वाई) के साथ वर्तमान बिंदु और अंत (एक्स, वाई) के बीच एक Bézier खींचता बिंदु वक्र (Photoshop में पेन टूल की तरह) की ओर मुड़े है किया जा रहा है। आधे डेल्टा एक्स पर सेट करें और इसकी ताकत को समायोजित करने के लिए वाई का उपयोग करें।

+0

के साथ गुडलक धन्यवाद, मुझे यह कहना चाहिए था कि मेरा लक्ष्य एक वेज आकार नहीं बनाना है, बल्कि मौजूदा सर्कल के किनारे पर एक रेखा खींचना है। – cronoklee

0

यहां 2 डी वेज आकार बनाने के लिए एक स्निपेट है। वेज के कोण को नियंत्रित करने के लिए आप startAngle और angle वर्ण समायोजित कर सकते हैं। त्रिज्या आकार की चौड़ाई निर्धारित करेगा। इसका उपयोग आकार, स्प्राइट, मूवीक्लिप या कुछ उप-वर्ग के भीतर किया जाना चाहिए जिसमें ग्राफिक्स ऑब्जेक्ट हो।

var i:int; 
var p:Point = new Point(); 
var g:Graphics = graphics; 
var radius:Number = 100; 
var startAngle:Number = 130; 
var angle:Number = 280; 
var segments:Number = 40; 
var degrees:Number = (startAngle + (angle - startAngle))/segments; 

g.beginFill(0xFF0000, 1); 
for(i = 0; i <= segments; i++) 
{ 
    p.x = Math.cos(((degrees * i) + startAngle) * Math.PI/180) * radius; 
    p.y = Math.sin(((degrees * i) + startAngle) * Math.PI/180) * radius; 
    g.lineTo(p.x, p.y); 
} 
g.endFill(); 
1

पी, एम के रूप में चक्र केंद्र, और वृत्त पर स्पर्श बिंदु के रूप में अपनी बात निरूपित एक्स त्रिभुज पीएमटी एक समकोण त्रिभुज है। हो सकता है कि आप पेपर पर इसे स्केच करना चाहें क्योंकि आप इसका पालन करना आसान बनाते हैं।

एक्स की स्थिति एक्स प्लस रेडियल वेक्टर की स्थिति एक्स यानी किनारे एमएक्स की स्थिति है। गणना वेक्टर एमएक्स की गणना के बारे में है।

वेक्टर एमएक्स को दो लंबवत घटकों में विघटित किया जा सकता है। एक जो एमपी के समानांतर है और एक जो एमपी के लिए लंबवत है। करने के लिए पहली बात उन दो दिशाओं में इकाई वैक्टर प्राप्त होती है। पहला आसान है क्योंकि यह एमपी का सामान्यीकृत संस्करण है। घटकों को स्वैप करके और एक घटक को अस्वीकार करके इसे एक लंबवत वेक्टर आसानी से 2 डी में प्राप्त किया जाता है। आप जिस घटक को अस्वीकार करते हैं वह अप्रासंगिक है क्योंकि आप आखिरकार दोनों स्पर्श रेखाएं चाहते हैं।

अब हमारे पास हमारे दो यूनिट वेक्टर हैं जिन्हें हमें यह पता लगाने की आवश्यकता है कि रेडियल वेक्टर एमएक्स बनाने के लिए प्रत्येक को कितना आवश्यक है। थेटा द्वारा कोण पीएमएक्स को दर्शाते हुए हमारे पास सरल दाएं कोण वाले त्रिभुजों से है जो cos (theta) = r/| एमपी | जहां आर आपके सर्कल का त्रिज्या है और | एमपी | एमपी की लंबाई है (जिसे आप पहले से ही अपने यूनिट वेक्टर प्राप्त करने के लिए गणना कर चुके हैं)।

एक्स से एमपी तक लंबवत छोड़ने से एक और दाहिने कोण वाला त्रिभुज होता है जिसमें विपरीत और आसन्न पक्ष दो घटकों का प्रतिनिधित्व करते हैं। इन पक्षों की लम्बाई एमपी दिशा में आर * कोस (थेटा) और लंबवत दिशा में आर * पाप (थेटा) हैं।

तो अपने अंतिम परिणाम अनिवार्य है

एक्स = एम + r * cos (थीटा) * unit_MP + r * sin (थीटा) * स्पर्श बिंदुओं में से एक और

के लिए unit_MP_perp_1

एक्स = एम + आर * कॉस (थेटा) * यूनिट_एमपी + आर * पाप (थेटा) * यूनिट_एमपी_परपी_2

दूसरे के लिए।यूनिट_एमपी और यूनिट_एमपी_पीआरपी_1/2 यूनिट वेक्टर हैं जिन्हें हमने पहले काम किया था। पेप वेक्टर का 1/2 संस्करण स्वैप के बाद पहले या दूसरे घटकों को अस्वीकार करने के अनुरूप है।

संपादित

आरेख आपके द्वारा जोड़े के संदर्भ में, समीकरण

x1 = cx + आर * cos (थीटा) * Ux + आर * sin (थीटा) * U1x
y1 हो जाता है = सी + आर * कॉस (थेटा) * यूई + आर * पाप (थेटा) * यू 1y

समान समीकरणों (x2, y2) के साथ। इन समीकरणों में

cos (थीटा) = आर/डी
पाप (थीटा) = ए/डी

जहां डी = sqrt ((px - CX)^2 + (py - cy) 2 ^)

और

Ux = (px -cx)/डी
Uy = (py -cy)/डी

और इतने

U1x = -Uy
U1y = Ux

अन्य स्पर्श बिंदु के लिए सीधा इकाई वेक्टर होगा

U2x = Uy
U2y = -Ux

+0

बहुत धन्यवाद @Troubadour लेकिन मैं अभी भी आपके चर के साथ थोड़ा खो गया हूँ। क्या आप शायद ऊपर पोस्ट किए गए ग्राफिक पर एक नज़र डाल सकते हैं और मेरी शर्तों का उपयोग करके अपने सूत्र को फिर से लिख सकते हैं? ऐसा लगता है कि मुझे क्या चाहिए! – cronoklee

+0

आपकी व्याख्या में "एम" क्या है? तुमने मुझे वहां खो दिया –

+0

वूप्स, मैं पूरी तरह से माफी मांगता हूं। मैंने सर्कल के केंद्र के रूप में एम के साथ पेपर पर कदम लिखे थे क्योंकि आपके चर को एमसी कहा जाता था लेकिन फिर एहसास हुआ कि यह सी होना चाहिए था! जब मैंने अपना जवाब लिखा तो मैंने सी के साथ शुरुआत की लेकिन एम को बहुत जल्दी उपयोग करने के लिए वापस चला गया। हर किसी को भ्रमित करने के लिए खेद है! मैंने इसे एम में बदल दिया है क्योंकि अधिकांश उत्तर पहले से ही इसका इस्तेमाल करते हैं। – Troubadour

1

(xP, yP) स्पर्शरेखा के चौराहे होने दो , (xC,yY) सर्कल का केंद्र बनें, जहां आप स्पर्श बिंदुओं के निर्देशांक (xT,yT) के लिए देख रहे हैं। और अधिक T टेंगेंट के वेक्टर बनें और R त्रिज्या के वेक्टर बनें। चूंकि वे लंबवत हैं, आपके पास R . T = 0 है।

यह हमें देता है

(xT-xC,yT-yC) . (xT-xP, yT-yP) = 0 

r वृत्त की त्रिज्या हो सकता है और x:=xT-xC, y:=yT-yC, xp:=xP-xC, yp:=yP-yC जाने (मूल रूप से, हम (0,0) में वृत्त ले जाते हैं) करते हैं। टेंगेंट बिंदु सर्कल पर है, इसलिए आपके पास x²+y²=r² है और इस प्रकार y=sqrt(r²-x²) भी है।

चर प्रतिस्थापन उपरोक्त समीकरण के लिए आवेदन किया हमें देता है:

r² -xp*x - yp*sqrt(r²-x²) = 0 
r² -xp*x = yp*sqrt(r²-x²) 
r^4 - 2*r²*xp*x + xp²*x² = yp²*(r²-x²) 
(yp²+xp²)*x² - 2*r²*xp*x + r^4-yp²*r² = 0 

now let a:=yp²+xp², b:=2*r²*xp, c:= (r²-yp²)*r² 
=> ax² + bx + c = 0 

यह 0, 1 या 2 समाधान के साथ एक quadratic equation है:

(x,y) . (x-xp, y-yp) = 0 
x²-xp*x + y²-yp*y = 0 

चक्र जानकारी हमारे पास है का उपयोग करना। 0, यदि पी सर्कल, 1, यदि पी सर्कल और 2 पर है, यदि पी सर्कल के बाहर है।

मैं स्पष्ट समाधान यहाँ रखा नहीं होगा, क्योंकि यह एक सूत्र का एक नरक है और यह, लिखने के लिए यदि आप के रूप में अपने कोड में चर चर करने के लिए यहाँ पेश किया नक्शा एक बहुत आसान है:

var sq:Function = function (f:Number) { return f*f; }, sqrt:Function = Math.sqrt; 
var xp:Number = xP-xC, yp:Number = yP-yC, 
    a:Number = sq(xp)+sq(yp), b:Number = 2*sq(r)*xp, c:Number = sq(r)*(sq(r)-sq(yp)); 
var x1:Number = (-b+sqrt(sq(b)-4*a*c))/(2 * a), 
    x2:Number = (-b+sqrt(sq(b)-4*a*c))/(2 * a); 
if (isNan(x1)) return []; 
var p1:Point = new Point(x1+cX, sqrt(sq(r)-sq(x1))+cY),//calculate y and undo shift 
    p2:Point = new Point(x2+cX, sqrt(sq(r)-sq(x2))+cY); 
return p1.equals(p2) ? [p1] : [p1, p2]; 

इसके साथ शुभकामनाएं, क्योंकि मैं गणित के साथ बहुत बुरा हूं, साथ ही यह 04:00 है, इसलिए आप शर्त लगा सकते हैं कि कहीं गलती है, लेकिन इसे आपको सही दिशा में ले जाना चाहिए;)

संबंधित मुद्दे