찾다
웹 프론트엔드H5 튜토리얼캔버스의 임의의 점을 기반으로 다각형을 그리는 방법

이 글은 캔버스의 임의의 점을 기반으로 다각형을 그리는 방법에 대한 관련 정보를 주로 소개합니다. 내용이 꽤 좋아서 지금 공유하고 참고하겠습니다.

Cause

오늘 "HTML5+Javascript Animation Basics" 책을 공부하던 중 8장 3절에서 세 개의 스프링을 이용해 세 점을 연결해 스트레칭 동작을 하는 방법에 대해 이야기했습니다.

예시를 마치고 4점, 5점이면 어떨까 생각해봤습니다.

코드를 다시 작성하고 포인트 개수를 가변적으로 만들었습니다. 최종 효과는 균형을 맞추기 위해 각 점의 최종 스트레칭 동작을 달성하는 것이지만 점 사이의 연결이 그다지 좋지 않고 일부가 교차됩니다.

그래서 이 부분을 최적화할 수 있지 않을까 생각해봤습니다.

연결 회전

이전 예의 포인트는 모두 임의의 위치에 있으므로 연결을 제어할 수 없습니다. 그래서 저는 이것부터 먼저 시작하고 싶습니다.

먼저 특정 점을 기준점으로 사용하여 이 점을 기준으로 하는 다른 점의 각도를 구합니다.

그런 다음 작은 각도에서 큰 각도에 따라 이 점들을 연결하면 일반 다각형을 그릴 수 있습니다.

대략적인 구현 코드는 다음과 같습니다.

let balls = [];
let ballNum = 6;
let firstBall = null;
while(ballNum--) {
  let ball = new Ball(20, parseColor(Math.random() * 0xffffff))
  ball.x = Math.random() * width;
  ball.y = Math.random() * height;
  balls.push(ball)

  if (!firstBall) {
    firstBall = ball
    ball.angle = 0
  } else {
    const dx = ball.x - firstBall.x,
          dy = ball.y - firstBall.y;

    ball.angle = Math.atan2(dy, dx);
  }
}

// 尝试让球连线是一个正多边形
balls = balls.sort((ballA, ballB) => {
  return ballA.angle - ballB.angle
})

이렇게 하면 마지막에 연결을 그릴 때 배열을 가로질러 작은 각도에서 큰 각도로 그릴 수 있습니다.

효과는 다음과 같습니다.

이를 통해 선을 넘는 상황을 크게 줄일 수 있지만 여전히 완전히 피할 수는 없습니다.

다음으로 Math.abs를 사용하여 각도를 수정하거나 각 점을 연결하기 위해 가장 작은 각도의 점을 찾는 등 이 솔루션을 최적화하려고 합니다. 하지만 결과는 좋지 않고, 선을 넘는 것도 피할 수 없습니다.

중심점을 기준으로 회전

나중에 또 다른 아이디어가 떠올랐습니다. 다각형의 중심점이 결정되면 중심점을 기준으로 모든 점의 각도를 별도로 계산할 수 있습니다. 포인트는 시계 방향 또는 시계 반대 방향으로 연결될 수 있습니다.

하지만 인터넷에서 오랫동안 검색한 결과 모든 포인트 알고리즘에는 특정 시계 방향 순서로 배열된 일련의 포인트가 필요합니다.

하지만 이 점이 있으면 이미 다각형을 그릴 수 있습니다.

X축 극 분할

을 포기해야 했습니다. 절망에 빠져 Google을 검색하다가 Zhihu에서 좋은 답변을 찾았습니다. 평면 위의 정렬되지 않은 점 집합을 연결하는 방법 단순한 다각형?

구체적인 알고리즘 설명은 답변만 참고하시면 됩니다. 자세한 내용은 다루지 않겠습니다.

단, 상부 체인과 하부 체인을 연결할 때 실제로는 상부 체인이 X축을 기준으로 내림차순으로 연결되고, 하부 체인이 X축을 기준으로 오름차순으로 연결되어 있는지 확인하기만 하면 됩니다( 시계 반대 방향으로 그려집니다.) X축이 동일한 점의 경우 Y축이 더 크거나 작은지는 중요하지 않습니다.

구현 시 답변에 나온 알고리즘에 따라 엄격하게 구현됩니다.

한 점이 상위 체인에 속하는지 하위 체인에 속하는지 판단할 때 가장 먼저 생각해야 할 것은 두 점을 기준으로 직선의 함수 방정식을 결정한 다음 계산할 점의 좌표를 도입하는 것입니다. 그런데 나중에 생각해보니 모든 점은 가장 왼쪽 극을 이용해서 경사각을 계산한 뒤 이를 각도 크기에 따라 나누는 게 시각적으로 이해하기 쉽더라고요.

대략적인 코드는 다음과 같습니다.

let balls = [];
let tempBalls = [];
let ballNum = 6;
let isDragingBall = false;

while(ballNum--) {
  let ball = new Ball(10, parseColor(Math.random() * 0xffffff))
  ball.x = Math.random() * width;
  ball.y = Math.random() * height;
  tempBalls.push(ball)
}

// 让点按X轴升序排序
tempBalls = tempBalls.sort((ballA, ballB) => {
  return ballA.x - ballB.x
})

// 找X轴左右极点
let firstBall = tempBalls[0],
    lastBall = tempBalls[tempBalls.length -1];
let smallXBalls = tempBalls.filter(ball => ball.x === firstBall.x),
    bigXBalls = tempBalls.filter(ball => ball.x === lastBall.x)

// 处理左右极点有多个的情况
if (smallXBalls.length > 1) {
  smallXBalls.sort((ballA, ballB) => {
    return ballB.y - ballA.y
  })
}
if (bigXBalls.length > 1) {
  bigXBalls.sort((ballA, ballB) => {
    return ballB.y - ballA.y
  })
}

firstBall = smallXBalls[0]
lastBall = bigXBalls[0]

// 获得极点连线的角度
let splitLineAngle = Math.atan2(lastBall.y - firstBall.y, lastBall.x - firstBall.x);
let upperBalls = [],
    lowerBalls = [];

// 所有其他点跟firstBall计算角度
// 大于splitLineAngle的都是下链
// 其他是上链
tempBalls.forEach(ball => {
  if (ball === firstBall || ball === lastBall) {
    return false
  }
  let angle = Math.atan2(ball.y - firstBall.y, ball.x - firstBall.x);
  if (angle > splitLineAngle) {
    lowerBalls.push(ball)
  } else {
    upperBalls.push(ball)
  }
})

// 处理X轴相同情况的排序
lowerBalls = lowerBalls.sort((ballA, ballB) => {
  if (ballA.x !== ballB.x) {
    return ballA.x - ballB.x
  }
  return ballB.y - ballA.y
})

upperBalls = upperBalls.sort((ballA, ballB) => {
  if (ballA.x !== ballB.x) {
    return ballB.x - ballA.x
  }
  return ballB.y - ballB.x
})

// 逆时针连接所有的点
balls = [firstBall].concat(lowerBalls, [lastBall], upperBalls)

balls = balls.map((ball, i) => {
  ball.text = i + 1;
  return ball
})

드디어 반환된 공은 시계 반대 방향으로 정렬된 다각형의 점입니다.

효과는 다음과 같습니다.

각 공의 내부 상태는 다음과 같습니다.

위 내용은 모두의 학습에 도움이 되기를 바랍니다. 관련 내용은 PHP 중국어 웹사이트를 주목해주세요!

관련 권장사항:

html5 사용 Canvas는 echart가 구현할 수 없는 원형 차트를 캡슐화합니다

HTML5 Canvas는 곡선을 그리는 방법을 구현합니다

위 내용은 캔버스의 임의의 점을 기반으로 다각형을 그리는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
H5 : 웹에서 사용자 경험을 향상시키는 방법H5 : 웹에서 사용자 경험을 향상시키는 방법Apr 19, 2025 am 12:08 AM

H5는 멀티미디어 지원, 오프라인 스토리지 및 성능 최적화로 웹 사용자 경험을 향상시킵니다. 1) 멀티미디어 지원 : H5 및 요소는 개발을 단순화하고 사용자 경험을 향상시킵니다. 2) 오프라인 스토리지 : WebStorage 및 IndexedDB는 오프라인으로 사용하여 경험을 향상시킵니다. 3) 성능 최적화 : 웹 워즈 및 요소는 성능을 최적화하여 대역폭 소비를 줄입니다.

H5 코드 해체 : 태그, 요소 및 속성H5 코드 해체 : 태그, 요소 및 속성Apr 18, 2025 am 12:06 AM

HTML5 코드는 태그, 요소 및 속성으로 구성됩니다. 1. 태그는 컨텐츠 유형을 정의하고 다음과 같은 각도 브래킷으로 둘러싸여 있습니다. 2. 요소는 컨텐츠와 같은 시작 태그, 내용 및 엔드 태그로 구성됩니다. 3. 속성 시작 태그에서 키 값 쌍을 정의하고 기능을 향상시킵니다. 웹 구조를 구축하기위한 기본 단위입니다.

H5 코드 이해 : HTML5의 기본 사항H5 코드 이해 : HTML5의 기본 사항Apr 17, 2025 am 12:08 AM

HTML5는 현대적인 웹 페이지를 구축하는 핵심 기술로 많은 새로운 요소와 기능을 제공합니다. 1. HTML5는 웹 페이지 구조 및 SEO를 향상시키는 의미 론적 요소를 소개합니다. 2. 멀티미디어 요소를 지원하고 플러그인없이 미디어를 포함시킵니다. 3. 양식은 새로운 입력 유형 및 검증 속성을 향상시켜 검증 프로세스를 단순화합니다. 4. 웹 페이지 성능 및 사용자 경험을 향상시키기 위해 오프라인 및 로컬 스토리지 기능을 제공합니다.

H5 코드 : 웹 개발자를위한 모범 사례H5 코드 : 웹 개발자를위한 모범 사례Apr 16, 2025 am 12:14 AM

H5 코드에 대한 모범 사례는 다음과 같습니다. 1. 올바른 문서 선언 및 문자 인코딩 사용; 2. 시맨틱 태그를 사용하십시오. 3. HTTP 요청을 줄입니다. 4. 비동기 부하 사용; 5. 이미지 최적화. 이러한 관행은 웹 페이지의 효율성, 유지 관리 및 사용자 경험을 향상시킬 수 있습니다.

H5 : 웹 표준 및 기술의 발전H5 : 웹 표준 및 기술의 발전Apr 15, 2025 am 12:12 AM

웹 표준과 기술은 현재까지 HTML4, CSS2 및 간단한 JavaScript에서 발전했으며 중대한 개발을 거쳤습니다. 1) HTML5는 캔버스 및 웹 스토리지와 같은 API를 도입하여 웹 응용 프로그램의 복잡성과 상호 작용을 향상시킵니다. 2) CSS3은 애니메이션 및 전환 기능을 추가하여 페이지를보다 효과적으로 만듭니다. 3) JavaScript는 화살표 기능 및 클래스와 같은 Node.js 및 ES6의 최신 구문을 통해 개발 효율 및 코드 가독성을 향상시킵니다. 이러한 변경으로 인해 웹 애플리케이션의 성능 최적화 및 모범 사례의 개발이 촉진되었습니다.

H5는 HTML5의 속기입니까? 세부 사항을 탐색합니다H5는 HTML5의 속기입니까? 세부 사항을 탐색합니다Apr 14, 2025 am 12:05 AM

H5는 HTML5의 약어 일뿐 만 아니라 더 넓은 현대 웹 개발 기술 생태계를 나타냅니다. 1. H5는 HTML5, CSS3, JavaScript 및 관련 API 및 기술을 포함합니다. 2. 그것은 더 풍부하고 대화식이며 부드러운 사용자 경험을 제공하며 여러 장치에서 원활하게 실행할 수 있습니다. 3. H5 기술 스택을 사용하여 반응 형 웹 페이지와 복잡한 대화식 기능을 만들 수 있습니다.

H5 및 HTML5 : 웹 개발에 일반적으로 사용되는 용어H5 및 HTML5 : 웹 개발에 일반적으로 사용되는 용어Apr 13, 2025 am 12:01 AM

H5 및 HTML5는 동일한 것을, 즉 html5를 나타냅니다. HTML5는 HTML의 다섯 번째 버전으로 시맨틱 태그, 멀티미디어 지원, 캔버스 및 그래픽, 오프라인 스토리지 및 로컬 스토리지와 같은 새로운 기능을 제공하여 웹 페이지의 표현성 및 상호 작용성을 향상시킵니다.

H5는 무엇을 언급합니까? 맥락 탐색H5는 무엇을 언급합니까? 맥락 탐색Apr 12, 2025 am 12:03 AM

h5referstohtml5, apivotaltechnologyinwebdevelopment.1) html5introducesnewelements 및 dynamicwebapplications.2) itsupp ortsmultimediawithoutplugins, enovannangeserexperienceacrossdevices.3) SemanticLementsImproveContentsTructUreAndSeo.4) H5'Srespo

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

mPDF

mPDF

mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구