Problème avec des coordonnées

LALO_5656 Messages postés 27 Date d'inscription mardi 8 novembre 2022 Statut Membre Dernière intervention 29 août 2024 - Modifié le 29 août 2024 à 12:12
mamiemando Messages postés 33262 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 6 septembre 2024 - 29 août 2024 à 14:42

Bonjour à tous,

J'ai code qui marche  bien avec les coordonnées mis en commentaire. Mais quand le nombre de coordonnées A B augmente, je n'ai pas le résultat attendu.

Est-ce-que quelqu'un à une idée de pourquoi ça ne marche pas ?

Merci d'avance

import csv
import matplotlib.pyplot
from matplotlib import pyplot as plt


def equdroite(x0, y0, x1, y1):
    a = y1 - y0
    b = x0 - x1
    c = -(b * y0 + a * x0)
    return a, b, c


def inside(Poly, p):
    for P in Poly:
        a, b, c, s, x, y = float(P[0]), float(P[1]), float(P[2]), float(P[3]), float(pp[0]), float(pp[1])
        if s * sign(x, y, a, b, c) < 0:
            #            print("outside:",a,b,c,s,x,y)
            return False
    return True


def sign(x, y, a, b, c):
    return a * x + b * y + c


x = [325025, 325000, 325000, 325025]
y = [2077495, 2077495, 2077520, 2077520]

# x = [325010.01, 325015.120, 325015.2, 325010.210]
# y = [2077560.012, 2077560.05, 2077555.21, 2077555.045]
sg = 5
A = [324987.612, 324987.549, 324987.525, 324986.697, 324984.445, 324989.878, 324994.957, 325001.832, 325006.195,
     325015.463, 325019.355, 325035.482, 325037.5, 325045.742, 325060.603, 324987.2]
B = [2077487.5, 2077487.897, 2077518.372, 2077523.137, 2077527.005, 2077537.484, 2077536.422, 2077536.602, 2077536.922,
     2077536.433, 2077536.6, 2077536.314, 2077537.5, 2077537.5, 2077487.5, 2077487.5]

# A = [324989.345, 324987.133, 324987.502, 325037.452, 325035.977, 324989.345]
# B = [2077586.246, 2077553.622, 2077537.955, 2077537.402, 2077589.933, 2077586.246]
nc = (len(A) - 1)
print(nc)
E = []
for p0 in range(nc):
    p1 = (p0 + 1) % nc
    p2 = (p0 + int(nc // 2)) % nc
    a, b, c = equdroite(A[p0], B[p0], A[p1], B[p1])
    s = sign(A[p2], B[p2], a, b, c)
    print("inloop:", p0, a, b, c, s)
    E.append([a, b, c, s, p0, p1])
print("E:", E)
for p in range(nc):
    for C in E:
        if p != C[4] and p != C[5]:
            a, b, c, s, xp, yp = C[0], C[1], C[2], C[3], A[p], B[p]
            v = sign(xp, yp, a, b, c)
            if s * v < 0:
                print("outside:", a, b, c, s, xp, yp)
                print("OUPS!", s, v)
matplotlib.pyplot.plot(A, B)
matplotlib.pyplot.scatter(x, y, color="r")
matplotlib.pyplot.axis("equal")
matplotlib.pyplot.grid(True)
plt.title("Coordonnées planifiés")
plt.xlabel("Axe des X")
plt.ylabel("Axe des Y")

phg = (int(min(A) // sg) * sg, int(min(B) // sg) * sg)
pbd = (int(max(A) // sg + 1) * sg, int(max(B) // sg + 1) * sg)
nrow = int((pbd[0] - phg[0]) // sg) + 1
ncol = int((pbd[1] - phg[1]) // sg) + 1
print(phg)
print(pbd)
print(nrow, ncol)
prouge = []
for row in range(nrow):
    for col in range(ncol):
        pp = (phg[0] + sg * row, phg[1] + sg * col)
        if inside(E, pp):
            prouge.append(pp)
xrouge = [ppp[0] for ppp in prouge]
yrouge = [ppp[1] for ppp in prouge]
matplotlib.pyplot.scatter(xrouge, yrouge, color="g")
matplotlib.pyplot.scatter(x, y, color="r")
with open("coordout.csv", "w") as f:
    print("X;Y", file=f)
    for xrouge, yrouge in prouge:
        print(f"{xrouge};{yrouge}", file=f)

data = A, B
with open('coordout.csv', 'a') as f:
    writer = csv.writer(f)
    writer.writerows(data)
matplotlib.pyplot.show()


 

5 réponses

luckydu43 Messages postés 3730 Date d'inscription vendredi 9 janvier 2015 Statut Membre Dernière intervention 11 septembre 2024 917
Modifié le 28 août 2024 à 16:24

Bonjour,

Le code est complexe à lire, je vais m'arrêter à quelques points de détail.

- Tes imports sont redondants, simplifie par

import matplotlib.pyplot as plt

- La méthode inside() de vérification du point dans le polygone est brutale, matplotlib contient déjà de quoi vérifier ça ! Par le fait ça allège quelques fonctions.

  • Importe Path de matplotlib et remplace def inside(Poly, p): par
from matplotlib.path import Path

...

def inside(Poly, p):
    path = Path(Poly)
    return path.contains_points([p])[0]
  • Remplace ta big double boucle for par :
path_for_oups = Path(list(zip(A, B)))
for i in range(nc):
    if not path_for_oups.contains_point((A[i], B[i])):
        print("OUPS!", A[i], B[i])

Tiens au jus !


1
mamiemando Messages postés 33262 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 6 septembre 2024 7 777
29 août 2024 à 12:24

Si on utilise cette nouvelle version de la fonction inside, il faut revoir la manière dont l'enveloppe E est construire :

E = list(zip(A, B))

On peut alors se débarrasser :

  • de la boucle qui construisait E (l41-49)
  • des fonctions equdroites, sign
  • de la variable nc

Bonne chance

1
mamiemando Messages postés 33262 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 6 septembre 2024 7 777
Modifié le 29 août 2024 à 14:42

Bonjour,

Je te propose cette réécriture plus simple de ce programme, qui j'espère, fait ce que tu veux en réutilisant les remarques faites dans les messages #2 et #5. J'ai renommé quelques variables afin qu'il soit plus clair et décomposé le code en fonction pour qu'il soit plus lisible. J'ai retiré la partie csv car elle n'est pas au centre de la question, mais libre à toi de la remettre.

Si j'ai bien compris, le but est de trouver, étant donnée une enveloppe polygonale (blue_points), de trouver tous les points contenus dans cette enveloppe (green_points) étant donné un pas discret arbitraire (step).

from matplotlib import pyplot as plt
from matplotlib.path import Path

def inside(poly, p):
    path = Path(poly)
    return path.contains_points([p])[0]

def quantize(x, step):
    return (x // step) * step

def make_dataset(dataset_id):
    if dataset_id == 1:
        red_xs = [325025, 325000, 325000, 325025]
        red_ys = [2077495, 2077495, 2077520, 2077520]
        blue_xs = [324987.612, 324987.549, 324987.525, 324986.697, 324984.445, 324989.878, 324994.957, 325001.832, 325006.195,
             325015.463, 325019.355, 325035.482, 325037.5, 325045.742, 325060.603, 324987.2]
        blue_ys = [2077487.5, 2077487.897, 2077518.372, 2077523.137, 2077527.005, 2077537.484, 2077536.422, 2077536.602, 2077536.922,
             2077536.433, 2077536.6, 2077536.314, 2077537.5, 2077537.5, 2077487.5, 2077487.5]
    elif dataset_id == 2:
        red_xs = [325010.01, 325015.120, 325015.2, 325010.210]
        red_ys = [2077560.012, 2077560.05, 2077555.21, 2077555.045]
        blue_xs = [324989.345, 324987.133, 324987.502, 325037.452, 325035.977, 324989.345]
        blue_ys = [2077586.246, 2077553.622, 2077537.955, 2077537.402, 2077589.933, 2077586.246]
    else:
        raise ValueError("Invalid dataset_id")
    return (red_xs, red_ys, blue_xs, blue_ys)

def find_discrete_points_in_hull(xs, ys, step):
    min_x = int(quantize(min(xs), step)) + step
    min_y = int(quantize(min(ys), step)) + step
    max_x = int(quantize(max(xs), step)) + step
    max_y = int(quantize(max(ys), step)) + step
    hull = list(zip(xs, ys))
    return [
        (px, py)
        for px in range(min_x, max_x, step)
        for py in range(min_y, max_y, step)
        if inside(hull, (px, py))
    ]

def my_plot(red_xs, red_ys, blue_xs, blue_ys, green_xs, green_ys):
    plt.plot(blue_xs, blue_ys)
    plt.axis("equal")
    plt.grid(True)
    plt.title("Coordonnées planifiées")
    plt.xlabel("Axe des X")
    plt.ylabel("Axe des Y")
    plt.scatter(green_xs, green_ys, color="g")
    plt.scatter(red_xs, red_ys, color="r")

def main():
    step = 5
    for dataset_id in (1, 2):
        (red_xs, red_ys, blue_xs, blue_ys) = make_dataset(dataset_id)
        green_points = find_discrete_points_in_hull(blue_xs, blue_ys, step)
        (green_xs, green_ys) = zip(*green_points)
        my_plot(red_xs, red_ys, blue_xs, blue_ys, green_xs, green_ys)
        plt.show()

main()

Bonne chance

1
yg_be Messages postés 23170 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 12 septembre 2024 1 532
28 août 2024 à 15:28

bonjour,

Si tu as une idée de ce que fait ce programme, pourrais-tu l'expliquer?

0
yg_be Messages postés 23170 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 12 septembre 2024 1 532
Modifié le 28 août 2024 à 16:42

Je pense que ton polygone est concave, tout simplement.

Les points 0 et 9 ne sont pas du même côté de la droite passant par les points 2 et 3
Les points 0 et 10 ne sont pas du même côté de la droite passant par les points 3 et 4
Les points 0 et 12 ne sont pas du même côté de la droite passant par les points 5 et 6
Les points 0 et 3 ne sont pas du même côté de la droite passant par les points 11 et 12
Les points 1 et 9 ne sont pas du même côté de la droite passant par les points 2 et 3
Les points 1 et 10 ne sont pas du même côté de la droite passant par les points 3 et 4
Les points 1 et 12 ne sont pas du même côté de la droite passant par les points 5 et 6
Les points 1 et 3 ne sont pas du même côté de la droite passant par les points 11 et 12
Les points 2 et 10 ne sont pas du même côté de la droite passant par les points 3 et 4
Les points 2 et 12 ne sont pas du même côté de la droite passant par les points 5 et 6
Les points 3 et 8 ne sont pas du même côté de la droite passant par les points 1 et 2
Les points 3 et 12 ne sont pas du même côté de la droite passant par les points 5 et 6
Les points 4 et 8 ne sont pas du même côté de la droite passant par les points 1 et 2
Les points 4 et 9 ne sont pas du même côté de la droite passant par les points 2 et 3
Les points 4 et 12 ne sont pas du même côté de la droite passant par les points 5 et 6
Les points 5 et 13 ne sont pas du même côté de la droite passant par les points 6 et 7
Les points 5 et 14 ne sont pas du même côté de la droite passant par les points 7 et 8
Les points 5 et 1 ne sont pas du même côté de la droite passant par les points 9 et 10
Les points 5 et 2 ne sont pas du même côté de la droite passant par les points 10 et 11
Les points 6 et 14 ne sont pas du même côté de la droite passant par les points 7 et 8
Les points 6 et 1 ne sont pas du même côté de la droite passant par les points 9 et 10
Les points 7 et 1 ne sont pas du même côté de la droite passant par les points 9 et 10
Les points 8 et 13 ne sont pas du même côté de la droite passant par les points 6 et 7
Les points 8 et 1 ne sont pas du même côté de la droite passant par les points 9 et 10
Les points 8 et 2 ne sont pas du même côté de la droite passant par les points 10 et 11
Les points 10 et 0 ne sont pas du même côté de la droite passant par les points 8 et 9
Les points 11 et 0 ne sont pas du même côté de la droite passant par les points 8 et 9
Les points 12 et 0 ne sont pas du même côté de la droite passant par les points 8 et 9
Les points 12 et 1 ne sont pas du même côté de la droite passant par les points 9 et 10
Les points 12 et 2 ne sont pas du même côté de la droite passant par les points 10 et 11
Les points 13 et 0 ne sont pas du même côté de la droite passant par les points 8 et 9
Les points 13 et 2 ne sont pas du même côté de la droite passant par les points 10 et 11
Les points 13 et 3 ne sont pas du même côté de la droite passant par les points 11 et 12
Les points 14 et 12 ne sont pas du même côté de la droite passant par les points 5 et 6
Les points 14 et 3 ne sont pas du même côté de la droite passant par les points 11 et 12

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
LALO_5656 Messages postés 27 Date d'inscription mardi 8 novembre 2022 Statut Membre Dernière intervention 29 août 2024 1
29 août 2024 à 07:18

Bonjour,

merci beaucoup luckydu43 pour vos observations merci a vous aussi yg_be effectivement il est concave, je veux utiliser shapely et la methode avec matplotlib voir

0