Maison interface Web Tutoriel H5 Comment dessiner un polygone basé sur des points aléatoires dans le canevas

Comment dessiner un polygone basé sur des points aléatoires dans le canevas

Jun 14, 2018 am 09:19 AM
canvas 多边形 绘制

Cet article présente principalement les informations pertinentes sur la façon de dessiner un polygone basé sur des points aléatoires dans le canevas. Le contenu est assez bon, je vais le partager avec vous maintenant et le donner comme référence.

Cause

Quand j'étudiais le livre "HTML5+Javascript Animation Basics" aujourd'hui, j'en ai parlé dans la troisième section du chapitre 8 Apprenez à utiliser trois ressorts pour relier trois points afin d'effectuer des exercices d'étirement.

Après avoir terminé l'exemple, j'ai réfléchi à ce qui se passerait si c'était quatre points ou cinq points.

J'ai réécrit le code pour rendre le nombre de points variable. L'effet final est de réaliser le mouvement d'étirement final de chaque point pour équilibrer, mais les connexions entre les points ne sont pas très belles, et certaines sont croisées.

J'ai donc réfléchi à la possibilité d'optimiser cette zone.

Faites pivoter la connexion

Les points de l'exemple précédent sont tous dans des positions aléatoires, la connexion est donc incontrôlable. Je veux donc commencer par cela en premier.

Utilisez d'abord un certain point comme point de référence pour obtenir les angles d'autres points par rapport à ce point.

Connectez ensuite ces points selon l'angle du petit au grand, afin de pouvoir dessiner un polygone normal.

Le code approximatif d'implémentation est le suivant :

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
})
Copier après la connexion

De cette façon, lorsque la connexion est tracée à la fin, le tableau peut être parcouru du petit au grand angle Venez dessiner.

L'effet est le suivant :

Cela peut réduire considérablement le nombre de lignes qui se croisent, mais cela ne peut toujours pas être complètement évité.

Ensuite, je veux essayer d'optimiser cette solution, par exemple en utilisant Math.abs pour corriger l'angle, ou en trouvant le point avec le plus petit angle pour relier chaque point. Mais le résultat n’est pas bon, il est impossible d’éviter de franchir les lignes.

Rotation basée sur le point central

J'ai pensé à une autre idée plus tard. Si le point central du polygone peut être déterminé, alors calculez. les positions relatives de tous les points par rapport au centre séparément. L'angle entre les points peut être utilisé pour relier ces points dans le sens des aiguilles d'une montre ou dans le sens inverse.

Mais après de longues recherches sur Internet, tous les algorithmes de points nécessitent une série de points disposés dans un certain ordre dans le sens des aiguilles d'une montre.

Mais si j'ai ces points, je peux déjà dessiner un polygone. J'ai dû abandonner

Segmentation bipolaire sur l'axe X

En désespoir de cause, j'ai dû faire une recherche sur Google, puis j'ai trouvé un réponse sur Zhihu qui était plutôt bonne : Comment connecter un ensemble non ordonné de points sur le plan en un simple polygone ?

Pour la description spécifique de l'algorithme, regardez simplement la réponse et je n'entrerai pas dans les détails.

Cependant, lors de la connexion de la chaîne supérieure et de la chaîne inférieure, il vous suffit de vous assurer que la chaîne supérieure est connectée par ordre décroissant sur l'axe X et que la chaîne inférieure est connectée par ordre croissant sur l'axe X ( dessiné dans le sens inverse des aiguilles d’une montre). Quant aux points ayant le même axe X, peu importe que l’axe Y soit plus grand ou plus petit.

Une fois implémenté, il est implémenté strictement selon l'algorithme de la réponse.

Pour juger si un point appartient à la chaîne supérieure ou à la chaîne inférieure, l'idée initiale est de déterminer l'équation fonctionnelle de la ligne droite basée sur deux points, puis d'introduire les coordonnées des points pour le calcul. Mais plus tard, j'ai pensé que tous les points utilisaient le pôle le plus à gauche pour calculer l'angle oblique, puis le divisons en fonction de la taille de l'angle, ce qui est plus facile à comprendre visuellement.

Le code approximatif est le suivant :

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
})
Copier après la connexion

Les boules finalement rendues sont les points du polygone triés dans le sens inverse des aiguilles d'une montre.

L'effet est le suivant :

L'état interne de chaque balle est le suivant :

Ce qui précède est le résumé de cet article. Tout le contenu, j'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois !

Recommandations associées :

Utilisez html5 Canvas encapsule un diagramme circulaire que les echarts ne peuvent pas implémenter

HTML5 Canvas implémente la méthode de dessin des courbes

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Le plan d'étage peut-il être dessiné directement dans un ppt architectural ? Le plan d'étage peut-il être dessiné directement dans un ppt architectural ? Mar 20, 2024 am 08:43 AM

ppt est largement utilisé dans de nombreux domaines et travaux, notamment dans l'éducation, l'architecture, etc. Lorsqu'il s'agit de ppt d'architecture, il faut d'abord penser à la présentation de certains dessins d'architecture. Si l'on n'utilise pas de logiciel de dessin professionnel, peut-on dessiner directement un plan architectural simple ? En fait, nous pouvons terminer l'opération ici. Ci-dessous, nous allons dessiner un plan d'étage relativement simple pour vous donner une idée. J'espère que vous pourrez réaliser de meilleurs dessins de plan d'étage basés sur cette idée. 1. Tout d’abord, nous double-cliquons pour ouvrir le logiciel ppt sur le bureau et cliquons pour créer un nouveau document de présentation vierge. 2. Nous trouvons Insérer → Forme → Rectangle dans la barre de menu. 3. Après avoir dessiné le rectangle, double-cliquez sur le graphique et modifiez le type de couleur de remplissage. Ici, nous pouvons modifier.

nombre heptagonal nombre heptagonal Sep 24, 2023 am 10:33 AM

Un nombre heptagonal est un nombre qui peut être représenté comme un heptagone. Un heptagone est un polygone à 7 côtés. Un nombre heptagonal peut être représenté comme une combinaison de couches successives d'heptagone (polygone à 7 côtés). donc,

Comment dessiner une carte géographique 3D avec Python Comment dessiner une carte géographique 3D avec Python Sep 28, 2023 am 10:19 AM

Présentation de la façon de dessiner des cartes géographiques 3D avec Python : dessiner des cartes géographiques 3D peut nous aider à comprendre les données géographiques et la distribution spatiale de manière plus intuitive. Python, en tant que langage de programmation puissant et facile à utiliser, fournit de nombreuses bibliothèques et outils pour dessiner différents types de cartes géographiques. Dans cet article, nous apprendrons comment dessiner des cartes géographiques 3D à l'aide du langage de programmation Python et de certaines bibliothèques populaires telles que Matplotlib et Basemap. Préparation de l'environnement : avant de commencer, nous devons nous assurer

Apprenez à dessiner des dendrogrammes et des graphiques radar en Python en cinq minutes Apprenez à dessiner des dendrogrammes et des graphiques radar en Python en cinq minutes Sep 27, 2023 pm 12:48 PM

Apprenez à dessiner des dendrogrammes et des graphiques radar avec Python en cinq minutes. Dans la visualisation de données, les dendrogrammes et les graphiques radar sont deux formes de graphiques couramment utilisées. Les arborescences sont utilisées pour afficher les structures hiérarchiques, tandis que les graphiques radar sont utilisés pour comparer les données sur plusieurs dimensions. Cet article expliquera comment dessiner ces deux graphiques à l'aide de Python et fournira des exemples de code spécifiques. 1. Dessiner des dendrogrammes Il existe plusieurs bibliothèques en Python qui peuvent être utilisées pour dessiner des dendrogrammes, telles que matplotlib et graphviz. Ce qui suit utilise la bibliothèque matplotlib comme exemple pour démontrer

Apprenez le cadre de canevas et expliquez en détail le cadre de canevas couramment utilisé Apprenez le cadre de canevas et expliquez en détail le cadre de canevas couramment utilisé Jan 17, 2024 am 11:03 AM

Explorez le framework Canvas : Pour comprendre quels sont les frameworks Canvas couramment utilisés, des exemples de code spécifiques sont nécessaires. Introduction : Canvas est une API de dessin fournie en HTML5, grâce à laquelle nous pouvons obtenir des graphiques et des effets d'animation riches. Afin d'améliorer l'efficacité et la commodité du dessin, de nombreux développeurs ont développé différents frameworks Canvas. Cet article présentera certains frameworks Canvas couramment utilisés et fournira des exemples de code spécifiques pour aider les lecteurs à mieux comprendre comment utiliser ces frameworks. 1.Cadre EaselJSEa

Quelles versions de html2canvas existe-t-il ? Quelles versions de html2canvas existe-t-il ? Aug 22, 2023 pm 05:58 PM

Les versions de html2canvas incluent html2canvas v0.x, html2canvas v1.x, etc. Introduction détaillée : 1. html2canvas v0.x, qui est une première version de html2canvas. La dernière version stable est la v0.5.0-alpha1. Il s'agit d'une version mature qui a été largement utilisée et vérifiée dans de nombreux projets ; 2. html2canvas v1.x, il s'agit d'une nouvelle version de html2canvas.

uniapp implémente comment utiliser Canvas pour dessiner des graphiques et des effets d'animation uniapp implémente comment utiliser Canvas pour dessiner des graphiques et des effets d'animation Oct 18, 2023 am 10:42 AM

Comment utiliser Canvas pour dessiner des graphiques et des effets d'animation dans Uniapp nécessite des exemples de code spécifiques 1. Introduction Avec la popularité des appareils mobiles, de plus en plus d'applications doivent afficher divers graphiques et effets d'animation sur le terminal mobile. En tant que framework de développement multiplateforme basé sur Vue.js, uniapp offre la possibilité d'utiliser un canevas pour dessiner des graphiques et des effets d'animation. Cet article présentera comment Uniapp utilise Canvas pour obtenir des effets de graphique et d'animation, et donnera des exemples de code spécifiques. 2. toile

Comment dessiner des graphiques animés avec Python Comment dessiner des graphiques animés avec Python Sep 27, 2023 am 09:53 AM

Comment dessiner des graphiques animés avec Python Python est un langage de programmation puissant qui peut être utilisé pour diverses visualisations de données et dessins de graphiques. Parmi eux, dessiner des graphiques animés peut rendre les données plus vivantes et intéressantes. Cet article explique comment utiliser Python pour dessiner des graphiques animés et fournit des exemples de code spécifiques. Tout d’abord, nous devons installer la bibliothèque matplotlib, qui est l’une des bibliothèques de graphiques les plus couramment utilisées en Python. Exécutez la commande suivante dans le terminal pour installer matplotlib : pipinsta

See all articles