JavaScriptで多角形(ポリゴン)の各辺の中点を求める方法
次のような、配列の中に配列が入った2次元配列があるとします。
const arr = [ [-73.9280684530257, 40.8099975343718], [-73.9282820374729, 40.8100875554645], [-73.9280124002104, 40.8103130893677], [-73.927875543761, 40.8102554080229], [-73.9280684530257, 40.8099975343718] ];
この例では、各サブ配列が2次元平面上の1つの点を表しており、その点は多角形(ポリゴン)の頂点に相当します。多角形の辺の数 n は、入力配列に含まれるサブ配列の数と一致します。
ここで求めたいのは、このような配列を受け取り、多角形の対応する各辺の中点を表す n 個のサブ配列からなる新しい配列を返すJavaScript関数です。
実装例
コードは以下のように記述できます。
const arr = [
[-73.9280684530257, 40.8099975343718],
[-73.9282820374729, 40.8100875554645],
[-73.9280124002104, 40.8103130893677],
[-73.927875543761, 40.8102554080229],
[-73.9280684530257, 40.8099975343718]
];
const findCenters = arr => {
const centerArray = [];
for (let i = 0; i < arr.length; i++) {
// 剰余演算子で最後の頂点と最初の頂点をつなぐ辺にも対応
const nextIndex = (i + 1) % arr.length;
centerArray[i] = [];
centerArray[i][0] = (arr[i][0] + arr[nextIndex][0]) / 2;
centerArray[i][1] = (arr[i][1] + arr[nextIndex][1]) / 2;
}
return centerArray;
};
console.log(findCenters(arr));コードの解説
この関数の仕組みは以下の通りです。
- ループ変数
iを使って、現在処理している頂点を順番にたどります。 - 剰余演算子
%でnextIndexを計算することにより、最後の頂点と最初の頂点を結ぶ辺も自動的に処理できます。これにより、閉じた多角形のすべての辺を漏れなくカバーできます。 - 隣接する2つの頂点のx座標・y座標それぞれの平均値を計算すれば、その辺の中点が求まります。計算結果は
centerArrayに格納していきます。
なお、元のコードではループ変数や nextIndex の宣言が省略されていましたが、意図しないグローバル変数の生成を防ぐため、let や const による明示的な宣言を推奨します。
出力結果
コンソールには次のように出力されます。
[ [ -73.92817524524929, 40.81004254491815 ], [ -73.92814721884164, 40.8102003224161 ], [ -73.92794397198571, 40.8102842486953 ], [ -73.92797199839336, 40.81012647119735 ], [ -73.9280684530257, 40.8099975343718 ] ]
出力を見ると、最後の要素は最初の頂点と最後の頂点(同じ座標)をつなぐ辺の中点として計算されていることがわかります。この手法は地図アプリケーションでのジオフェンス表示や、図形描画ライブラリでのラベル配置など、地理座標を扱うさまざまな場面で応用できます。
-
【JavaScript入門】Symbolを使ってオブジェクトごとに一意のIDを作成する方法
はじめにJavaScriptでオブジェクトごとに一意のIDを作成したい場合、Symbol()を使うのが最も簡単かつ確実な方法です。Symbolは呼び出されるたびに必ず新しい一意の値を生成するため、たとえ同じ説明文字列を渡しても、二度と同じ値にはなりません。以下は、各オブジェクトに対して一意のIDを作成するサンプルコードです。実装例<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewp
-
JavaScriptで連結リストの各ノードの「次に大きい値」を効率的に求める方法
問題概要JavaScriptで、連結リストの先頭ノード(head)を唯一の引数として受け取る関数を作成することを考えます。この連結リストには数値データが格納されており、リスト内の各ノードには「次に大きい値(next larger value)」が存在する場合があります。ノードiに対して next_larger(node_i) とは、j > i かつ node_j.val > node_i.val を満たすノードの中で、j が最小になるような node_j.val のことです。そのような j が存在しない場合、次に大きい値は 0 となります。つまり私たちの関数は、リスト内の各要素に対