সারসংক্ষেপ
এই উত্তরটি প্রশ্নটিকে বৃহত্তর প্রসঙ্গে ফেলেছে, বৈশিষ্ট্যগুলির শেফফিল উপস্থাপনার জন্য প্রযোজ্য একটি দক্ষ অ্যালগরিদম বর্ণনা করে ("ভেক্টর" বা "পয়েন্টগুলির" লাইনস্ট্রিংস "হিসাবে), এর প্রয়োগের কয়েকটি উদাহরণ দেখায় এবং ব্যবহার বা পোর্টিংয়ের জন্য কার্য কোড দেয় একটি জিআইএস পরিবেশ।
পটভূমি
এটি রূপচর্চা বিশিষ্টতার উদাহরণ । সম্পূর্ণ সাধারণভাবে, একটি বিচ্ছিন্নতা তাদের অঞ্চলে একটি অঞ্চলের পয়েন্টগুলি "ছড়িয়ে দেয়"; পয়েন্টগুলি যেখানে তারা বাড়ে সেখানে সংগ্রহ "হ্রাস"। জিআইএস-এর অ্যাপ্লিকেশনগুলি অসংখ্য: আগুনের বিস্তার, সভ্যতার চলাচল, গাছপালার বিস্তার এবং আরও অনেক কিছুর মডেলিং।
গাণিতিকভাবে এবং খুব দুর্দান্ত (তবে দরকারী) সাধারণতার মধ্যে, একটি বিস্তৃতি একটি রিমানিয়ান বহুগুণে (যেমন একটি বিমান, গোলক, বা উপবৃত্তাকার) পয়েন্টগুলির একটি সেট ছড়িয়ে দেয় । এই পয়েন্টগুলিতে স্পর্শটি স্পর্শকাতর বান্ডেলের একটি উপসেট দ্বারা নির্ধারিত হয় । এর অর্থ হ'ল প্রতিটি বিন্দুতে ভেক্টরগুলির একটি সেট (দিকনির্দেশ এবং দূরত্ব) দেওয়া হয় (আমি এটিকে "প্রতিবেশ" বলি); এই ভেক্টরগুলির প্রত্যেকটি তার বেস পয়েন্ট থেকে শুরু করে একটি জিওডেসিক পাথ বর্ণনা করে । এই সমস্ত পথের প্রান্তে বেস পয়েন্টটি "স্প্রেড" হয়। ("প্রসারণ" এর আরও সীমিত সংজ্ঞার জন্য যা প্রচলিতভাবে চিত্র প্রক্রিয়াকরণে নিযুক্ত করা হয়, উইকিপিডিয়া নিবন্ধটি দেখুন see ছড়িয়ে পড়া ক্রিয়াকলাপটি তাত্পর্যপূর্ণ মানচিত্র হিসাবে পরিচিত ডিফারেনশিয়াল জ্যামিতিতে)
কোনও বৈশিষ্ট্যের "বাফারিং" হ'ল এই জাতীয় বিস্তারের সহজতম উদাহরণগুলির মধ্যে: বৈশিষ্ট্যের প্রতিটি পয়েন্টের চারপাশে ধ্রুবক ব্যাসার্ধের একটি ডিস্ক (বাফার ব্যাসার্ধ) তৈরি করা হয় (কমপক্ষে ধারণামূলকভাবে)। এই ডিস্কগুলির ইউনিয়নটি বাফার।
এই প্রশ্নটি একটি আরও জটিল জটিল প্রসারণের গণনা জিজ্ঞাসা করে যেখানে কেবলমাত্র প্রদত্ত কোণগুলির (অর্থাৎ, একটি বৃত্তাকার ক্ষেত্রের মধ্যে) মধ্যে ছড়িয়ে পড়ার অনুমতি দেওয়া হয়। এটি কেবল এমন বৈশিষ্ট্যগুলির জন্যই অর্থবোধ করে যা কোনও প্রশংসনীয়ভাবে বাঁকানো পৃষ্ঠকে ঘিরে থাকে না (যেমন গোলক বা উপবৃত্তাকারে ছোট বৈশিষ্ট্য বা বিমানের কোনও বৈশিষ্ট্য)। আমরা যখন বিমানটিতে কাজ করি তখন এটি সমস্ত সেক্টরকে একই দিকে অভিমুখী করে তোলা অর্থপূর্ণ। (আমরা যদি বাতাসের মাধ্যমে আগুনের বিস্তারকে মডেলিং করতাম তবে আমরা চাই যে সেক্টরগুলি বাতাসের সাথে কেন্দ্রিক হবে এবং বাতাসের গতির সাথে তাদের আকারগুলিও পৃথক হতে পারে: এটি আমি যে প্রসার দিয়েছি তার সাধারণ সংজ্ঞার জন্য একটি প্রেরণা। ) (উপবৃত্তাকার মতো বাঁকা পৃষ্ঠের উপরে সমস্ত ক্ষেত্রকে "একই" দিকের দিকে পরিচালিত করা অসম্ভব))
নিম্নলিখিত পরিস্থিতিতে প্রসারণ তুলনামূলকভাবে সহজ:
বৈশিষ্ট্যটি সমতলে রয়েছে (এটি হ'ল আমরা বৈশিষ্ট্যের মানচিত্রটি ছড়িয়ে দিচ্ছি এবং আশা করি মানচিত্রটি মোটামুটি নির্ভুল)।
প্রসারণ স্থির থাকবে : বৈশিষ্ট্যের প্রতিটি পয়েন্টে ছড়িয়ে পড়া একই অভিযানের একত্রিত পাড়াগুলির মধ্যে ঘটবে।
এই সাধারণ পাড়াটি উত্তল। উত্তেজনা গণনাগুলি ব্যাপকভাবে সরল করে তোলে এবং গতি বাড়ায়।
এই প্রশ্নটি এই ধরনের বিশেষায়িত পরিস্থিতিতে ফিট করে: এটি বৃত্তাকার ক্ষেত্রগুলি দ্বারা যার উত্স (ডিস্কগুলির কেন্দ্রগুলি যেখানে তারা এসেছিল) বেস পয়েন্টগুলিতে অবস্থিত দ্বারা স্বেচ্ছাসেবী বহুভুজগুলির বিসারণের জন্য জিজ্ঞাসা করে। শর্ত থাকে যে এই ক্ষেত্রগুলি 180 ডিগ্রির বেশি ছড়িয়ে না যায়, তারা উত্তল হবে। (বৃহত্তর খাত সর্বদা অর্ধে দুটি উত্তল সেক্টরে বিভক্ত হতে পারে; দুটি ছোট dilations এর ইউনিয়ন পছন্দসই ফলাফল দেবে।)
বাস্তবায়ন
কারণ আমরা ইউক্লিডিয়ান গণনা করছি - বিমানে ছড়িয়ে পড়া - আমরা কেবলমাত্র পয়েন্টটি সেই বিন্দুতে অনুবাদ করে কেবল একটি বিন্দু বিভক্ত করতে পারি । (এটি করতে সক্ষম হতে, পাড়ার একটি উত্স প্রয়োজনএটি বেস পয়েন্টের সাথে সামঞ্জস্য করবে। উদাহরণস্বরূপ, এই প্রশ্নের ক্ষেত্রগুলির উত্স হল যে বৃত্ত থেকে তারা গঠিত হয় তার কেন্দ্র। এই উত্সটি সেক্টরের সীমানায় অবস্থিত। স্ট্যান্ডার্ড জিআইএস বাফারিং অপারেশনে পাড়াটি এর কেন্দ্রস্থলে উত্স সহ একটি বৃত্ত; এখন উত্সটি বৃত্তের অভ্যন্তরের মধ্যে রয়েছে। একটি উত্স নির্বাচন করা গণনার ক্ষেত্রে কোনও বড় বিষয় নয়, কারণ উত্সের পরিবর্তনটি কেবল পুরো পাতলা স্থানান্তরিত করে, তবে প্রাকৃতিক ঘটনাকে মডেলিংয়ের ক্ষেত্রে এটি একটি বড় ব্যাপার হতে পারে। sector
কোডে ফাংশন নিচে প্রকাশ কিভাবে একটি উৎপত্তি সুনির্দিষ্ট করা যেতে পারে।)
একটি রেখাংশ বিভাজনকে বিভক্ত করা জটিল হতে পারে তবে উত্তল প্রতিবেশের জন্য আমরা সাবধানতার সাথে নির্বাচিত সমান্তরালামের পাশাপাশি দুটি প্রান্তের পয়েন্টগুলির সংশ্লেষ হিসাবে মিশ্রণটি তৈরি করতে পারি। (স্থানের স্বার্থে আমি এই জাতীয় গাণিতিক দৃ .়তা প্রমাণ করার জন্য বিরতি দেব না, তবে পাঠকদের তাদের নিজস্ব প্রমাণ চেষ্টা করার জন্য উত্সাহিত করব কারণ এটি একটি অন্তর্দৃষ্টিপূর্ণ অনুশীলন।) এখানে তিনটি ক্ষেত্র ব্যবহার করে একটি চিত্রণ দেওয়া হয়েছে (গোলাপী রঙে দেখানো হয়েছে)। তাদের ইউনিট রেডিয়াই রয়েছে এবং তাদের কোণগুলি শিরোনামে দেওয়া হয়েছে। রেখাংশটি নিজেই দৈর্ঘ্য 2, আনুভূমিক এবং কালোতে দেখানো হয়েছে:
Parallelograms গোলাপী পয়েন্ট যে হিসাবে দূরে সম্ভব সেগমেন্ট থেকে এসেছ লোকেটিং দ্বারা পাওয়া যায় শুধুমাত্র উল্লম্ব দিক । এটি দুটি নিম্ন পয়েন্ট এবং সেগমেন্টের সমান্তরাল রেখাগুলির সাথে দুটি উচ্চ পয়েন্ট দেয়। আমাদের কেবলমাত্র চারটি পয়েন্টকে সমান্তরালগ্রামে যোগ করতে হবে (নীল রঙে দেখানো হয়েছে)। লক্ষ্য করুন, ডানদিকে, কীভাবে এটি সেক্টর নিজেই কেবল একটি রেখাংশ (এমনকি সত্য বহুভুজ নয়) হয়ে উঠেছে: সেখানে বিভাগটির প্রতিটি বিন্দু উত্তর পূর্বের 171 ডিগ্রি পূর্বদিকে একটি দুরত্বের জন্য অনুবাদ করা হয়েছে 0 থেকে 1 পর্যন্ত। এই শেষ পয়েন্টগুলির সেটটি সমান্তরালগ্রাম দেখানো। এই গণনার বিবরণ নীচের কোডের buffer
মধ্যে সংজ্ঞায়িত ফাংশনটিতে উপস্থিত হবে dilate.edges
।
একটি পললাইন বিচ্ছিন্ন করতে , আমরা এটি গঠন করে এমন পয়েন্ট এবং বিভাগগুলির বিভাজনের মিলন গঠন করি। dilate.edges
এই লুপটি সম্পাদন করার শেষ দুটি লাইন ।
বহুভুজকে বিস্তৃতকরণের জন্য বহুভুজটির অভ্যন্তরটি এর সীমানার পরাভূতকরণ সহ অন্তর্ভুক্ত করা দরকার। (এই দৃser়তাটি প্রসারণ আশপাশ সম্পর্কে কিছু ধারণা তৈরি করে One একটি হ'ল সমস্ত পাড়াগুলি বিন্দু (0,0) ধারণ করে, যা বহুভুজটিকে তার পচনের মধ্যে অন্তর্ভুক্ত করার গ্যারান্টি দেয় vari পরিবর্তনশীল পাড়াগুলির ক্ষেত্রে এটিও ধরে নিয়েছে যে কোনও অভ্যন্তরের বিভাজন বহুভুজের বিন্দুটি সীমানার পয়েন্টগুলি ছড়িয়ে দেওয়ার বাইরে প্রসারিত হবে না constant ধ্রুবক পাড়াগুলির ক্ষেত্রে এটি case
আসুন এটি কীভাবে কাজ করে তার কয়েকটি উদাহরণ দেখি , প্রথমে একটি নোনগন দিয়ে (বিশদ প্রকাশের জন্য বেছে নেওয়া হয়েছে) এবং তারপরে একটি বৃত্ত দিয়ে (প্রশ্নটির চিত্রটির সাথে মিল রেখে বেছে নেওয়া হয়েছে)। উদাহরণগুলি একই তিনটি পাড়া ব্যবহার করতে থাকবে, তবে 1/3 এর ব্যাসার্ধে সঙ্কুচিত হবে।
এই চিত্রটিতে বহুভুজের অভ্যন্তর ধূসর, বিন্দু বিস্তৃতকরণ (সেক্টর) গোলাপী এবং প্রান্তের ডিলেশন (সমান্তরালোগ্রাজগুলি) নীল।
"চেনাশোনা" সত্যই মাত্র একটি 60-গন, তবে এটি একটি বৃত্তের সাথে সুন্দরভাবে সজ্জিত করে।
কর্মক্ষমতা
যখন বেস বৈশিষ্ট্যটি এন পয়েন্ট এবং মাইল পয়েন্টগুলি এম পয়েন্ট দ্বারা প্রতিনিধিত্ব করা হয়, তখন এই অ্যালগরিদমের জন্য ও (এন এম) প্রচেষ্টা প্রয়োজন। ইউনিয়নে শীর্ষে এবং প্রান্তগুলির জঞ্জাল সরল করে এটি অনুসরণ করতে হবে, যার জন্য হে (এন এম লগ (এন এম)) প্রচেষ্টা প্রয়োজন হতে পারে: এটি জিআইএসকে জিজ্ঞাসা করার জন্য কিছু; আমাদের এটি প্রোগ্রাম করা উচিত নয়।
উত্তল বেস বৈশিষ্ট্যগুলির জন্য কম্পিউটেশনাল প্রয়াসকে ও (এম + এন) এ উন্নত করা যেতে পারে (কারণ আপনি মূল দুটি আকারের সীমানা বর্ণনা করে উল্লম্বগুলির তালিকাগুলি যথাযথভাবে মার্জ করে নতুন সীমানা ঘুরে কীভাবে কাজ করতে পারেন)। এটি পরে কোনও পরিষ্কারের প্রয়োজন হবে না।
যখন বেস বৈশিষ্ট্যটির চারপাশে অগ্রসর হওয়ার সাথে সাথে প্রসারণ পাড়াটি ধীরে ধীরে আকার এবং / বা অরিয়েন্টেশন পরিবর্তিত করে, প্রান্তটির বিস্তৃতিটি এর প্রান্তের সংক্রমণের ইউনিটের উত্তল হাল থেকে নিকটবর্তী হতে পারে। দুটি বিচ্ছিন্ন পাড়ায় যদি এম 1 এবং এম 2 পয়েন্ট থাকে তবে এটি শিউস ও প্রেপারেটায়, কম্পিউটেশনাল জ্যামিতিতে বর্ণিত একটি অ্যালগরিদম ব্যবহার করে ও (এম 1 + এম 2) চেষ্টা করে পাওয়া যাবে । সুতরাং, কে = এম 1 + এম 2 + ... + এম (এন) কে এন প্রসারণ আশেপাশের মোট উল্লম্বের সংখ্যা হতে দেওয়া, আমরা ও (কে * লগ (কে)) সময়ের মধ্যে বিচ্ছিন্নতা গণনা করতে পারি।
আমরা চাই সমস্ত সাধারণ সরল বাফার হলে আমরা কেন এই জাতীয়করণকে মোকাবেলা করতে চাই? পৃথিবীতে বৃহত বৈশিষ্ট্যগুলির জন্য, বাস্তবে ধ্রুব আকারের একটি বিস্তৃতি পাড়া (যেমন একটি ডিস্ক) এর মানচিত্রটিতে এই গণনাগুলি সম্পাদন করা হয় যেখানে বিভিন্ন আকারের হতে পারে। এইভাবে আমরা ইউক্যালিডিয়ান জ্যামিতির সমস্ত সুবিধা উপভোগ করতে থাকায় উপবৃত্তাকারীর জন্য নির্ভুল গণনা করার একটি উপায় অর্জন করি ।
কোড
উদাহরণগুলি এই R
প্রোটোটাইপের সাহায্যে তৈরি হয়েছিল , যা আপনার প্রিয় ভাষায় (পাইথন, সি ++ ইত্যাদি) সহজেই পোর্ট করা যায়। কাঠামোতে এটি এই উত্তরে উল্লিখিত বিশ্লেষণের সাথে সমান্তরাল হয় এবং তাই পৃথক ব্যাখ্যার প্রয়োজন হয় না। মন্তব্যগুলি কিছু বিশদ স্পষ্ট করে।
(এটি লক্ষণীয় আকর্ষণীয় হতে পারে যে ট্রিগনোমেট্রিক গণনাগুলি কেবল উদাহরণ বৈশিষ্ট্যগুলি তৈরি করতে ব্যবহৃত হয় - যা নিয়মিত বহুভুজ - এবং ক্ষেত্রগুলি d
#
# Dilate the vertices of a polygon/polyline by a shape.
#
dilate.points <- function(p, q) {
# Translate a copy of `q` to each vertex of `p`, resulting in a list of polygons.
pieces <- apply(p, 1, function(x) list(t(t(q)+x)))
lapply(pieces, function(z) z[[1]]) # Convert to a list of matrices
}
#
# Dilate the edges of a polygon/polyline `p` by a shape `q`.
# `p` must have at least two rows.
#
dilate.edges <- function(p, q) {
i <- matrix(c(0,-1,1,0), 2, 2) # 90 degree rotation
e <- apply(rbind(p, p[1,]), 2, diff) # Direction vectors of the edges
# Dilate a single edge from `x` to `x+v` into a parallelogram
# bounded by parts of the dilation shape that are at extreme distances
# from the edge.
buffer <- function(x, v) {
y <- q %*% i %*% v # Signed distances orthogonal to the edge
k <- which.min(y) # Find smallest distance, then the largest *after* it
l <- (which.max(c(y[-(1:k)], y[1:k])) + k-1) %% length(y)[1] + 1
list(rbind(x+q[k,], x+v+q[k,], x+v+q[l,], x+q[l,])) # A parallelogram
}
# Apply `buffer` to every edge.
quads <- apply(cbind(p, e), 1, function(x) buffer(x[1:2], x[3:4]))
lapply(quads, function(z) z[[1]]) # Convert to a list of matrices
}
#----------------------- (This ends the dilation code.) --------------------------#
#
# Display a polygon and its point and edge dilations.
# NB: In practice we would submit the polygon, its point dilations, and edge
# dilations to the GIS to create and simplify their union, producing a single
# polygon. We keep the three parts separate here in order to illustrate how
# that polygon is constructed.
#
display <- function(p, d.points, d.edges, ...) {
# Create a plotting region covering the extent of the dilated figure.
x <- c(p[,1], unlist(lapply(c(d.points, d.edges), function(x) x[,1])))
y <- c(p[,2], unlist(lapply(c(d.points, d.edges), function(x) x[,2])))
plot(c(min(x),max(x)), c(min(y),max(y)), type="n", asp=1, xlab="x", ylab="y", ...)
# The polygon itself.
polygon(p, density=-1, col="#00000040")
# The dilated points and edges.
plot.list <- function(l, c) lapply(l, function(p)
polygon(p, density=-1, col=c, border="#00000040"))
plot.list(d.points, "#ff000020")
plot.list(d.edges, "#0000ff20")
invisible(NULL) # Doesn't return anything
}
#
# Create a sector of a circle.
# `n` is the number of vertices to use for approximating its outer arc.
#
sector <- function(radius, arg1, arg2, n=1, origin=c(0,0)) {
t(cbind(origin, radius*sapply(seq(arg1, arg2, length.out=n),
function(a) c(cos(a), sin(a)))))
}
#
# Create a polygon represented as an array of rows.
#
n.vertices <- 60 # Inscribes an `n.vertices`-gon in the unit circle.
angles <- seq(2*pi, 0, length.out=n.vertices+1)
angles <- angles[-(n.vertices+1)]
polygon.the <- cbind(cos(angles), sin(angles))
if (n.vertices==1) polygon.the <- rbind(polygon.the, polygon.the)
#
# Dilate the polygon in various ways to illustrate.
#
system.time({
radius <- 1/3
par(mfrow=c(1,3))
q <- sector(radius, pi/12, 2*pi/3, n=120)
d.points <- dilate.points(polygon.the, q)
d.edges <- dilate.edges(polygon.the, q)
display(polygon.the, d.points, d.edges, main="-30 to 75 degrees")
q <- sector(radius, pi/3, 4*pi/3, n=180)
d.points <- dilate.points(polygon.the, q)
d.edges <- dilate.edges(polygon.the, q)
display(polygon.the, d.points, d.edges, main="-150 to 30 degrees")
q <- sector(radius, -9/20*pi, -9/20*pi)
d.points <- dilate.points(polygon.the, q)
d.edges <- dilate.edges(polygon.the, q)
display(polygon.the, d.points, d.edges, main="171 degrees")
})
এন = 60 এবং এম = 121 (বাম), এম = 181 (মাঝারি) এবং এম = 2 (ডান) সহ এই উদাহরণটির (শেষ চিত্র থেকে) গণনার সময় ছিল এক চতুর্থাংশ দ্বিতীয়। তবে এর বেশিরভাগটি ছিল প্রদর্শনের জন্য। সাধারণত, এই R
কোডটি প্রতি সেকেন্ডে প্রায় এন এম = 1.5 মিলিয়ন হ্যান্ডেল করবে (দেখানো সমস্ত উদাহরণ গণনা করার জন্য মাত্র 0.002 সেকেন্ড বা তার বেশি সময় নেয়)। তবুও, এম এন প্রোডাক্টটির উপস্থিতি বিশদ প্রতিবেশের মাধ্যমে অনেকগুলি চিত্র বা জটিল পরিসংখ্যানগুলির সংক্রমণকে বোঝায় যা যথেষ্ট সময় নিতে পারে, তাই সাবধান! বড় সমস্যা মোকাবেলার আগে ছোট সমস্যার জন্য সময় নির্ধারণ করুন ch এই পরিস্থিতিতে কেউ একজন রাস্টার-ভিত্তিক সমাধানের দিকে নজর রাখতে পারে (যা বাস্তবায়নের পক্ষে আরও সহজ, মূলত কেবল একক প্রতিবেশী গণনার প্রয়োজন ulation)