একটি চেনাশোনা (চিত্র) এর মধ্যে এলোমেলো পয়েন্ট (পিক্সেল) গণনা করুন


19

আমার একটি চিত্র রয়েছে যাতে একটি নির্দিষ্ট স্থান এবং একটি নির্দিষ্ট ব্যাসের চেনাশোনা রয়েছে। আমার যা করা দরকার তা হ'ল বৃত্তের মধ্যে এলোমেলো পয়েন্টগুলি গণনা করতে সক্ষম হবেন এবং তারপরে পিক্সেলগুলিকে ম্যানিপুলেট করতে পয়েন্টের সাথে সম্পর্কিত বলেছিলেন। আমার কাছে ইতিমধ্যে নিম্নলিখিত কোড রয়েছে:

private Point CalculatePoint()
{
    var angle = _random.NextDouble() * ( Math.PI * 2 );
    var x = _originX + ( _radius * Math.Cos( angle ) );
    var y = _originY + ( _radius * Math.Sin( angle ) );
    return new Point( ( int )x, ( int )y );
}

এবং এটি বৃত্তের পরিধি হিসাবে সমস্ত পয়েন্টগুলি সন্ধান করার জন্য সূক্ষ্মভাবে কাজ করে, তবে আমার বৃত্তের যে কোনও জায়গা থেকে সমস্ত পয়েন্ট দরকার। যদি এটি অর্থবোধ না করে তবে আমাকে জানান এবং আমি পরিষ্কার করার জন্য যথাসাধ্য চেষ্টা করব।


আপডেটটি দেখুন।
ডেভিড গাউভিয়া

3
এই বিবেচনায় ভাল প্রশ্ন যে অজান্তেই ভারী বিতরণ তৈরি করা একটি সাধারণ ত্রুটি।
টিম হল্ট

উত্তর:


35

আপনি যদি একটি সহজ সমাধান চান তবে কেবল ব্যাসার্ধটিকেও এলোমেলো করুন:

private Point CalculatePoint()
{
    var angle = _random.NextDouble() * Math.PI * 2;
    var radius = _random.NextDouble() * _radius;
    var x = _originX + radius * Math.Cos(angle);
    var y = _originY + radius * Math.Sin(angle);
    return new Point((int)x,(int)y);
}

তবে এর ফলে আপনার পয়েন্টগুলি বৃত্তের কেন্দ্রের দিকে আরও বেশি কেন্দ্রীভূত হবে:

এখানে চিত্র বর্ণনা লিখুন

অভিন্ন বন্টন পেতে আলগোরিদিমে নিম্নলিখিত পরিবর্তন করুন:

var radius = Math.Sqrt(_random.NextDouble()) * _radius;

যা নিম্নলিখিত ফলাফল দেবে:

এখানে চিত্র বর্ণনা লিখুন

আরও তথ্যের জন্য নিম্নলিখিত লিঙ্কটি পরীক্ষা করুন: ম্যাথ ওয়ার্ল্ড - ডিস্ক পয়েন্ট পিকিং

এবং শেষ পর্যন্ত এখানে অ্যালগোরিদমের উভয় সংস্করণের তুলনা করে একটি সাধারণ জেএসফিডাল বিক্ষোভ রয়েছে


1
দুর্দান্ত উত্তর। কেবল একটি জিনিস যোগ করতে: এলোমেলো সংখ্যা জেনারেটর বীজ করতে ভুলবেন না :)
কেভিনটোডিসকো

ওফ আপনি এটির সাথে সাক্ষাত করেছেন - আমি আমার পোস্ট করার সময় এই পোস্টটি দেখেনি। ওল্ফ্রাম সাইট এই ধরণের জিনিসটির জন্য দুর্দান্ত এক উত্স।
টিম হল্ট

1
@ টিমহোল্ট সর্বদা হয় :)
ডেভিড

এটি কি ধরে নিচ্ছে যে বৃত্ত কেন্দ্রটি 0,0 এ রয়েছে?
jjxtra

@ সাইকোড্যাড বৃত্তের কেন্দ্র হবে (_রিজিএনএক্স, _রিজিনওয়াই)
ডেভিড

5

শুধু এলোমেলো আর এবং থেইটা ব্যবহার করবেন না! এটি কেন্দ্রে আরও পয়েন্ট সহ ভারী বিতরণ তৈরি করে। এই পৃষ্ঠাটি এটি ভালভাবে চিত্রিত করে ...

http://mathworld.wolfram.com/DiskPointPicking.html

এখানে এমন পদ্ধতিটি যা একটি ওজনহীন বিতরণ তৈরি করে ...

var r = rand(0,1)
var theta = rand(0,360)

var x = sqrt(r) * cos(theta)
var y = sqrt(r) * sin(theta)

উফ নির্বাচিত উত্তরের সদৃশ: পি
টিম হল্ট

আমি বিভ্রান্ত কারণ আপনি র্যান্ডম আর এবং থেইটা ব্যবহার করবেন না বলে এটি ভারী বিতরণ তৈরি করে বলে আপনি যে কোডটি দেখান তাতে আপনি দাবী করছেন যে একটি নন-ওজনযুক্ত বিতরণ তৈরি করে এটি [0,1] এর মধ্যে আর তৈরি করে। আপনি কি এলোমেলো সংখ্যাটি বর্গমূল করতে চান?
পিটুক

হ্যাঁ ব্যাসার্ধের বর্গমূলকে (যতক্ষণ না এটি 0-1 হয়) মাঝখানে পয়েন্টগুলির অপ্রত্যাশিত ঘনত্বকে হ্রাস করে। আমি পোস্ট করা ওল্ফ্রাম লিঙ্কটি দেখুন, যা এটি চিত্রিত করে এবং আমার চেয়ে আরও ভাল অঙ্কের সাথে এটি ব্যাখ্যা করে।
টিম হল্ট

আমার খারাপ। আমি x এবং y গণনা করার সময় আপনাকে sqrt (r) করতে দেখছি do
পিটিউকে

4

আপনি সেখানে অর্ধেক। এলোমেলো কোণ উত্পন্ন করার পাশাপাশি, ব্যাসার্ধের চেয়ে কম বা সমান, এলোমেলো দূরত্ব তৈরি করুন যাতে আপনি অভিন্ন বন্টন পান:

private Point CalculatePoint()
{
    var angle = _random.NextDouble() * Math.PI * 2;
    var distance = Math.Sqrt(_random.NextDouble()) * _radius;
    var x = _originX + (distance * Math.Cos(angle));
    var y = _originY + (distance * Math.Sin(angle));
    return new Point((int)x, (int)y);
}

এখন আপনি মেরু দিয়ে ভাবছেন ।

স্কোয়ার রুট এড়াতে আপনিও এর মতো দূরত্বকে ওজন করতে পারেন:

var distance = _random.NextDouble() + _random.NextDouble();
distance = (distance <= 1 ? distance : 2 - distance) * _radius;

ঠিক আছে, সুতরাং আমরা পার্থক্য কয়েক সেকেন্ডের মধ্যে ঠিক একই উত্তর দেওয়া। এখন কি? :)
ডেভিড গওভিয়া

@ ডেভিডগুভিয়া আমরা উভয়ই সঠিকভাবে থাকার জন্য উভয়কেই সমীক্ষা করি। সবাই জিতল! : ডি
জন পুরী

উভয় উত্তর খুব প্রশংসা (এবং লিঙ্কটিও!)। মানুষ আমি নিজেও তা না দেখার জন্য একজন বোকা, আমার কাছে -1 :( আপনারা উভয়েরই আবার ধন্যবাদ!
ডিএমিলস

এটি এলোমেলো পয়েন্ট উত্পন্ন করবে, তবে সেগুলি ডিস্কের উপরে একত্রে বিতরণ করা হবে না, তাই না? বরং সেগুলি কেন্দ্রের দিকে ভারী করা হবে। শুধু যাচ্ছি আমি কিছু মিস করছি না not
পিটুক

1
@ পেটুক: আপনি ঠিক বলেছেন, দূরত্বটি ওজন করা উচিত। আমাকে আপডেট করুন।
জন পূর্দি

3

পারফরম্যান্স যদি সমস্যা হয় তবে একটি বিকল্প সমাধান হ'ল আপনার বৃত্তের প্রস্থ / উচ্চতা সহ একটি বাক্সে এলোমেলো অবস্থান তৈরি করা এবং তারপরে বৃত্তের অঞ্চলে নয় এমন কোনও পয়েন্ট দূরে ফেলে দেওয়া।

এই পদ্ধতির সুবিধাটি হ'ল আপনি কোনও কস / পাপ / স্কয়ার্ট ফাংশন করছেন না যা আপনার প্ল্যাটফর্মের উপর নির্ভর করে একটি বড় গতির সাশ্রয় হতে পারে।

var x = _random.NextDouble();
var y = _random.NextDouble();
if (x*x + y*y < 1.0f)
{
    // we have a usable point inside a circle
    x = x * diameter - _radius + _OriginX;
    y = y * diameter - _radius + _OriginY;
    // use the point(x,y)
}

আমি এটি চেষ্টা করে দেখতে যাচ্ছি এবং এটি জিনিসগুলির গতি বাড়িয়ে দেয় কিনা তা দেখতে যাচ্ছি। আমি নিশ্চিত যে আমার একটি পারফরম্যান্স সমস্যা আছে তবে আমি যাইহোক এটি চেষ্টা করব, ধন্যবাদ!
ডিএমিলস

0

আমি তালিকাভুক্ত মন্তব্যগুলির মধ্যে একটিের পদ্ধতিকে গ্রহণ করেছি এবং একটি ডোনাট শেপড পয়েন্ট জেনারেশন সিস্টেম তৈরি করতে কার্যকারিতা বাড়িয়েছি।

            private Vector2 CalculatePosition()
            {
                double angle = _rnd.NextDouble() * Math.PI * 2;
                double radius = InnerCircleRadius + (Math.Sqrt(_rnd.NextDouble()) * (OuterCircleRadius - InnerCircleRadius));
                double x = (_context.ScreenLayout.Width * 0.5f) + (radius * Math.Cos(angle));
                double y = (_context.ScreenLayout.Height * 0.5f) + (radius * Math.Sin(angle));
                return new Vector2((int)x, (int)y);
            }

এটি পূর্বে উল্লিখিত মত একই পদ্ধতির তবে বিভিন্ন ফলাফল সরবরাহ করেছে provided বৃত্তের অভ্যন্তরীণ অংশটি বিন্দু ছাড়াই ফাঁকা ছেড়ে যাবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.