Newsgroup: it.comp.lang.visual-basic
Titolo: [VB.NET 2005 - CONSIGLIO - UN PO LUNGO ] Piccolo programma di CAD : Selezionare oggetti

Ciao a tutti, vengo a chiedervi un piccolo consiglio.
Sto iniziando ad utilizzare il VB 2005 e le GDI+, e sto realizzando un
programmino  simil-cad per prendere un po di confdenza con le GDI+.
Senza entrare tanto nel dettaglio, mi sono creato la mia classe
Rettangolo e quando disegno col mouse un rettangolo su una picturebox,
creo una nova istanza della classe e la salvo su un array, per cui se
disegno 100 rettangoli ho un array di 100 elementi ,ognuno che punta
alla rispettiva figura.
il mio problema è selezionare una figura già disegnata, cioè quando 
clicco sopra il rettagolo voglio selezinarlo:
Per il momento ho rsolto creando una matrice bidimensionale di (WIDTH x 
HEIGH  pixel ) di Object, e quando disegno una figura vado a salvare 
nell'elemento (x,y) il riferimento alla figura (questo per tutti i pixel 
che compongono il mio rettangolo). Quando poi faccio click su un punto 
(x,y) della pictureox che rappresenta il mio foglio, vado a vedere nella 
matrice se nell'elemento (x,y) c'è o no un riferimento alla figura.
Problemi che presumo verrano fuori sono i seguenti:
1) occupazione di memoria ( matrice do 500*500 di object è bella grossa 
considerando il fatto che la maggior parte degli elementi sarà Nothing)
2) finchè ho figure costituite da linee verticali ed orizzontali è 
semplice, ma nel caso di ellissi o di cerchi o di linee curve generiche 
  per esempio dovrei fare una enormità di conti per calcolarmi le 
coordinate dei pixel che compongono la figura.
3) varie ed eventuali che per ora non espongo per essere breve.
Qualcuno sa darmi un parere sulla strada che sto seguendo, oppure 
qualcuno ha fatto qualcosa del genere e sa darmi una dritta su come 
impostare il tutto?
Ringrazio anticipatamente, e mi scuso se il post è risultato piuttosto 
lungo.
ciao, roby
Inviato da X-Privat.Org - Registrazione gratuita 
http://www.x-privat.org/join.php

 matrice se nell'elemento (x,y) c'è o no un riferimento alla figura.
Se, buongiorno :-D
Ogni primitiva e' rappresentata da una o piu' equazioni (il cerchio da una, 
le patch da una, i poligoni da N -con N pari al numero di lati-, etc. etc.).
Metti X ed Y nelle equazioni e le risolvi.

 ha scritto nel messaggio 
news:vEl1g.87643$PR2.1...@twister2.libero.it...

Ah, questo ovviamente se vuoi usare un metodo "matematico".
Altrimenti, c'e' anche un trucchetto vecchio come il mondo (usato spesso in 
diverse applicazioni e funziona benissimo):
Crea un secondo buffer video, identico a quello principale, ma invisibile. 
Assegna ad ogni primitiva un ID numerico, progressivo ed univoco
(l'indice dell'array va' benissimo)
Quando l'utente disegna qualcosa sul buffer principale, tu disegnalo anche 
sull'altro **MA** usando come colore di foreground l'ID dell'oggetto.
Quando l'utente fa' click su un pixel nel buffer principale, controlla il 
colore del corrispondente pixel nel buffer secondario. Il colore del pixel 
indica l'oggetto selezionato.

 
Beh, questa mi sembra un'ottima idea.
Mi permetterebbe anche di risolvere problemi diversi come ZOOM ecc. e 
non devo sprecare tempo e risorse per calcolare tutti i punti con il 
metodo "matematico"
Stasera quando torno dal lavoro proverò. intanto grazie.
ciao,roby


 dei pixel che compongono la figura.
Non ho mai provato con forme diverse dal rettangolo, ma se tu vuoi ad es. 
che per un cerchio la figura venga selezionata solo se clicchi all'interno 
del cerchio puoi usare anzichè un test su Rectangle.Contains() un test su 
Region.IsVisible() (perchè abbiano chiamato così questo metodo mi rimane un 
mistero).
Nelle regioni puoi metterci la forma che vuoi, in particolare puoi creare 
una regione partendo da un GraphicsPath, che ha tutti i metodi AddXYZ() che 
ti permettono di sbizzarrirti nella creazione della forma che vuoi.
Consigli aggiuntivi:
1) Creati una classe base, ad es. Public Class Figura con tutte le proprietà 
comuni a tutte le figure che deciderai di fare, ad es.
Bounds As Rectangle
Contains(x, y) As Boolean
ecc
NON aggiungere una proprietà del tipo Shape as TipoDiFigura perchè non serve 
a un tubo se non a riempire il codice di If
Deriva da Figura tutte le altre, ad es.
Class Rectangle Inherits Figura
Class Ellipse Inherits Figura
Class Polygon Inherits Figura
ecc
2) Ricordati di fare una Dispose() su tutti gli oggetti della GDI appena non 
ti servono più, altrimenti dopo un po' ti si impalla tutto :)
Ciao 

 indica l'oggetto selezionato.
Se si segue questa strada occorre ricordarsi di ridisegnare il tutto se si 
cambia il piano Z di un oggetto.
Ciao 

 cambia il piano Z di un oggetto.
Si ridisegna tutto solamente nel caso di un riposizionamento X-Y di 
un'oggetto (teoricamente, poi si puo' ottimizzare anche qui).
Nel caso del cambio di piano, si ridisegna solo quando l'oggetto che cambia 
piano diventa il primo o era il primo. In tutti gli altri casi si puo' 
ignorare il cambio.

 puo' ignorare il cambio.
Non sono s'accordo.
Metti di avere 3 rettangoli
+---------+
| 1    +---------+
|      |    2    |
|   +--------+   |
|   |  3     |   |
+---|        |---+
    |        |
    +--------+
Se il triangolo 1 passa sopra il 2 va ridisegnato tutto, o almeno invalidata 
l'area del rettangolo in questione (a meno che tu non voglia ricalcolarti 
solo la parte nuovamente visibile del rettangolo, ma sarebbe solo più 
complesso e alla fine credo anche più lento).
Dato che non hai modo di sapere se 1 è visibile o no quando portato su 
(sempre a meno di calcoli un po' troppo complessi per lo scopo che si vuole 
raggiungere), ti conviene ridisegnare il tutto e buonanotte.
Ciao 

 Ciao 
eh già. provare per credere.
Grazie 1000, mi sei stato di ottimo aiuto.
ciao,roby
