Comment générer des coordonnées (x, y) à partir de 4 points

Résolu/Fermé
LALO_5656 Messages postés 21 Date d'inscription mardi 8 novembre 2022 Statut Membre Dernière intervention 4 juillet 2023 - Modifié le 24 nov. 2022 à 16:04
yg_be Messages postés 22149 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 29 novembre 2023 - 6 janv. 2023 à 19:01

Bonjour, à tous,

Je voudrais générer des coordonnées x,y  à partir de 4 points sources (maillage régulier de 5m*5m entre les points) dans une emprise bien définie et extraire toutes les coordonnées dans un fichier .csv

import matplotlib.pyplot as plt

# Les 4 coordonnées sources
x = [325010,  325015,  325015,  325010,  325010]
y = [2077560, 2077560, 2077555, 2077555, 2077560]

# L'emprise du projet
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]

plt.plot(A, B)
plt.scatter(x, y, color="r")
plt.axis("equal")
plt.grid()
plt.show()

7 réponses

LALO_5656 Messages postés 21 Date d'inscription mardi 8 novembre 2022 Statut Membre Dernière intervention 4 juillet 2023 1
24 nov. 2022 à 17:22

Effectivement le but est de trouver l'ensemble des points contenus dans l'enveloppe bleu.

Je mis la couleur rouge sur les 4 points source juste pour les differencier des points à générer.

Pour la redondance des points 1 et 5 c'est une erreur.Tous les points sont espacés de 5m les uns par rapport au autres.

1
yg_be Messages postés 22149 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 29 novembre 2023 1 407
Modifié le 24 nov. 2022 à 20:47

Un exemple, horriblement mal écrit, et supposant que le polynôme est convexe:

import matplotlib.pyplot as plt
def equdroite(x0,y0,x1,y1):
    a=y1-y0
    b=x0-x1
    c=-(b*y0+a*x0)
#     print("verif00:",sign(x0,y0,a,b,c),sign(x1,y1,a,b,c))
    return a,b,c
def inside(Poly,p):
    for P in Poly:
        a,b,c,s,x,y=P[0],P[1],P[2],P[3],pp[0],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
# Les 4 coordonnées sources
x = [325010,  325015,  325015,  325010,  325010]
y = [2077560, 2077560, 2077555, 2077555, 2077560]
sg=5
# L'emprise du projet
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
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])
# print("E:",E)
plt.plot(A, B)
plt.scatter(x, y, color="r")
plt.axis("equal")
plt.grid()


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(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]
plt.scatter(xrouge,yrouge, color="g")
plt.show()
0
yg_be Messages postés 22149 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 29 novembre 2023 1 407
24 nov. 2022 à 09:57

bonjour,

qu'as-tu essayé?

peux-tu donner quelques exemples de coordonnées à obtenir?

0
mamiemando Messages postés 32777 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 29 novembre 2023 7 684
Modifié le 24 nov. 2022 à 16:29

Bonjour,

Si j'ai bien compris le but de l'exercice, le but est de trouver l'ensemble des points rouges contenus dans l'enveloppe bleue selon l'espacement dicté par les 4 points rouges définis par x et y. Note au passage que dans ton code, le 1er et le 5e points sont redondants.

D'un point de vue maths, cela revient au problème consistant à énumérer les points contenu dans une enveloppe convexe (en tout cas dans l'exemple, elle est convexe). Aussi simple que ce problème puisse paraître, il n'y a pas de manière simple de résoudre ce problème (plus de détails ici). En effet, il faut "comprendre" de quel côté est l'intérieur de l'empreinte pour chaque segment défini (en maths on parle de facette). Si l'enveloppe est convexe, il suffit que le point considéré soit du bon côté de chaque facette pour être dans le polytope (ce que tu appelles l'empreinte) et cela revient à comparer la position d'un point par rapport à une droite dans le plan.

Cependant, si l'emprise n'est pas convexe (par exemple, si l'empreinte a une forme de L, de T, ou de H, elle n'est pas convexe et ces méthodes ne s'appliquent pas), alors c'est beaucoup plus compliqué car les points dans l'empreinte ne satisfont pas simultanément les inégalités induites par les facettes.

Par contre il y peut être moyen de ruser, y compris quand l'enveloppe n'est pas convexe. En effet, tu peux :
1) dessiner ton enveloppe dans un svg et colorer son intérieur;
2) énumérer les points de la grille contenus dans le rectangle dont les coins ont pour coordonnées ((min(x), min(y)), (min(x), max(y)), (max(x), max(y)), (max(x), min(y))) ;
3) récupérer la couleur du pixel du point testé (par exemple avec PIL).

Une fois les points déterminés, tu peux facilement les mettre dans un fichier csv (avec ou sans le module csv).

Bonne chance

0
yg_be Messages postés 22149 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 29 novembre 2023 1 407
24 nov. 2022 à 18:50

En quoi est-ce difficile, si le polygone est convexe?

Si utile, on peut préalablement vérifier si le polygone est bien convexe.

0
mamiemando Messages postés 32777 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 29 novembre 2023 7 684 > yg_be Messages postés 22149 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 29 novembre 2023
Modifié le 25 nov. 2022 à 02:26

Pardon, tu as raison, ça mérite clarification. Dans #4, quand je dis "il n'existe pas de manière simple" je voulais dire, à moins de comparer chaque point avec chaque facette, il n'y a pas de manière d'itérer facilement sur les points qui nous intéressent (genre une méthode toute prête).

La méthode que tu proposes dans #6 revient (si j'ai bien compris ton code) à faire ce que j'indiquais dans #4 (mais sans avoir à passer par PIL, ce qui est bien plus élégant) à savoir énumérer les points dans une zone et rejeter ceux qui contredisent une facette.

0
yg_be Messages postés 22149 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 29 novembre 2023 1 407 > mamiemando Messages postés 32777 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 29 novembre 2023
Modifié le 25 nov. 2022 à 08:09

En effet, le code en #6 fait ce que tu décris.

Ceci vérifie également si le polygone est bien convexe:

import matplotlib.pyplot 
def equdroite(x0,y0,x1,y1):
    a=y1-y0
    b=x0-x1
    c=-(b*y0+a*x0)
#     print("verif00:",sign(x0,y0,a,b,c),sign(x1,y1,a,b,c))
    return a,b,c
def inside(Poly,p):
    for P in Poly:
        a,b,c,s,x,y=P[0],P[1],P[2],P[3],pp[0],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
# Les 4 coordonnées sources
x = [325010,  325015,  325015,  325010,  325010]
y = [2077560, 2077560, 2077555, 2077555, 2077560]
sg=5
# L'emprise du projet
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]
# A = [324989.345,  324987.133,  324980,  325037.452,  325035.977,  324989.345]
# B = [2077586.246, 2077553.622, 2077800, 2077537.402, 2077589.933, 2077586.246]
# avgA,avgB=sum(A)/len(A),sum(B)/len(B)
# # print ("avg:",avgA,avgB)
# A=[x-avgA for x in A]
# B=[x-avgB for x in B]
# x=[x-avgA for x in x]
# y=[x-avgB for x in y]
nc=len(A)-1
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()


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(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.show()
0
yg_be Messages postés 22149 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 29 novembre 2023 1 407
6 janv. 2023 à 19:01

En fait, shapely fait tout cela.

0
LALO_5656 Messages postés 21 Date d'inscription mardi 8 novembre 2022 Statut Membre Dernière intervention 4 juillet 2023 1
25 nov. 2022 à 10:10

Bonjour exactement ce à quoi je m'attendais merci infinement .

Maintenant il ne me reste plus de voir comment extraire tous les coordonnées de ces points dans un fichier csv.

Encore merci

0

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

Posez votre question
LALO_5656 Messages postés 21 Date d'inscription mardi 8 novembre 2022 Statut Membre Dernière intervention 4 juillet 2023 1
25 nov. 2022 à 13:46

Bonjour voila ce que je ajouter à la fin du code  dans l'espoir de recuperer ces coordonnées mais hélas il me renvoie une erreur.

with open('Coordout.csv', 'w+') as of:
    of.write("X;Y\n")
    for p in prouge:
        of.write('{:f};{:f}\n'.format(p.xrouge, p.yrouge))
plt.close()
0
yg_be Messages postés 22149 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 29 novembre 2023 1 407
25 nov. 2022 à 16:25

Quelle erreur?

sans doute plutôt:

for p in prouge:
    print(p[0],p[1])
0
LALO_5656 Messages postés 21 Date d'inscription mardi 8 novembre 2022 Statut Membre Dernière intervention 4 juillet 2023 1
25 nov. 2022 à 17:20

Bonsoir,ce code à la fin voila l'erreur qu'il me donne:  line 83, in <module>
    of.write('{:f};{:f}\n'.format(xrouge, yrouge))
TypeError: unsupported format string passed to list.__format__ 

with open('Coordout.csv', 'w+') as of:
    of.write("X;Y\n")
    for p in prouge:
        print(p[0], p[1])
        of.write('{:f};{:f}\n'.format(xrouge, yrouge))
plt.close()
matplotlib.pyplot.show()
0
mamiemando Messages postés 32777 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 29 novembre 2023 7 684
Modifié le 25 nov. 2022 à 18:21

Bonjour,

Tu te compliques la vie :

points = [(1, 2), (3, 4)]
with open("coordout.csv", "w") as f:
    print("X;Y", file=f)
    for (x, y) in points:
        print(f"{x};{y}", file=f)

Bonne chance

0
LALO_5656 Messages postés 21 Date d'inscription mardi 8 novembre 2022 Statut Membre Dernière intervention 4 juillet 2023 1
30 nov. 2022 à 08:54
with open("coordout.csv", "w") as f:
    print("X;Y", file=f)
    for xrouge, yrouge in prouge:
        print(f"{xrouge};{yrouge}", file=f)
matplotlib.pyplot.show()

Bonjour à tous merci beaucoup pour vos réaction.

Mon problème est résolu

0