IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Tester la superposition de 2 surfaces géométriques


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2004
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 110
    Par défaut Tester la superposition de 2 surfaces géométriques
    Bonjour à tous ,

    Dans une table T_POSITION_POS (POS_ID,POS_X_POS_Y,REC_LONG,REC_LARG) représente la position des rectangles dans un dessin 2D.
    J'ai volontairement dénormaliser mon modèle pour simplifier la résolution de mon problème (J'ai bien sur une table T_RECTANGLE_REC(REC_ID,REC_LONG_REC_LARG) connectée à T_POSITION_POS.

    Je voudrais y ajouter une contrainte supplémentaire "les chevauchements des rectangles sont interdits".
    J'ai rajouté un trigger mais je n'arrive pas trouver la requête qui puisse tester si la sufarce sur laquelle va être positionné le nouveau rectangle est libre.

    Est-ce que quelqu'un à une idée ?


    Merci d'avance


    Voici les scripts :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    CREATE TABLE T_POSITION_POS (
    			     POS_ID IDENTITY(1,1) NOT NULL,
                                 POS_X INTEGER NOT NULL,
    			     POS_Y INTEGER NOT NULL,
    			     REC_LONGUEUR INTEGER NOT NULL,
    			     REC_LARGEUR INTEGER NOT NULL
                                )
    GO
    ALTER TABLE T_POSITION_POS ADD CONSTRAINT
    	PK_POS_ID PRIMARY KEY CLUSTERED 
    	(POS_ID) ON [PRIMARY]	  
    GO
    INSERT INTO T_POSITION_POS (POS_X,POS_Y,REC_LONGUEUR,REC_LARGEUR) 
    VALUES(0,0,20,10)
    GO
    INSERT INTO T_POSITION_POS (POS_X,POS_Y,REC_LONGUEUR,REC_LARGEUR) 
    VALUES(10,5,20,10)
    /* Devrais provoquer une erreur grace au trigger */

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 22 010
    Billets dans le blog
    6
    Par défaut
    trois cas à envisager :
    • le chevauchement : un des angles du rectangle est dans un autre rectangle
    • l'inclusion : tous le rectangle est dans l'un des rectangles
    • la superposition : le rectangle englobe entièrement un des rectangles


    • les cas 1 et 2 se résume à : vérifier si un des points du rectangle est dans un rectangle
    • le cas trois se résume à vérifier si les angles opposés sont l'un avant le rectanagle par rapport à l'origine et l'autre après le rectangle par rapport à m'origine

    Votre contrainte serait facilité si vous aviez une vue proposant les côtés du rectangle, comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    -- création de la vue :
    CREATE V_POSITION_POS
    AS
       SELECT POS_ID, POS_X                AS POS_X_DEBUT,
                      POS_X + REC_LONGUEUR AS POS_X_FIN,
                      POS_Y                AS POS_Y_DEBUT,
                      POS_Y + REC_LARGEUR  AS POS_Y_FIN,
                                              REC_LONGUEUR,
                                              REC_LARGEUR
       FROM   T_POSITION_POS
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    -- cas 1 et 2
              SELECT *
              FROM   V_POSITION_POS AS P
                     CROSS JOIN inserted as i
              WHERE  (i.POS_X BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y BETWEEN POS_Y_DEBUT AND POS_Y_FIN)
                  OR (i.POS_X BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y + REC_LARGEUR BETWEEN POS_Y_DEBUT AND POS_Y_FIN)
                  OR (i.POS_X + REC_LONGUEUR BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y BETWEEN POS_Y_DEBUT AND POS_Y_FIN)
                  OR (i.POS_X + REC_LONGUEUR BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y + REC_LARGEUR BETWEEN POS_Y_DEBUT AND POS_Y_FIN)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    -- cas 3 
              SELECT *
              FROM   V_POSITION_POS AS P
                     CROSS JOIN inserted as i
              WHERE  i.POS_X <= POS_X_DEBUT AND i.POS_Y < POS_Y_DEBUT
                AND  i.POS_X + REC_LONGUEUR >= POS_X_FIN AND i.POS_Y + REC_LARGEUR >= POS_Y_FIN
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    -- factorisation des cas 1, 2 et 3 :
              SELECT *
              FROM   V_POSITION_POS AS P
                     CROSS JOIN inserted as i
              WHERE  (i.POS_X BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y BETWEEN POS_Y_DEBUT AND POS_Y_FIN)
                  OR (i.POS_X BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y + REC_LARGEUR BETWEEN POS_Y_DEBUT AND POS_Y_FIN)
                  OR (i.POS_X + REC_LONGUEUR BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y BETWEEN POS_Y_DEBUT AND POS_Y_FIN)
                  OR (i.POS_X + REC_LONGUEUR BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y + REC_LARGEUR BETWEEN POS_Y_DEBUT AND POS_Y_FIN)  
                  OR (i.POS_X <= POS_X_DEBUT AND i.POS_Y < POS_Y_DEBUT
                      AND i.POS_X + REC_LONGUEUR >= POS_X_FIN AND i.POS_Y + REC_LARGEUR >= POS_Y_FIN)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    -- encapsulation dans un trigger :
    CREATE TRIGGER E_IU_POS
    ON T_POSITION_POS
    FOR INSERT, UPDATE
    AS
    BEGIN
    IF EXISTS(SELECT *
              FROM   V_POSITION_POS AS P
                     CROSS JOIN inserted as i
              WHERE  (i.POS_X BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y BETWEEN POS_Y_DEBUT AND POS_Y_FIN)
                  OR (i.POS_X BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y + REC_LARGEUR BETWEEN POS_Y_DEBUT AND POS_Y_FIN)
                  OR (i.POS_X + REC_LONGUEUR BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y BETWEEN POS_Y_DEBUT AND POS_Y_FIN)
                  OR (i.POS_X + REC_LONGUEUR BETWEEN POS_X_DEBUT AND POS_X_FIN
                      AND i.POS_Y + REC_LARGEUR BETWEEN POS_Y_DEBUT AND POS_Y_FIN)  
                  OR (i.POS_X <= POS_X_DEBUT AND i.POS_Y < POS_Y_DEBUT
                      AND i.POS_X + REC_LONGUEUR >= POS_X_FIN AND i.POS_Y + REC_LARGEUR >= POS_Y_FIN)               
             )
    BEGIN
       ROLLBACK TRANSACTION;
       RAISERROR('Chevauchement de rectangle', 16, 1);
    END;
    END
    GO
    A +

    PS : pas testé... Donc à vérifier !
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre éclairé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Par défaut
    Il manque un cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       ------
       |    |
    ---|----|----
    |  |    |   |
    |  |    |   |
    ---|----|----
       |    |
       ------
    Les rectangles superposés dont les angles d'un rectangle ne sont pas dans l'autre rectangle.

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 22 010
    Billets dans le blog
    6
    Par défaut
    Bien vu ! A adapter...

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Membre éclairé Avatar de Monstros Velu
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2003
    Messages
    619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 619
    Par défaut
    J'ai réfléchi à ce problème, et je n'ai rien trouvé d'autre que de vérifier les intersection des segments constituant les rectangles (ou du moins, la localisation des points autour d'un ligne déterminé par un segment)... du coup, ça m'a l'air assez énorme comme calcul...

  6. #6
    Membre confirmé
    Inscrit en
    Octobre 2004
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 110
    Par défaut
    J'ai testé la solution , elle fonctionne à part qu'il a fallu rajouter
    un critère supplémentaire (P.POS_ID<>i.POS_ID AND ...) afin d'exclure du test la ligne insérée(trigger AFTER oblige) .

    Quand au cas soumis pas Mostros Velu , je n'ai heureusement pas à le traiter car mes rectangles ont une contrainte supplémentaire : Longueur>Largeur.

    Merci à tous pour votre aide .

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Calculer la surface d'une forme géométrique irrégulière
    Par Eayoub dans le forum Mathématiques
    Réponses: 3
    Dernier message: 07/03/2011, 09h55
  2. Superposition de surface
    Par razonback dans le forum SDL
    Réponses: 16
    Dernier message: 22/03/2008, 18h31
  3. Superposition de surface
    Par razonback dans le forum C
    Réponses: 2
    Dernier message: 18/03/2008, 18h23
  4. Réponses: 2
    Dernier message: 30/03/2007, 13h17
  5. Calcul de surface et de périmètre de forme géométrique
    Par Nathan dans le forum Delphi .NET
    Réponses: 1
    Dernier message: 15/05/2006, 13h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo