Toon posts:

[vb.net] coordinaten + contains

Pagina: 1
Acties:

Verwijderd

Topicstarter
ik heb een aantal, 50, rechthoeken getekent op mijn form. nu wil ik als je op 1 rechthoek klikt, dat er dan een msg komt: u heeft geklikt op rechthoek 34 bv. ik heb alle x- en y-coordinaten en width en height in een array gestopt. maar nu wil ik dus dat het programma met contains kijkt in welke rechthoek de geklikte coordinaat in voor komt.
bv. er is geklikt op point(123,456) dat betekent dus dat hij voorkomt in rechthoek met x- en y-coordinaten (120, 450) want de rechthoek is 40 breed en 50 hoog.

wie weet hoe ik dit kan doen. ik ben een btje gaan vogelen met contains, maar ik kom niet achter de coordinaten vanuit de array.

Verwijderd

Topicstarter
winforms

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 21-05 14:59

pjvandesande

GC.Collect(head);

Je zou met een foreach'lus even alle reactangles moeten controleren.

code:
1
2
3
4
5
6
7
8
9
10
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    foreach(Rectangle rect in _rectangles)
    {
        if(rect.Contains(e.X, e.Y))
        {
            // Voer hier iets uit met de rectangle
        }
    }
}

[ Voor 5% gewijzigd door pjvandesande op 19-09-2004 12:49 ]


Verwijderd

Topicstarter
het is mijn bedoeling om de coordinaten + maten (origineel) in een array te zetten met de naam van de rechthoek. Dan moeten de rechthoeken getekent worden, en als er dan op eentje geklikt wordt, moet hij de naam uit de array halen die bij de coordinaten hoort, zodat ik weet op welke rechthoek er geklikt is.

is het mogelijk om de rechthoeken achteraf pas te declareren, zoals:

dim i as short
for i = 1 to 100
public arraynaam(i, 1) as new rectangle(arraynaam(i, 2), arraynaam(i, 2), arraynaam(i, 3), arraynaam(i, 4))
next

dan haalt ie de coordinaten en namen uit de array. En kun je wel declareren achteraf zodat de variable in het hele programma bruikbaar is? En zo ja, met welk statement doe je dat dan?

[ Voor 4% gewijzigd door Verwijderd op 19-09-2004 18:52 . Reden: aanvulling ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 16:52
Waarom maak je geen custom 'Rectangle' object dat gebruik maakt van de .NET infrastructuur om een rectangle te tekenene, en dan kan je jouw eigen objecten in die array(list) bewaren.

https://fgheysels.github.io/


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 21-05 14:59

pjvandesande

GC.Collect(head);

whoami schreef op 20 september 2004 @ 08:40:
Waarom maak je geen custom 'Rectangle' object dat gebruik maakt van de .NET infrastructuur om een rectangle te tekenene, en dan kan je jouw eigen objecten in die array(list) bewaren.
Je kan zo iets doen als:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public struct RectAndCo : Rectangle
{
    private Point _orginalPoint;

    public Point OrginalPoint
    {
        get
        {
            return _orginalPoint;
        }
        set
        {
            _orginalPoint = value;
        }
    }

    public RectAndCo(Rectange rect, Point orginalPoint) : base(rect)
    {
        _orginalPoint = orginalPoint;
    }
}
Verwijderd schreef op 19 september 2004 @ 14:22:
dan haalt ie de coordinaten en namen uit de array. En kun je wel declareren achteraf zodat de variable in het hele programma bruikbaar is? En zo ja, met welk statement doe je dat dan?
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public struct DieArrayVulClass
{
    private ArrayList _dieArray;

        ...

    public RectAndCo[] FunctieMetDieLus()
    {
        _dieArray = new ArrayList(100); 

        for(int i = 0; i < 100; i++)
        {
            _dieArray.Add((new rectangle(
                arraynaam(i, 2), arraynaam(i, 2),
                arraynaam(i, 3), arraynaam(i, 4)), 
                new Point(orgineleX, orgineleY);
        }

        return (RectAndCo[])_dieArray.ToArray(typeof(RectAndCo));
    }
}

Verwijderd

Topicstarter
wat eigenlijk mijn bedoeling is, is om die rectangles te declareren, zodat je met rectangle.contains kan kijken of die coordinaat in de rectangle voorkomt. zodat je kunt kijken of er op die rectangle geklikt is.
Ik heb al wel goede oplossingen gevonden, om er een klasse van te maken zodat hij zo en zo al public is. wat ik eigenlijk alleen nog wil weten, is of je dus kan declareren in een loop. ik heb veel op msdn gekeken, maar kan alleen wat lezen over de scope..

hier een voorbeeld over wat ik wil.

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
dim  i as short
for i = 0 to 100
     public arraynaam(i, 1) as new rectangle(arraynaam(i, 2), arraynaam(i, 3),
     arraynaam(i, 4), arraynaam(i, 5))
next




sub form_click()

dim i as short
for i = 0 to 100
    if arraynaam(i,1).contains(e.x, e.y) then
        msgbox "Er is op deze rectangle geklikt."
    end if
next
exit sub


nu is het dus de bedoeiling dat hij de gegevens uit de array invult in de statements.. maar jah, zie dat maar eens voor elkaar te krijgen.. 8)7

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 21-05 14:59

pjvandesande

GC.Collect(head);

Als de arraylist of array een class member is en je vult hem in een lus, vallen deze binnen de scope van de classe. Dus zullen gewoon blijven bestaan.
Verwijderd schreef op 20 september 2004 @ 10:17:
nu is het dus de bedoeiling dat hij de gegevens uit de array invult in de statements.. maar jah, zie dat maar eens voor elkaar te krijgen.. 8)7
Dat wil gewoon met de code die ik hier boven heb gepost. Zolang je een carray vult met een groteren scope van alleen die lus of method (functie), dus een classmember met de scope van de gehele class kun je deze gewoon vullen in een lusje.

edit:
Quote en reactie toegevoegd.

[ Voor 67% gewijzigd door pjvandesande op 20-09-2004 10:31 ]


  • FireWood
  • Registratie: Augustus 2003
  • Laatst online: 17:27
code:
1
2
3
4
5
6
7
8
9
sub form_click()

dim i as short
for i = 0 to 100
    if arraynaam(i,1).contains(e.x, e.y) then
        msgbox "Er is op deze rectangle geklikt."
    end if
next
exit sub


Bij mij werkt dat stuk gewoon wat je hebt getypt. Ik zelf heb deze algoritme een week of vier geleden zelf gebouwd, het word moeilijker met lijnen :)

Dit is problematischer:

code:
1
2
3
4
5
dim  i as short
for i = 0 to 100
     public arraynaam(i, 1) as new rectangle(arraynaam(i, 2), arraynaam(i, 3),
     arraynaam(i, 4), arraynaam(i, 5))
next


je declareert een variabele in een loop, wat zowiezo onduidelijkheid geeft, terwijl het ook geen nut heeft. dit is al wat beter:

code:
1
2
3
4
5
6
7
8
9
10
dim arraynaam(,) as new ....          'staat ergens bovenin

sub ....
dim  i as short
for i = 0 to 100
'breid array uit met één laag
     arraynaam(i,1) = new rectangle(arraynaam(i, 2), arraynaam(i, 3),
        arraynaam(i, 4),  arraynaam(i, 5)
next
end sub


code technisch klopt er geen zak van, maar dit is denk ik wel mogelijk, dus niet steeds opnieuw declareren, dat kan namelijk niet.

Nog betere oplossing:

Waarom zet je een rectangle rechtstreeks in een array? kun je dit niet pas uitvoeren aan het einde? Bespaart geheugen, en warschijnlijk kost het verder geen performence.

[ Voor 102% gewijzigd door FireWood op 20-09-2004 22:32 . Reden: toevoegingen ]

Noobs don't use "F1", Pro's do, but they can't find the information they needed


  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

Ik heb zoiets zelf al gebouwd, maar wel op een totaal andere manier. Ik ben namelijk niet zo gecharmeerd van die arrays (x,1), (x,2), enz. waarbij elke cijfer een bepaalde betekenis heeft. Qua structuur is dat helemaal niks. Voor iemand die de code niet kent, is het toch verwarrend of is de volgorde voor hem minder logisch dan voor jou. Ik stel een Enum voor om dat te verhelpen.

Wat ik heb gedaan is het volgende: Ik had een tabel in een database met daarin alle locaties van containers. Elke regel bevatte een rectangle. Ik weet niet meer wat er in de tabel stond, maar ik denk dan aan de coördinaten linksboven en rechtsonder (of de rectangle-info, dus linksboven en de size).

Als je vervolgens de tabel in een dataset laadt, heb je én de informatie om de rectangle en alle tools om de positie te bepalen.
In de datatable kan je een Select aangroepen. Je hebt een coördinaat en vervolgens selecteer je alle DataRows waarbij 'e.x>linksboven.x AND e.y>linksboven.y AND e.x<rechstonder.x AND e.y<rechtsonder.y' (waarbij rechtonder ook een combinatie van linksboven en size kan zijn).

Vervolgens krijg je één of meer DataRows terug waar de cursor in staat. Dan kan je met de ID van die DataRow weer andere informatie ophalen, etc...

Echt veel makkelijker kan het niet dacht ik 8)
En gebruik strongtyped datasets, dat maakt het wat makkelijker.

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 21-05 14:59

pjvandesande

GC.Collect(head);

Chief.NET schreef op 20 september 2004 @ 22:25:Echt veel makkelijker kan het niet dacht ik 8)
En gebruik strongtyped datasets, dat maakt het wat makkelijker.
Dit lijkt mij niet echt de makkelijkste oplossing. Eerlijk gezecht vind ik het helemaal niet.
Een array met een custom class er in lijkt mij veel beter, of als hij alleen X en Y nodig heeft een array vol met objecten van het type Point, of met X, Y, Width en Height natuurlijk een Rectangle.

Je gebruikt wel een strongtyped dataset, dat maakt het nog een beetje goed, maar ik kan me er toch nog weinig mee voorstellen. Zeker als je maar praat over 100 objecten.

  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

Het verschil is wel dat je elke keer een hele array moeten doorlopen waarbij je gaat testen of het punt wat je hebt in een opgegeven rectangle valt.

De vraag is uiteindelijk: hoe vul je de custom rectangleclass? Als je dat in code doet (lijkt me stug, ook al met 100 items) maakt het niet veel uit. Komt het uit een database, waarom zou je dan de hele handel ombouwen in een custom class? De DataTabel doet het al voor je.

In principe is het zo dat dergelijke info altijd komt uit iets wat ook in de vorm van een DataTable uit te drukken is (of uit te drukken zou moeten zijn, want het is data). Dan is een DataTable.Select het eenvoudigst, want het is maar één regel code.

En ik heb het idee dat een DataTable.Select sneller is dan een lijst doorlopen. Toen ik mijn systeem bouwde kwam de informatie waarmee ik tekende al uit een DataTable en ging het over 3000 regels, maargoed... dat zou niet eens uit moeten maken. Alles wat ik niet op één hand kan tellen, vind ik al veel.

edit:
Okee, misschien draaf ik wat ver door, maar dergelijke applicaties zie ik niet zonder een database.

[ Voor 6% gewijzigd door MrSleeves op 21-09-2004 11:21 ]

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 21-05 14:59

pjvandesande

GC.Collect(head);

Chief.NET schreef op 21 september 2004 @ 11:07:Het verschil is wel dat je elke keer een hele array moeten doorlopen waarbij je gaat testen of het punt wat je hebt in een opgegeven rectangle valt.
Ik had zelf rectangles met elke keer dezelfde afstand, dus kon aan der hand van een berekening.

Maar opzich 300 items controleren of ze een punt bevatten is niet zo veel, je dataset doet zo iets intern ook zo ongeveer.
Dan is een DataTable.Select het eenvoudigst, want het is maar één regel code.
Dit is zeker waar.
Pagina: 1