একটি অনিয়মিত আকারের ক্ষেত্রটি কীভাবে গণনা করবেন?


17

লুপিং লাইন বিভাগগুলির একটি সংকলন দ্বারা সংজ্ঞায়িত আমার কাছে একটি রুম অবজেক্ট রয়েছে যার জন্য অঞ্চলটি গণনা করা দরকার। ক্লাসগুলি নীচে বর্ণিত হতে পারে (সিউডো-কোডে):

class Point {
    float x; 
    float y;
    ...
    float distanceFrom(Point p);
}

class Segment {
    Point start;
    Point end;
    ...
    float length();
}

class Room {
    List<Segment> walls;
    ...
    float area();
}

ঘরের দেয়াল কখনও কোথাও ছেদ করতে পারে না তবে বিভাগগুলির শেষ পয়েন্টগুলিতে এবং তৈরি করা "সাব-লুপগুলি" একটি নতুন ঘরে আলাদা করা হবে। সমাধানটি পুরোপুরি নির্ভুল হওয়ার প্রয়োজন নেই (ত্রুটির 10% মার্জিন গ্রহণযোগ্য) এবং খুব প্রায়ই গণনা করা হয় না (<1 / s)।


7
Roomগুলিগুলির একটি তালিকা অন্তর্ভুক্ত করার জন্য এটি আরও অর্থপূর্ণ হবে Pointএবং তারপরে প্রতিটি পয়েন্টকে এক সাথে সংযুক্ত করে বিভাগগুলি পান এবং তারপরে আবার লুপ করুন। অন্যথায়, আপনার বর্তমান সেটআপের সাথে, ভুল মানগুলি পাওয়া খুব পূর্ব দিকে (যেমন বন্ধ না হওয়া ঘর, মাঝখানে প্রাচীরযুক্ত ঘর ইত্যাদি)। এটি সেরা বিকল্প হবে।
এমসিমিস্ট্রি

আর একটি বিকল্প হ'ল শীর্ষটি আকারের ত্রিভুজ এবং প্রতিটি ত্রিভুজের ক্ষেত্রগুলি গণনা করুন। শক্ত অংশটি ত্রিভুজ। করণীয়, তবে সবসময় সুন্দর নয়। জুতার উত্তরটি এখনও আরও ভাল।
Draco18s আর এসই-তে বিশ্বাস করে না

@ এমসিমিস্টেরির সমাধানটি কার্যকর হবে না, কারণ এটি Roomসর্বদা সম্পূর্ণ হওয়া দরকার , এবং আমার যদি প্লেয়ারকে Roomএস ব্যবহার করে তৈরি করতে পারা যায় তবে তা নাও হতে পারে Segment। এছাড়াও, একটি বদ্ধ ঘরে ফাংশনটি নির্ধারণ করা সহজ (কেবলমাত্র Segmentসেগুলির মধ্যে লুপ করুন এবং তারা একটি ঘর তৈরি করেছেন তা নিশ্চিত করুন)।

উত্তর:


31

আপনি গাউসের জুতার ফর্মুলাটি ব্যবহার করতে পারেন :

আপনাকে প্রতিটি পয়েন্টের এক্স স্থানাঙ্ক নিতে হবে, তাদের পরবর্তী পয়েন্টের y স্থানাঙ্ক দ্বারা গুণিত করুন, তারপরে বর্তমান পয়েন্টের y স্থানাঙ্ককে ফলাফল থেকে পরবর্তী পয়েন্টের এক্স স্থানাঙ্ক দ্বারা গুণিত করে মোট ক্ষেত্রের সাথে যুক্ত করুন। আপনি প্রতিটি পয়েন্টের জন্য এটি করার পরে, বহুভুজের আসল অঞ্চল পেতে মোট অঞ্চলটি অর্ধেক করুন। যদি বর্তমান পয়েন্টটি সর্বশেষ হয় তবে তারপরেরটি প্রথমটি।

A = 0

for (i = 0; i < points.length; i++) do

    A += points[i].x * points[(i + 1) % points.length].y - points[i].y * points[(i + 1) % points.length].x

end

A /= 2

2
আমি সর্বদা এটি ব্যবহার করেছি যে দুটি ভেক্টরের ক্রস প্রোডাক্ট গণনা করতে কখনও জানত না যে এটিকে জুতো অ্যালগরিদম বলা হয়
সিডার

3
নোট করুন যে এটি ত্রিভুজগুলি দিয়ে তৈরি একটি অনিয়মিত 3 ডি অবজেক্টের ভলিউম গণনা করার জন্য বাড়ানো যেতে পারে এবং এটি ক্যালকুলাসের মৌলিক উপপাদ্যের একটি তুচ্ছ ঘটনা হিসাবে বিবেচনা করা যেতে পারে।
ডায়েটারিচ এপ্প

5
এখানকার অঞ্চলটি স্বাক্ষরিত। পয়েন্টগুলি অন্য দিক দিয়ে যান এবং চূড়ান্ত Aউপেক্ষিত হয়। লক্ষ্য উপর নির্ভর করে একটি A = |A|প্রয়োজন হতে পারে। নেতিবাচক অঞ্চল কোড সহ পয়েন্টগুলির অভ্যন্তরীণ এবং বাইরের তালিকা (বিপরীত ক্রমের একটি) ব্যবহার করে একটি অনিয়মিত ডোনাট অঞ্চলটি খুঁজে পেতে পারে।
chux

6
কারণ অবশ্যই গস বা ইউলারের উভয়েরই জন্য এটির একটি সূত্র রয়েছে।
কর্সিকা

0

আমরা একটি মন্টি কার্লো পদ্ধতিও ব্যবহার করতে পারি।

যথেচ্ছ আকারের চারপাশে একটি আয়তক্ষেত্র আঁকুন Dra অভিন্ন বিতরণকৃত PRNG উত্স যেমন ধরুন। মেরস্নে টুইস্টার, তারপরে আয়তক্ষেত্রের এক্স, ওয়াই দৈর্ঘ্যের দ্বারা মডুলো ফাংশনটি ব্যবহার করে আউটপুটটি আবদ্ধ করুন। নং গণনা করুন। আপনার আকারের অভ্যন্তরে এলোমেলো পয়েন্টের। উত্পাদিত পয়েন্টগুলির মোট পরিমাণ দ্বারা ভাগ করুন। আয়তক্ষেত্রের ক্ষেত্রফল দ্বারা সেই ভাগফলকে গুণ করুন। প্রতিটি পুনরাবৃত্তির সাহায্যে আপনি সত্য অঞ্চলে রূপান্তর করতে পারবেন। অ্যালগরিদমটি হাস্যকরভাবে পার্থিবোধযোগ্য এবং নির্বিচারে মাত্রিক আকার 'ভলিউম' গণনা করতে ব্যবহার করা যেতে পারে, যতক্ষণ আপনি নির্ধারণ করতে পারবেন যে কোনও আর ^ N স্থানাঙ্ক আকৃতির আর ^ N সীমানার মধ্যে পড়ে কিনা।

এখানে কেউ এই পদ্ধতিটি চেনাশোনা অঞ্চলটি ব্যবহার করছে তারপরে পাই গণনা করার জন্য এটি ব্যবহার করে https://www.youtube.com/watch?v=VJTFfIqO4TU


2
-১: আপনি এটির পরিসীমা পেতে মডুলো ব্যবহার করতে চান না, আপনি একটি অভিন্ন বিতরণ বা অন্যান্য বিতরণ ব্যবহার করতে চান, এটি মডিউল পদ্ধতিতে সমস্ত ধরণের পরিসংখ্যানগত সমস্যা রয়েছে।
ব্যবহারকারী 1997744

12
এই পদ্ধতিটি উপকারী হতে পারে যখন আমাদের কাছে কোনও সাধারণ বহুভুজ না থাকে, তবে এমন একধরণের অন্তর্নিহিত আকার রয়েছে যার ফ্র্যাক্টাল বা মেটাবল ব্লবের মতো সীমানা প্রকাশ করা কঠিন। প্রশ্ন হিসাবে যেমন বহুভুজের ক্ষেত্রে এটি মনে হয় এটি অযথা ব্যয়বহুল হবে।
ডিএমগ্রিগরি

@ ডিএমজি গ্রেগরি যেমন উল্লেখ করেছে, এটি আমি যা খুঁজছিলাম তা নয়। তবে আমি মনে করি যে কারওর প্রয়োজনে এটি একটি +1 প্রাপ্য।

এটি আকর্ষণীয় তবে অন্তর্ভুক্তি পরীক্ষাগুলির ব্যয় কী প্রতিরোধমূলক হবে না? উদাহরণস্বরূপ, আপনার যদি এমন আকৃতি থাকে যা এই পদ্ধতির জন্য ওয়ারেন্ট দেওয়ার পক্ষে যথেষ্ট জটিল, তবে অন্তর্ভুক্তি পরীক্ষাগুলিও কি সত্যিই ব্যয়বহুল হবে না, যদি আপনি সেগুলি টন করতে চান না? (বহুভুজ অনুমান করে)
মতিয়া

ঠিক আছে Modulo আসলে সমস্যাযুক্ত, কিন্তু এটি একটি সহজ সমাধান। আমরা যা পাই তা হ'ল এলোমেলো পি = 1/2 বিট 0/1, সুতরাং আমরা যা পাই তা সংখ্যার অভিন্ন বিতরণ। ০ থেকে from পর্যন্ত its বিটের জন্য rand এড়াতে আপনার কোনও স্টেট মেশিনের মতো কিছু দরকার যা ম্যাপিংকে ঘুরিয়ে দেয়। 6,7 মানচিত্র 1,2 তারপর 3,4 তারপর 5,0 এ এবং এটি এগিয়ে যায়। তারা যখনই আসে তখন আমরা 6,7 ফেলে দিতে পারি। যাইহোক এটি একটি লাইব্রেরি বাস্তবায়নের সমস্যা।
ফ্র্যাঞ্জ

-1

অন্য পদ্ধতির: না।

পরিবর্তে:

while (Segments.Count > 3)
{
    Segment A = Segments[Segments.Count - 2];
    Segment B = Segments[Segments.Count - 1];
    Segment C = new Segment(B.End, A.Start);
    Triangle T = new Triangle(A, B, C);
    Segments[Segments.Count - 2] = C;
    Segments.RemoveAt(Segments.Count - 1);
    if (B is inside the new shape Segments)
        Area -= T.Area;
    else
        Area += T.Area;
}
Area += new Triangle(Segments[0], Segments[1], Segments[2]).Area;

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


2
গাউসের শোলিজ সূত্র এটির জন্য একটি সংক্ষিপ্তকরণ যা গণনার সংখ্যা অর্ধেক বা তৃতীয়াংশ। এটি কাজ করে।
পিটার জেরকেন্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.