2011-09-06 11 views
9

मैं अंक का एक सेट उत्पन्न करने की कोशिश कर रहा हूं (Vector संरचना द्वारा प्रतिनिधित्व) जो लगभग सर्पिल आकाशगंगा का मॉडल करता है।गैलेक्सी जनरेशन एल्गोरिदम

सी # कोड जो मैं साथ खेल रहा हूं नीचे है; लेकिन मुझे लगता है कि यह आकाशगंगा के एक 'हाथ' उत्पन्न करने के लिए प्रतीत होता है।

public Vector3[] GenerateArm(int numOfStars, int numOfArms, float rotation) 
    { 
     Vector3[] result = new Vector3[numOfStars]; 
     Random r = new Random(); 

     float fArmAngle = (float)((360/numOfArms) % 360); 
     float fAngularSpread = 180/(numOfArms * 2); 

     for (int i = 0; i < numOfStars; i++) 
     { 

      float fR = (float)r.NextDouble() * 64.0f; 
      float fQ = ((float)r.NextDouble() * fAngularSpread) * 1; 
      float fK = 1; 

      float fA = ((float)r.NextDouble() % numOfArms) * fArmAngle; 


      float fX = fR * (float)Math.Cos((MathHelper.DegreesToRadians(fA + fR * fK + fQ))); 
      float fY = fR * (float)Math.Sin((MathHelper.DegreesToRadians(fA + fR * fK + fQ))); 

      float resultX = (float)(fX * Math.Cos(rotation) - fY * Math.Sin(rotation)); 
      float resultY = (float)(fY * Math.Cos(rotation) - fX * Math.Sin(rotation)); 

      result[i] = new Vector3(resultX, resultY, 1.0f); 
     } 

     return result; 
    } 
+0

ऐसा लगता है कि एक दूसरे numOfArms के आधार पर पाश और हथियारों के बीच कोणीय दूरी के अनुसार हाथ कोण offseting की जरूरत है। फिर numOfStars/numOfArms होने के लिए अपने आंतरिक पुनरावृत्ति पाश को बदलें। –

+0

क्या यह gamedev पर नहीं है? –

+0

इसके अलावा: http://stackoverflow.com/questions/348321/mathematical-question-procedural- जनरेशन-of-a-galaxy –

उत्तर

2

मैं अमूर्त होगा कि createArm फ़ंक्शन में कार्य करता है।

फिर आप प्रत्येक हाथ को अपनी आकाशगंगा (अस्थायी रूप से) के रूप में स्टोर कर सकते हैं।

तो यदि आप 2 हथियार चाहते हैं, तो 5000 की 2 आकाशगंगाएं करें। फिर, उनमें से एक को उत्पत्ति के चारों ओर 0 डिग्री घुमाएं (इसलिए हिलना नहीं है) और मूल के चारों ओर 180 डिग्री।

इसके साथ आप अलग-अलग रोटेशन राशियों का उपयोग कर हथियारों की मनमानी संख्या कर सकते हैं। आप घूर्णन दूरी को अधिक यादृच्छिक बनाकर, "360/n) की बजाय एक सीमा के साथ कुछ" प्राकृतिककरण "भी जोड़ सकते हैं। उदाहरण के लिए, 5 हथियार 0, 72, 144, 216, 288 होगा लेकिन कुछ randomization के साथ आप कर सकते हैं यह 0, 70, 146, 225, 301

संपादित करें:

कुछ त्वरित गूगल फू कहता है मुझे (source)

q = initial angle, f = angle of rotation. 

x = r cos q 
y = r sin q 

x' = r cos (q + f) = r cos q cos f - r sin q sin f 
y' = r sin (q + w) = r sin q cos f + r cos q sin f 

hence: 
x' = x cos f - y sin f 
y' = y cos f + x sin f 
+0

कोई विचार है कि मैं एल्गोरिदम को 0.0 के आसपास के सभी मानों को' घूमने 'के लिए कैसे बदल सकता हूं? मैं इसे प्रत्येक बिंदु पर एक रोटेशन मैट्रिक्स के साथ कर सकता हूं, लेकिन createArm फ़ंक्शन में 'रोटेशन ऑफसेट' मान में पास करने में सक्षम होना बेहतर होगा, और अंक पीढ़ी पर घुमाएंगे। –

+0

क्या कोई सर्पिल आकाशगंगाएं हैं जिनमें दो से अधिक हथियार हैं? मुझे नहीं लगता कि ऐसा तब तक होता है जब तक कि यह किसी तरह से व्यवधान (विलय/टक्कर) के कारण एक क्षणिक सुविधा नहीं है। –

+0

@ क्रिसिस मैंने सिग्ग्राफ से छेड़छाड़ किए गए कुछ सूत्रों को जोड़ा। – corsiKa

4

इस चेक। यह घनत्व तरंग सिद्धांत का उपयोग कर आकाशगंगा का अनुकरण है। कोड उपलब्ध है। http://beltoforion.de/galaxy/galaxy_en.html

+0

लिंक मर चुका है, लेकिन उन सभी के लिए जो अभी भी इसे पढ़ना चाहते हैं, निम्न लिंक का उपयोग करें https://web.archive.org/web/20140119101505/http://beltoforion.de/galaxy/galaxy_en.html – Peter

4

मुझे यह विचार पसंद आया कि मुझे अपने साथ अपने साथ खेलना पड़ा और मेरा परिणाम यहां है। ध्यान दें कि मैंने वेक्टर 3 के बजाय पॉइंटएफ का उपयोग किया है, लेकिन आप कुछ स्थानों पर खोज और प्रतिस्थापित करने और , 0) जोड़ने में सक्षम होना चाहिए।

PointF[] points; 

private void Render(Graphics g, int width, int height) 
{ 
    using (Brush brush = new SolidBrush(Color.FromArgb(20, 150, 200, 255))) 
    { 
     g.Clear(Color.Black); 
     foreach (PointF point in points) 
     { 
      Point screenPoint = new Point((int)(point.X * (float)width), (int)(point.Y * (float)height)); 
      screenPoint.Offset(new Point(-2, -2)); 
      g.FillRectangle(brush, new Rectangle(screenPoint, new Size(4, 4))); 
     } 
     g.Flush(); 
    } 
} 

public PointF[] GenerateGalaxy(int numOfStars, int numOfArms, float spin, double armSpread, double starsAtCenterRatio) 
{ 
    List<PointF> result = new List<PointF>(numOfStars); 
    for (int i = 0; i < numOfArms; i++) 
    { 
     result.AddRange(GenerateArm(numOfStars/numOfArms, (float)i/(float)numOfArms, spin, armSpread, starsAtCenterRatio)); 
    } 
    return result.ToArray(); 
} 

public PointF[] GenerateArm(int numOfStars, float rotation, float spin, double armSpread, double starsAtCenterRatio) 
{ 
    PointF[] result = new PointF[numOfStars]; 
    Random r = new Random(); 

    for (int i = 0; i < numOfStars; i++) 
    { 
     double part = (double)i/(double)numOfStars; 
     part = Math.Pow(part, starsAtCenterRatio); 

     float distanceFromCenter = (float)part; 
     double position = (part * spin + rotation) * Math.PI * 2; 

     double xFluctuation = (Pow3Constrained(r.NextDouble()) - Pow3Constrained(r.NextDouble())) * armSpread; 
     double yFluctuation = (Pow3Constrained(r.NextDouble()) - Pow3Constrained(r.NextDouble())) * armSpread; 

     float resultX = (float)Math.Cos(position) * distanceFromCenter/2 + 0.5f + (float)xFluctuation; 
     float resultY = (float)Math.Sin(position) * distanceFromCenter/2 + 0.5f + (float)yFluctuation; 

     result[i] = new PointF(resultX, resultY); 
    } 

    return result; 
} 

public static double Pow3Constrained(double x) 
{ 
    double value = Math.Pow(x - 0.5, 3) * 4 + 0.5d; 
    return Math.Max(Math.Min(1, value), 0); 
} 

उदाहरण:

points = GenerateGalaxy(80000, 2, 3f, 0.1d, 3); 

परिणाम: Galaxy

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