Subject: RE : Get the collection of cells included in an EllipticalArc
From: Christophe Le Page (christophe.l@chula.ac.th)
Date: Thu Jan 22 2009 - 10:17:23 CET
Bonjour Fabrice,
For the origin of the ellipse, assuming that the method is to be activated
from an elementary spatial entity, no need to indicate it: just refer to the
centre of the elementary spatial entity.
For its extent, better not to use pixels but rather IS units (meters for
instance). Below are some standard methods to work with real landscape
distances when the spatial resolution has been defined (first method)
Cell class >> areaHa
"Getter accessor with default value = 0.25 Ha (spatial resolution)"
^area ifNil:[area := 0.25]
Cell class >> lengthMeters
^(self areaHa * 10000) sqrt
Cell >> distanceMetersTo: anotherCell
| x y |
x := (self numCol - anotherCell numCol) abs.
y := (self numLine - anotherCell numLine) abs.
^(x * x + (y * y)) sqrt * self class lengthMeters
Then the method to get cells belonging to en ellipse around a cell can be
written like this:
Cell >> ellipseExtent: aPoint startAngle: angle1 sweepAngle: angle2
"aPoint in meters; angles between 0 and 360"
"spatial grid should have been opened for this method to work"
"as it refers to images of the spatial entities defined when the spatial
grid opens"
| ellipse extentPixels selection ellipseComponents radius ring |
extentPixels := (aPoint x * self image bounds width / self class
lengthMeters)
@ (aPoint y * self image bounds height / self
class lengthMeters).
ellipse := EllipticalArc
boundingBox: (self center extent: extentPixels)
startAngle: angle1
sweepAngle: angle2.
ellipse := ellipse translatedBy: (ellipse bounds width / 2) negated
@ (ellipse bounds height / 2) negated.
selection := Set with: self.
ellipseComponents := Set new.
radius := 1.
[selection isEmpty not] whileTrue:
[ellipseComponents addAll: selection.
ring := self layerOfRadius: radius.
selection := ring select: [:c | ellipse regionIntersects: (c
image bounds translatedBy: c center)].
radius := radius + 1].
"ellipseComponents do: [:c | c color: #red].
ellipse displayFilledOn: self spaceModel vue graphicsContext.
self flash."
^ellipseComponents
This code can certainly be optimized, but at least it seems to do the job:
below a snap of the spatial grid after sending the message below to the cell
in yellow
self ellipseExtent: 2500@1500 startAngle: 0 sweepAngle: 360
I hope you will get what you need from this.
Sawatdee,
Clp
> -----Message d'origine-----
> De : owner-cormas@cirad.cirad.fr [mailto:owner-cormas@cirad.cirad.fr] De
> la part de Fabrice Vinatier
> Envoyé : mardi 30 décembre 2008 19:10
> À : Cormas forum
> Objet : Get the collection of cells included in an EllipticalArc
>
> Hello,
> In order to simulate the attraction radius of a trap in windy
> conditions, I want to collect the cells belonging to a
> spatialEntityElement of the form :
>
> ellipse := EllipticalArc
> boundingBox: (150 @ 175 extent: 100 @ 50)
> startAngle: 0
> sweepAngle: 360.
>
> Do you know how to proceed?
> Thanks in advance for your answer.
> Best regards,
>
> --
> Fabrice Vinatier
> Modélisation / Entomologie
>
> CIRAD - PRAM
> Unité de recherche Systèmes de culture bananes, plantains et ananas
>
> Téléphone : 05 96 42 30 58
>