[F#] 귀갑을 찢는 게으른 설치
구체적으로'어떤 다각형의 임의적인 위치에 대해 다각형을 구성하는 변에서 가장 가까운 변에 속하도록 다각형을 각 변의 지배구역으로 분할한다'는 문제다.
계산하면 각 변에 2등분선을 긋지만 다각형이 복잡하면 고민이다.
그래서 이번에 우리는 다각형을 그물 모양으로 나누어 각 변의 거리를 계산하여 구역을 나누는 알고리즘을 게으름 피우게 만들었다.
처리 프로그램
다음 다각형을 고려합니다.
이것을 덮을 수 있는 그물 모양을 만들어라.
망상물의 중심이 다각형 안에 있는 대상만을 대상으로 한다.
각 망상물과 다각형의 각 변의 거리를 계산하여 최소 거리의 변과 같은 색깔로 착색하고 구역을 구분한다.
결과적으로 기하학적 영역의 분할은 약간 힘에 의존했다.
해설
한 걸음 한 걸음 쫓아가면 별일 아니지만, 수학 지식을 많이 잊어버려 고전한다.
아래의 알고리즘을 쓸 수 있다면 간단하게 실현할 수 있다.
2 중학교나 고등학교의 수학 문제가 될 것 같아 어렵지 않지만, 나는 거의 기억하지 못하고 고전했다.
최종적으로 다음과 같은 내용을 참고하였다.
먼저 어떤 망상물이 다각형에 포함되는지 판단한다.
실현은 다음과 같다.
(**
ポリゴンに対して指定の点が内包されるか
*)
let isInternal (points : (float * float) array) (x : float, y : float) =
// ポリゴンを構成する点から線分を取得する
// 最後の線分はインデックス0と接続するため、
// 剰余算を用いる
let polyLines =
[| 0 .. points.Length - 1 |]
|> Array.map (fun i ->
let p1 = points.[(i ) % points.Length]
let p2 = points.[(i + 1) % points.Length]
(p1, p2)
)
polyLines
// c点からの(1,0)方向の水平線と
// ポリゴン各辺の交点を持つ辺のみ抽出する
|> Array.filter (fun ((x1, y1), (x2, y2)) ->
let (vx, vy) = (x2 - x1, y2 - y1)
// 水平線と交点を持つ=y座標が一致するということなので
// そのときのベクトル倍率を計算する
let t = (y - y1) / vy
let cx = x1 + t * vx
let cy = y1 + t * vy
let minY = [ y1; y2 ] |> List.min
let maxY = [ y1; y2 ] |> List.max
x <= cx && // 左側で交差する場合は除く
minY <= y && y <= maxY // 線分外で交差する場合は除く
)
// 交点が奇数なら内側
|> Array.length
|> fun count -> count % 2 = 1
점과 직선의 거리를 계산하면 다음과 같다.
(**
直線ABに対するC点を通る垂線の交点座標
*)
let verticalCrossPoint (pointA : (float * float), pointB : (float * float))
(pointC : float * float) =
let (ax, ay) = pointA
let (bx, by) = pointB
let (cx, cy) = pointC
let (abx, aby) = ((bx - ax), (by - ay))
let (acx, acy) = ((cx - ax), (cy - ay))
let t = (abx * acx + aby * acy) / (abx ** 2.0 + aby ** 2.0)
(ax + t * abx, ay + t * aby)
(**
直線ABと点Cの距離
*)
let distance (pointA : (float * float), pointB : (float * float))
(pointC : float * float) =
let (cx, cy) = pointC
let (px, py) = verticalCrossPoint (pointA, pointB) pointC
((px - cx) ** 2.0 + (py - cy) ** 2.0) ** 0.5
그리고 이 색깔들을 조합해서 가장 가까운 격자 가장자리에 같은 색을 칠하는 것이 최초로 붙인 그림이다.그림은 SVG가 다음과 같은 방법으로 만든 것이다.
이번에 우리는 기하학적 계산으로 구역 분할을 시험해 보려고 한다.
Reference
이 문제에 관하여([F#] 귀갑을 찢는 게으른 설치), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/sos/articles/c377b02e754286텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)