Suite

Est-ce que quelqu'un connaît une fonction pour déterminer si un point se trouve sur une polyligne ?


ArcEngine 10 .Net 4 c#

J'autorise actuellement l'utilisateur à sélectionner un point sur une polyligne et à créer un point sur la ligne. J'utilise l'outil de capture.

Je veux juste m'assurer que lorsque l'utilisateur clique sur l'écran, le retour de point que je reçois se trouve au-dessus de la polyligne.

Je me demandais s'il existait une méthode permettant de vérifier si l'IPOINT est sur l'une des polylignes du calque polyligne.


Il y a probablement un moyen plus simple de le faire, mais c'est ce que je fais.

//couche est la couche que vous vérifiez ESRI.ArcGIS.Carto.IIdentifyidentifier1 = couche comme IIdentify; //idGeo est IGeometry que vous souhaitez interroger - dans votre cas un point, mais j'utilise un carré ici IArray array = identifier1.Identify(idGeo); if (array != null) { object obj = array.get_Element(0); IFeatureIdentifyObj fobj = obj as IFeatureIdentifyObj; IRowIdentifyObject irow = fobj as IRowIdentifyObject; Fonctionnalité IFeature = irow.Row as IFeature ; IGéométrie géométrie1 = feature.Shape; IPointCollection pc = géométrie1 comme IPointCollection ; if(pc != null && pc.PointCount > 0) //alors c'est une polyligne }

Vous pouvez probablement utiliser l'interface iHitTest pour cela. http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#//002m0000021v000000

Je n'utilise que VB donc je n'ai pas d'exemple sous la main. Voici un exemple de version 9.3 : http://resources.esri.com/help/9.3/ArcGISEngine/arcobjects/esriGeometry/IHittest_HitTest_Example.htm


Si vous utilisez arcgis, créez simplement une nouvelle couche de topologie, définissez la règle car les points sont couverts par une ligne, puis l'outil de topologie validera les données que vous avez fournies et affichera les erreurs s'il y en a une


Pour déterminer de quel côté de la ligne de $A=(x_1,y_1)$ à $B=(x_2,y_2)$ tombe un point $P=(x,y)$, vous devez calculer la valeur :- $d =(x-x_1)(y_2-y_1)-(y-y_1)(x_2-x_1)$ Si $d<0$ alors le point se trouve d'un côté de la ligne, et si $d>0$ alors il se trouve de l'autre côté . Si $d=0$ alors le point se trouve exactement sur la ligne.

Pour voir si les points sur le côté gauche de la ligne sont ceux avec des valeurs positives ou négatives, calculez la valeur de $d$ pour un point que vous savez être à gauche de la ligne, comme $(x_1-1,y_1)$ et puis comparez le signe avec le point qui vous intéresse.

Addenda:

Par souci d'exhaustivité, une explication de la façon dont cela fonctionne est la suivante :

La direction de la ligne $AB$ peut être définie comme ltx_2, y_2> - <x_1, y_1> = <x_2 - x_1, y_2 - y_1>$

La direction orthogonale (perpendiculaire) à cette ligne sera $vec n=<y_2-y_1, -(x_2 - x_1)>$ (nous retournons les x et les y et annulons une composante, c'est-à-dire (y, -x)). Vous pouvez vérifier que cela est orthogonal en prenant le produit scalaire avec la valeur d'origine et en vérifiant qu'il est 0).

Un vecteur possible allant de la ligne au point $P$ est $D = P-A = <x-x_1,y-y_1> $

Ce vecteur $D$ est composé de 2 composantes, une composante $D^$ qui est parallèle à la droite $AB$ et une composante $D^<ot>$ qui est perpendiculaire à la droite $AB$ . Par définition $D^ cdot vec n = 0$ . Puisqu'une direction parallèle à la ligne sera perpendiculaire à la normale de cette ligne.

Nous sommes intéressés à savoir si le point est du côté auquel la normale pointe, ou du côté auquel la normale pointe en face. En d'autres termes, nous voulons savoir si $D^<ot>$ est dans le même sens que $vec n$ ou non.

C'est essentiellement le signe du produit scalaire de $D$ et $vec n$ puisque $D cdot vec n = (D^ <ot>+ D^) cdot vec n = D ^ <ot>cdot vec n$

Arithmétiquement : $<x-x_1, y-y_1> cdot <y_2 - y_1, -(x_2 - x_1)>$ $=(x-x_1)(y_2 - y_1) - (y-y_1)(x_2 - x_1)$

En bref, nous calculons la distance la plus courte signée de la ligne $AB$ au point $P$ puis évaluons le signe de cette distance.


Edit - Eh bien, c'est embarrassant

Avec un peu plus de réflexion sur les maximisations dans (b) et (c), il est clair qu'elles résolvent le même programme, donc tout cet exercice était mal posé.

Ecrire egin sup_ <eta_<-k>in mathbb^, eta_k=0> L(y, oldsymbol<eta>) &= sup_ <eta_<-k>in mathbb^, eta_k=0> L(y, [eta_<-k>, eta_k]) & = sup_<eta in mathbb^k> egin L(y, [eta_<-k>, eta_k]) & eta_k=0 -infty & eta_k eq 0 end & = sup_<eta in mathbb^k> egin L_<-k>(y, eta_<-k>) & eta_k=0 -infty & eta_k eq 0 end & = sup_ <eta_<-k>in mathbb^> L_<-k>(y, eta_<-k>) end


2 réponses 2

Dans ce cas, créez une matrice de projection orthogonale orientée le long de cette normale, puis transformez les sommets du triangle et votre point par multiplication, et cela devrait devenir une simple vérification 2D pour voir si le point se trouve dans le triangle (volume).

De plus, vous auriez également une valeur Z que vous pourriez utiliser pour éliminer les points trop hauts au-dessus du triangle.

LookAtLH est comment vous pourriez le faire dans D3D/XNA par exemple, EyePosition pourrait être le centre de votre triangle, Focus serait EyePosition + normal, et la direction ascendante devrait être quelque chose de perpendiculaire à cela, c'est-à-dire que l'un des sommets du triangle devrait fonctionner.

Je suis sûr que vous pouvez trouver la source d'une matrice de transformation LookAt similaire avec un peu de recherche sur Google si vous ne voulez pas utiliser une bibliothèque entière pour une seule fonction.

Il y a une excellente réponse à cette question sur la communauté Math de Stack Exchange : Déterminez si la projection du point 3D sur le plan se trouve dans un triangle. Ce qui n'est, à son tour, qu'un résumé de cet article dans Journal of Graphics Tools : Wolfgang Heidrich, 2005, Computing the Barycentric Coordinates of a Projected Point, Journal of Graphics Tools, pp 9-12, 10(3).


2 réponses 2

Voici une façon d'obtenir quelque chose comme ce que vous décrivez. Je l'ai écrit sous forme d'algorithme, mais je suis sûr que quelqu'un pourrait trouver une expression mathématique générale pour la position finale du point "pondéré" par rapport aux 4 points initiaux.

  1. Calculez les proportions de "poids" que chaque coin a par rapport à son opposé. Disons donc que TL (en haut à gauche) en a 100, TR en a 200, BR en a 300 et BL en a 400. Alors TL a 1/4 du poids dans sa diagonale où BR a les 3/4 autres. Et TR a 1/3 là où BL a 2/3.
  2. Début WP (point "pondéré") au TL. Déplacez-le le long de la diagonale TL-BR de la même proportion de la distance à BR que le poids proportionnel de TL.
  3. Déterminez la ligne parallèle à la diagonale TR-BL qui passe par la position actuelle du WP. Déterminez également les intersections de cette ligne avec la limite du quadrilatère déterminé par les 4 points.
  4. Déplacez WP le long de cette ligne jusqu'au point d'intersection avec la limite supérieure du quadrilatère.
  5. Déplacez WP vers le bas sur la ligne d'une distance telle que le rapport de la distance déplacée à la distance à l'autre point limite qui coupe la ligne soit juste le poids proportionnel de TR.

Maintenant, WP devrait être là où vous le voulez.

En utilisant mon exemple de l'étape 1, voici où le WP devrait être à chaque étape en supposant que les quatre points sont les sommets du carré unitaire.


3 réponses 3

Comme le polygone est convexe, c'est simple ! Deux sommets sont consécutifs si tous les autres sommets sont situés du même côté de la ligne qui passe par ces deux points. Cela signifie que le produit vectoriel du vecteur de l'un des points à l'autre avec le vecteur du premier point à n'importe quel autre du polygone a le même signe (tous négatifs ou tous positifs). Par exemple, si ces deux points sont appelés $P_1$ et $P_2$ , vous devez calculer tout le produit croisé de $langle P_1, P_2 angle$ avec $langle P_1, P_i angle$ ( $P_i$ signifie ici tout autres sommets).

De plus, comme discuté dans le commentaire, nous avons quelques cas dégénérés. Le cas dégénéré est un phénomène courant en géométrie computationnelle, qui est généralement traité séparément. Ici, le cas dégénéré est que trois points sont situés sur une ligne.

Étant donné que le polygone est convexe, son centroïde $C$ est à l'intérieur. Testez les gradients des lignes $CV$ pour chaque sommet $V$ . Cela donne un test de temps linéaire.

Une alternative à la réponse d'OmG (ce qui est génial) serait de trier vos points dans un tableau ordonné où vous pouvez trouver tous les points voisins en regardant les points de chaque côté. Cette méthode serait très utile si vous devez travailler avec le même polygone pour de nombreux calculs, car la plupart des travaux sont effectués en amont, mais le coût de déterminer si deux points sont voisins est ensuite très faible.

Alors comment trier le tableau ?

Disons que nous avons un tableau de nos points non triés où chaque point contient ses coordonnées x et y.

Nous voulons d'abord trouver les points les plus à gauche et les plus à droite, c'est-à-dire les valeurs x les plus élevées et les plus basses. Une fonction pour cela ressemblerait à ce qui suit :

Le point le plus à droite serait presque identique, mais le moins serait échangé contre un plus grand que.

Ensuite, nous imaginons que nous traçons une ligne de notre point le plus à gauche à notre point le plus à droite. Ensuite, nous regroupons tous les points restants en deux catégories, ceux en dessous de la ligne et ceux au-dessus.

Maintenant, en supposant que nous ayons stocké tous les points sous/dessus dans leurs propres tableaux, nous avons toutes les informations nécessaires pour construire notre tableau ou nos points triés.

  1. Nous choisissons notre point de départ comme le point le plus à gauche
  2. Ensuite, nous ajoutons toutes les valeurs du tableau supérieur dans l'ordre croissant (le plus petit en premier).
  3. Ajouter le point le plus à droite
  4. Ajoutez les valeurs dans le sous-tableau dans l'ordre décroissant x (le plus grand en premier)

Le résultat est un tableau où chaque point se connecte au point suivant du tableau et le dernier point se connecte au premier. Notez que cette méthode donne comme résultat un polygone sans intersection, que l'entrée soit convexe ou concave. La sortie ne sera garantie convexe que si l'entrée est garantie convexe.

Voir ci-dessous pour un code plus complet

Et voilà, nous l'avons ! et maintenant pour vérifier si les points sont côte à côte, c'est facile quelque chose comme :


Les publicités sur YouTube demandant des dons pour les enfants malades via Drive.com sont-elles une arnaque ?

Ces dernières semaines, YouTube m'a montré une publicité demandant de faire des dons pour aider à payer les factures médicales des enfants malades via un site de financement participatif appelé Drove.

Cependant, les annonces semblent très suspectes. Dans un exemple, une enfant appelée Tovi dans un lit d'hôpital parle dans une langue slave d'être très malade et d'avoir peur de mourir si elle ne reçoit pas le bon traitement, mais aucune précision n'est donnée sur la maladie. Elle dit alors qu'il y a un médecin à Boston qui peut l'aider, mais encore une fois, aucun détail n'est donné. Vous êtes ensuite invité à faire un don via drive.com, mais on ne sait pas exactement à quoi l'argent sera utilisé, ni combien est nécessaire. Toute la publicité semble faite avec des images d'archives de modèles agissant comme des médecins et des pharmaciens, et le supposé hôpital de Boston n'est qu'un bâtiment avec le mot "hôpital" dessus, mais pas de nom.

Tout à propos de cela crie "scam", mais je me demande si l'ensemble du site Drove est une arnaque, ou simplement cette campagne. Je me demande aussi comment il est possible qu'une arnaque comme celle-ci reste sur YouTube pendant des semaines sans être supprimée. À quelle autorité signaleriez-vous ce genre de chose de toute façon?

Est-il possible qu'il s'agisse d'une sorte de demi-arnaque, et qu'il s'agisse en fait d'enfants malades, mais la campagne est intentionnellement vague sur le montant d'argent nécessaire et la part des dons qui va réellement aux enfants, afin qu'ils puissent réclamer légitimité même si les enfants ne reçoivent qu'une petite somme de la campagne ?

J'espère que quelqu'un pourra faire la lumière à ce sujet dans une réponse, afin que les personnes qui se demandent s'il faut faire un don ou non puissent trouver cette question et prendre une décision plus éclairée.


Démontrer que le postulat parallèle d'Euclide est faux sur le modèle hyperboloïde

Considérons le cas bidimensionnel, c'est-à-dire du lieu hyperbolique. Définissez notre hyperboloïde comme l'ensemble des points $x=(x_1,x_2,x_3)$ dans l'espace 3-(note : espace de Minkowski, mais pas nécessaire pour ce problème) qui remplissent $x_1^2 - y_1^2 - z_1^2 = 1$ et $x_1>0$. Une ligne hyperbolique est définie comme l'intersection d'un plan qui passe par l'origine avec l'hyperboloïde. Deux points hyperboliques distincts (points sur l'hyperboloïde) déterminent une ligne hyperbolique. Considérez le dessin étiqueté [2] sur cette image pour plus de clarté (de ce site Web) :

Je voudrais prouver quelque chose qui semble intuitivement clair :

Étant donné une droite hyperbolique $h$ et un point hyperbolique $p$ non sur $h$, il existe une infinité de droites hyperboliques passant par $p$ qui ne coupent pas $h$.

(note : c'est la variante hyperbolique du postulat parallèle d'Euclide)

Ma tentative de preuve commence ainsi :

On a par définition que $h$ est l'intersection du plan $m_1$ déterminé par deux points hyperboliques distincts et l'origine avec l'hyperboloïde. Comme $p$ n'est pas contenu par $h$, nous avons que $p$ ne peut pas non plus être contenu par $m_1$, donc toute ligne hyperbolique couverte par $p$ est l'intersection d'un autre plan $m_2$, déterminé par $ p$, l'origine et un certain point $s$, avec l'hyperboloïde. $m_1$ et $m_2$ sont donc des plans distincts mais parce qu'ils se rencontrent au moins en un point, l'origine, ils ne peuvent pas être parallèles et nous savons donc d'après la géométrie euclidienne que leur intersection est une droite $l$. Parce que $h$ est sur l'hyperboloïde, si $l$ et $h$ se coupent, cela signifie que la ligne hyperbolique couverte par $p$ coupe $h$ en un point hyperbolique, nous voulons donc montrer qu'il y a une infinité de façons de choisir le point $s$ pour que $h$ et $l$ ne se coupent pas.

et à ce stade, j'allais utiliser un argument topologique pour montrer que nous pouvons sélectionner infiniment plus de points $s$ pour que $h$ et $l$ ne se coupent pas. Mais je ne pouvais pas le faire, je pense que ma méthode est peut-être erronée et que l'algèbre est une meilleure façon de procéder. Est-ce que quelqu'un ici sait comment le montrer ou peut m'indiquer une référence avec une preuve?


Qu'est-ce qu'un déphasage en trigonométrie et comment puis-je le déterminer à partir d'un graphique ?

Je suis un étudiant en pré-calcul qui apprend les transformations de fonctions trigonométriques et je suis extrêmement confus au sujet de la définition d'un déphasage (et donc très, très frustré).

Nous apprenons les fonctions des deux formes générales suivantes :

La définition du déphasage qui nous a été donnée était la suivante : "Le décalage horizontal par rapport à une onde de référence".

On nous a ensuite fourni le graphique suivant (et aucune autre information n'a été donnée au-delà du fait qu'il s'agissait d'une fonction transformée en sinus ou en cosinus de l'une des formes données ci-dessus):

(Ignorez mes marques de crayon effacées dans le graphique !)

On nous a demandé de trouver le déphasage de la fonction représentée graphiquement par rapport à la fonction parent cosinus $y=cos(x)$ . On nous a également demandé de trouver le déphasage de la fonction représentée graphiquement par rapport à la fonction parent sinus $y=sin(x)$ . (Bien sûr, nos réponses seraient des estimations aveugles basées sur le graphique.)

J'étais complètement mystifié. La définition donnée ci-dessus ne m'a pratiquement rien dit de ce que je voulais savoir. Et quand j'ai demandé une explication au professeur, cela n'a pas mis fin à ma confusion. Quelqu'un ici a-t-il une bonne explication de ce qu'est un déphasage, et peut-être aussi comment (étant donné une solide connaissance de la définition) je pourrais résoudre le problème de graphe mentionné ci-dessus ?


Schéma de câblage de cet interrupteur 12V bleu ?

Je recherche un schéma de câblage ou des informations sur les connexions internes de cet interrupteur de l'ère du train bleu.

Il sert au contrôle des points automatiques, et est visible sur la boite d'origine :

Les points se connectent à l'arrière de l'interrupteur à l'aide d'un connecteur à 3 pôles :

Je veux utiliser un microcontrôleur pour faire fonctionner les points sans appuyer manuellement sur les boutons. Comme je n'en ai aucun, je ne peux pas mesurer les connexions (à l'aide d'un multimètre).

Quelqu'un possède-t-il ce commutateur et souhaite-t-il partager des informations ?

C'est ainsi que je pense que l'interrupteur fonctionne. J'ai essayé de le câbler de cette façon et cela fonctionne, mais les points bougent à peine. Peut-être que le problème vient des solénoïdes à l'intérieur des pointes ?


Voir la vidéo: Comment savoir si un point appartient à la courbe représentative dune fonction? (Octobre 2021).