Je cherche un moyen de calculer la zone, en pixels, d'une instance arbitraire de L'arrière-plan: j'ai java.awt.geom.area code>.
forme < / code> S dans mes applications pouvant se chevaucher. Je veux savoir à quel point un
forme code> chevauche une autre. La forme
code> s peut être asymétrique, tournée, etc. Si j'avais une fonction
de la zone code> (ou
zone code>), je pourrais utiliser le Intersection de deux
forme code> s comme: p>
5 Réponses :
Une approche serait de addendum 1: Utilisation de cette Calculatrice pour voir l'effet de Addendum 2: Compter les pixels peuvent avoir des problèmes de performance; L'échantillonnage peut aider. Si chaque Vous devrez peut-être valider les résultats empiriquement. P> p> remplissage () code> chacun échelonné et transformé
forme code>
avec une couleur différente à l'aide d'un alphacomposite code>
et comptez les pixels qui se chevauchent dans le sous-jacent raster code>
. alphacomposite.xor code>
montre que l'interssertion de Toutes deux couleurs opaques sont zéro. P> forme code> A> est raisonnablement convexe, il peut être possible d'estimer le chevauchement du rapport du
intersect () code> < / a> zone à la somme des zones du
forme code>
s ' getbounds2d () code>
. Par exemple, p>
Merci d'avoir souligné les options de rasterizing une partie de l'image et de la recherche de valeurs d'échantillonnage réelles.
Je pense que c'est plus précis, mais j'ai aussi suggéré une alternative potentiellement plus rapide qui pourrait être suffisante.
Pour trouver la zone d'un polygone à l'aide de l'extrait suivant: ici n est le nombre total de sommets et x [i] et y [i] sont les coordonnées x et y. d'un sommet i.
Notez que pour que cet algorithme fonctionne, le polygone doit être fermé. Il fonctionne sur des polygones ouverts. P> Vous pouvez trouver des alogrits mathématiques liés aux polygones ici . Vous devez le convertir en Code vous-même :) P> P>
Merci pour le lien. Ceci est une approche valide, mais pas une direction que je veux entrer. La forme code> S peut inclure des segments de courbe et peut être des compositions d'autres formes. Les maths deviennent trop velus pour que je puisse suivre.
@iter, vous pouvez utiliser un getPathiterator (affinetransform at, double planéité) code> pour se rapprocher de la courbe en tant que polygone. De plus, les constructeurs code> code> décomposeront la forme dans des composants non auto-interssers, de sorte que cet algorithme fonctionnera si vous l'adaptez pour utiliser un
pathiterator code>.
J'ai utilisé cette classe pour se rapprocher de la zone d'une forme dans l'un de mes projets. Il est lent mais à haute résolution, il peut encore être plus rapide que de compter des pixels (car le coût de comptage des pixels augmente quadratique avec la résolution, mais le nombre de segments de ligne sur le périmètre augmente linéairement.)
import static java.lang.Double.NaN; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.FlatteningPathIterator; import java.awt.geom.Line2D; import java.awt.geom.PathIterator; public abstract class Areas { public static double approxArea(Area area, double flatness, int limit) { PathIterator i = new FlatteningPathIterator(area.getPathIterator(identity), flatness, limit); return approxArea(i); } public static double approxArea(Area area, double flatness) { PathIterator i = area.getPathIterator(identity, flatness); return approxArea(i); } public static double approxArea(PathIterator i) { double a = 0.0; double[] coords = new double[6]; double startX = NaN, startY = NaN; Line2D segment = new Line2D.Double(NaN, NaN, NaN, NaN); while (! i.isDone()) { int segType = i.currentSegment(coords); double x = coords[0], y = coords[1]; switch (segType) { case PathIterator.SEG_CLOSE: segment.setLine(segment.getX2(), segment.getY2(), startX, startY); a += hexArea(segment); startX = startY = NaN; segment.setLine(NaN, NaN, NaN, NaN); break; case PathIterator.SEG_LINETO: segment.setLine(segment.getX2(), segment.getY2(), x, y); a += hexArea(segment); break; case PathIterator.SEG_MOVETO: startX = x; startY = y; segment.setLine(NaN, NaN, x, y); break; default: throw new IllegalArgumentException("PathIterator contains curved segments"); } i.next(); } if (Double.isNaN(a)) { throw new IllegalArgumentException("PathIterator contains an open path"); } else { return 0.5 * Math.abs(a); } } private static double hexArea(Line2D seg) { return seg.getX1() * seg.getY2() - seg.getX2() * seg.getY1(); } private static final AffineTransform identity = AffineTransform.getQuadrantRotateInstance(0); }
Je commenterais si je pouvais. Suraj, votre algorithme est correct, mais le code doit être dans votre code, la dernière vertice n'est pas prise en compte. Juste une petite édition :) p> p>
La réponse donnée n'est pas exacte, j'ai constaté que, après private int calcAreaSize(Area area){
int sum = 0;
float xBegin=0, yBegin=0, xPrev=0, yPrev=0, coords[] = new float[6];
for (PathIterator iterator1 = area.getPathIterator(null, 0.1); !iterator1.isDone(); iterator1.next()){
switch (iterator1.currentSegment(coords))
{
case PathIterator.SEG_MOVETO:
xBegin = coords[0]; yBegin = coords[1];
break;
case PathIterator.SEG_LINETO:
// the well-known trapez-formula
sum += (coords[0] - xPrev) * (coords[1] + yPrev) / 2.0;
break;
case PathIterator.SEG_CLOSE:
sum += (xBegin - xPrev) * (yBegin + yPrev) / 2.0;
break;
default:
// curved segments cannot occur, because we have a flattened ath
throw new InternalError();
}
xPrev = coords[0]; yPrev = coords[1];
}
return sum;
}
pourquoi doubler [] coordiens = nouveau double [6]; Et pas un autre index est utilisé?
Vous devriez être capable d'étendre la formule d'intersection du polygone aux courbes Bezier. Ensuite, vous pouvez utiliser des itérateurs de chemins pour obtenir des zones proches de toutes les formes / zones.