From 8ecdf7569c4b5bfcd58142e9d1498e747791dfab Mon Sep 17 00:00:00 2001 From: "J. Neugebauer" Date: Thu, 23 Dec 2021 09:22:32 +0100 Subject: [PATCH] OOP Version: Formen-Klassen --- .../ngb/zm/formen/AbgerundetesRechteck.java | 59 +++++ src/schule/ngb/zm/formen/Bild.java | 147 ++++++++++++ src/schule/ngb/zm/formen/Bogen.java | 110 +++++++++ src/schule/ngb/zm/formen/Drache.java | 117 +++++++++ src/schule/ngb/zm/formen/Dreieck.java | 32 +++ src/schule/ngb/zm/formen/Ellipse.java | 93 ++++++++ src/schule/ngb/zm/formen/Form.java | 225 ++++++++++++++++++ src/schule/ngb/zm/formen/FormGruppe.java | 103 ++++++++ src/schule/ngb/zm/formen/Formenebene.java | 70 ++++++ src/schule/ngb/zm/formen/Freiform.java | 40 ++++ src/schule/ngb/zm/formen/Fuellform.java | 49 ++++ src/schule/ngb/zm/formen/Konturform.java | 114 +++++++++ src/schule/ngb/zm/formen/Kreis.java | 67 ++++++ src/schule/ngb/zm/formen/Kurve.java | 183 ++++++++++++++ src/schule/ngb/zm/formen/Linie.java | 92 +++++++ src/schule/ngb/zm/formen/Pfeil.java | 137 +++++++++++ src/schule/ngb/zm/formen/Punkt.java | 34 +++ src/schule/ngb/zm/formen/Raute.java | 38 +++ src/schule/ngb/zm/formen/Rechteck.java | 107 +++++++++ src/schule/ngb/zm/formen/Text.java | 134 +++++++++++ src/schule/ngb/zm/formen/Vieleck.java | 72 ++++++ src/schule/ngb/zm/formen/Viereck.java | 34 +++ 22 files changed, 2057 insertions(+) create mode 100644 src/schule/ngb/zm/formen/AbgerundetesRechteck.java create mode 100644 src/schule/ngb/zm/formen/Bild.java create mode 100644 src/schule/ngb/zm/formen/Bogen.java create mode 100644 src/schule/ngb/zm/formen/Drache.java create mode 100644 src/schule/ngb/zm/formen/Dreieck.java create mode 100644 src/schule/ngb/zm/formen/Ellipse.java create mode 100644 src/schule/ngb/zm/formen/Form.java create mode 100644 src/schule/ngb/zm/formen/FormGruppe.java create mode 100644 src/schule/ngb/zm/formen/Formenebene.java create mode 100644 src/schule/ngb/zm/formen/Freiform.java create mode 100644 src/schule/ngb/zm/formen/Fuellform.java create mode 100644 src/schule/ngb/zm/formen/Konturform.java create mode 100644 src/schule/ngb/zm/formen/Kreis.java create mode 100644 src/schule/ngb/zm/formen/Kurve.java create mode 100644 src/schule/ngb/zm/formen/Linie.java create mode 100644 src/schule/ngb/zm/formen/Pfeil.java create mode 100644 src/schule/ngb/zm/formen/Punkt.java create mode 100644 src/schule/ngb/zm/formen/Raute.java create mode 100644 src/schule/ngb/zm/formen/Rechteck.java create mode 100644 src/schule/ngb/zm/formen/Text.java create mode 100644 src/schule/ngb/zm/formen/Vieleck.java create mode 100644 src/schule/ngb/zm/formen/Viereck.java diff --git a/src/schule/ngb/zm/formen/AbgerundetesRechteck.java b/src/schule/ngb/zm/formen/AbgerundetesRechteck.java new file mode 100644 index 0000000..49e9bff --- /dev/null +++ b/src/schule/ngb/zm/formen/AbgerundetesRechteck.java @@ -0,0 +1,59 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; + +public class AbgerundetesRechteck extends Rechteck { + + protected double rundung = 1.0; + + public AbgerundetesRechteck( double pX, double pY, double pBreite, double pHoehe, double pRundung ) { + super(pX, pY, pBreite, pHoehe); + rundung = pRundung; + } + + public AbgerundetesRechteck( Rechteck pRechteck ) { + super( + pRechteck.x, pRechteck.y, + pRechteck.breite, pRechteck.hoehe); + kopiere(pRechteck); + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + if( pForm instanceof AbgerundetesRechteck ) { + AbgerundetesRechteck rechteck = (AbgerundetesRechteck) pForm; + rundung = rechteck.rundung; + } + } + + @Override + public Shape getShape() { + return new RoundRectangle2D.Double( + 0, 0, breite, hoehe, rundung, rundung + ); + } + + @Override + public boolean equals( Object o ) { + if( this == o ) return true; + if( o == null || getClass() != o.getClass() ) return false; + AbgerundetesRechteck rechteck = (AbgerundetesRechteck) o; + return super.equals(o) && + Double.compare(rechteck.rundung, rundung) == 0; + } + + @Override + public String toString() { + return getClass().getCanonicalName() + "[" + + "x=" + x + + ",y=" + y + + ",breite=" + breite + + ",hoehe=" + hoehe + + ",rundung=" + rundung + + ']'; + } + +} diff --git a/src/schule/ngb/zm/formen/Bild.java b/src/schule/ngb/zm/formen/Bild.java new file mode 100644 index 0000000..d9365f7 --- /dev/null +++ b/src/schule/ngb/zm/formen/Bild.java @@ -0,0 +1,147 @@ +package schule.ngb.zm.formen; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.net.URL; + +public class Bild extends Form { + + private double breite; + + private double hoehe; + + private BufferedImage bild; + + public Bild( String pQuelle ) { + this(0, 0, pQuelle); + } + + public Bild( double pX, double pY, String pQuelle ) { + super(pX, pY); + + if( pQuelle == null || pQuelle.length() == 0 ) + throw new IllegalArgumentException("Bildquelle darf nicht null oder leer sein."); + + try { + // Bilddatei aus dem Arbeitsverzeichnis laden + File file = new File(pQuelle); + if( file.isFile() ) { + bild = ImageIO.read(file); + } else { + // relativ zur .class-Datei + URL url = getClass().getResource(pQuelle); + + // relativ zum ClassLoader + if( url == null ) { + url = getClass().getClassLoader().getResource(pQuelle); + } + + // aWebadresse oder JAR-Datei + if( url == null ) { + url = new URL(pQuelle); + } + + bild = ImageIO.read(url); + } + + if( bild == null ) { + throw new IllegalArgumentException("Bild konnte nicht aus " + pQuelle + " geladen werden!"); + } + + breite = bild.getWidth(null); + hoehe = bild.getHeight(null); + setAnkerpunkt(ZENTRUM); + } catch( IOException ioe ) { + throw new IllegalArgumentException("Bild konnte nicht aus " + pQuelle + " geladen werden!", ioe); + } + } + + public Bild( Bild pBild ) { + super(pBild.getX(), pBild.getY()); + kopiere(pBild); + } + + @Override + public Form kopie() { + return new Bild(this); + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + if( pForm instanceof Bild ) { + Bild pBild = (Bild)pForm; + bild = new BufferedImage(pBild.bild.getWidth(), pBild.bild.getHeight(), pBild.bild.getType()); + Graphics2D g = bild.createGraphics(); + g.drawImage(pBild.bild, 0, 0, null); + g.dispose(); + + breite = bild.getWidth(null); + hoehe = bild.getHeight(null); + setAnkerpunkt(pForm.getAnkerpunkt()); + } + } + + public double getBreite() { + return breite; + } + + public void setBreite( double pBreite ) { + skalieren(pBreite / breite); + } + + public double getHoehe() { + return hoehe; + } + + public void setHoehe( double pHoehe ) { + skalieren(pHoehe / hoehe); + } + + @Override + public void setAnkerpunkt( byte pAnker ) { + ankerBerechnen(breite, hoehe, pAnker); + } + + @Override + public void skalieren( double pFaktor ) { + super.skalieren(pFaktor); + breite *= pFaktor; + hoehe *= pFaktor; + } + + @Override + public Shape getShape() { + return new Rectangle2D.Double(0, 0, breite, hoehe); + } + + /* + @Override + public AffineTransform getVerzerrung() { + AffineTransform verzerrung = new AffineTransform(); + verzerrung.translate(x, y); + verzerrung.scale(skalierung, skalierung); + verzerrung.rotate(Math.toRadians(drehwinkel)); + verzerrung.translate(-anker.x, -anker.y); + return verzerrung; + } + */ + + @Override + public void zeichnen( Graphics2D graphics, AffineTransform pVerzerrung ) { + if( !sichtbar ) { + return; + } + + AffineTransform current = graphics.getTransform(); + graphics.transform(getVerzerrung()); + graphics.drawImage(bild, 0, 0, (int) breite, (int) hoehe, null); + graphics.setTransform(current); + } + +} diff --git a/src/schule/ngb/zm/formen/Bogen.java b/src/schule/ngb/zm/formen/Bogen.java new file mode 100644 index 0000000..c4ef3f9 --- /dev/null +++ b/src/schule/ngb/zm/formen/Bogen.java @@ -0,0 +1,110 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Arc2D; + +public class Bogen extends Form { + + protected double breite; + + protected double hoehe; + + protected double winkel; + + protected double startwinkel; + + protected int typ = OFFEN; + + public Bogen( double pX, double pY, double pRadius, double pWinkel ) { + this(pX, pY, pRadius, pRadius, pWinkel, 0.0); + } + + public Bogen( double pX, double pY, double pRadius, double pWinkel, double pStartwinkel ) { + this(pX, pY, pRadius, pRadius, pWinkel, pStartwinkel); + } + + public Bogen( double pX, double pY, double pBreite, double pHoehe, double pWinkel, double pStartwinkel ) { + super(pX, pY); + breite = pBreite; + hoehe = pHoehe; + winkel = pWinkel; + startwinkel = pStartwinkel; + setAnkerpunkt(ZENTRUM); + + keineFuellung(); + } + + public Bogen( Bogen pBogen ) { + this(pBogen.x, pBogen.y, pBogen.breite, pBogen.hoehe, pBogen.winkel, pBogen.startwinkel); + kopiere(pBogen); + } + + public double getBreite() { + return breite; + } + + public void setBreite( double pBreite ) { + this.breite = pBreite; + } + + public double getHoehe() { + return hoehe; + } + + public void setHoehe( double pHoehe ) { + this.hoehe = pHoehe; + } + + public double getWinkel() { + return winkel; + } + + public void setWinkel( double pWinkel ) { + this.winkel = pWinkel; + } + + public double getStartwinkel() { + return startwinkel; + } + + public void setStartwinkel( double pStartwinkel ) { + this.startwinkel = pStartwinkel; + } + + public int getTyp() { + return typ; + } + + public void setTyp( int pTyp ) { + this.typ = pTyp; + } + + @Override + public Form kopie() { + return new Bogen(this); + } + + @Override + public void kopiere(Form pForm) { + super.kopiere(pForm); + if( pForm instanceof Bogen ) { + Bogen b = (Bogen) pForm; + breite = b.breite; + hoehe = b.hoehe; + winkel = b.winkel; + startwinkel = b.startwinkel; + typ = b.typ; + } + } + + @Override + public void setAnkerpunkt( byte pAnker ) { + ankerBerechnen(breite, hoehe, pAnker); + } + + @Override + public Shape getShape() { + return new Arc2D.Double(0, 0, breite, hoehe, startwinkel, winkel, typ); + } + +} diff --git a/src/schule/ngb/zm/formen/Drache.java b/src/schule/ngb/zm/formen/Drache.java new file mode 100644 index 0000000..69415da --- /dev/null +++ b/src/schule/ngb/zm/formen/Drache.java @@ -0,0 +1,117 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Path2D; + +public class Drache extends Form { + + private double breite; + + private double hoehe; + + private double verhaeltnis; + + public Drache( double pX, double pY, double pBreite, double pHoehe ) { + this(pX, pY, pBreite, pHoehe, 0.5); + } + + public Drache( double pX, double pY, double pBreite, double pHoehe, double pVerhaeltnis ) { + super(pX, pY); + breite = pBreite; + hoehe = pHoehe; + verhaeltnis = pVerhaeltnis; + setAnkerpunkt(ZENTRUM); + } + + public Drache( Drache pDrache ) { + this(pDrache.x, pDrache.y, pDrache.breite, pDrache.hoehe, pDrache.verhaeltnis); + kopiere(pDrache); + } + + public double getBreite() { + return breite; + } + + public void setBreite( double breite ) { + this.breite = breite; + } + + public double getHoehe() { + return hoehe; + } + + public void setHoehe( double hoehe ) { + this.hoehe = hoehe; + } + + public double getVerhaeltnis() { + return verhaeltnis; + } + + public void setVerhaeltnis( double pVerhaeltnis ) { + this.verhaeltnis = pVerhaeltnis; + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + if( pForm instanceof Drache ) { + Drache d = (Drache) pForm; + breite = d.breite; + hoehe = d.hoehe; + verhaeltnis = d.verhaeltnis; + } + } + + @Override + public Drache kopie() { + return new Drache(this); + } + + @Override + public void skalieren( double pFaktor ) { + super.skalieren(pFaktor); + breite *= pFaktor; + hoehe *= pFaktor; + } + + @Override + public void setAnkerpunkt( byte pAnker ) { + ankerBerechnen(breite, hoehe, pAnker); + } + + @Override + public Shape getShape() { + double bHalb = breite * .5, hVerh = verhaeltnis*hoehe; + Path2D shape = new Path2D.Double(); + shape.moveTo(bHalb, 0); + shape.lineTo(breite, hVerh); + shape.lineTo(bHalb, hoehe); + shape.lineTo(0, hVerh); + shape.closePath(); + return shape; + } + + @Override + public boolean equals( Object o ) { + if( this == o ) return true; + if( o == null || getClass() != o.getClass() ) return false; + Drache d = (Drache) o; + return super.equals(o) && + Double.compare(d.breite, breite) == 0 && + Double.compare(d.hoehe, hoehe) == 0 && + Double.compare(d.verhaeltnis, verhaeltnis) == 0; + } + + @Override + public String toString() { + return getClass().getCanonicalName() + '[' + + "breite=" + breite + + ",hoehe=" + hoehe + + ",verhaeltnis=" + verhaeltnis + + ",x=" + x + + ",y=" + y + + ']'; + } + +} diff --git a/src/schule/ngb/zm/formen/Dreieck.java b/src/schule/ngb/zm/formen/Dreieck.java new file mode 100644 index 0000000..e119003 --- /dev/null +++ b/src/schule/ngb/zm/formen/Dreieck.java @@ -0,0 +1,32 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Point2D; +import java.util.Arrays; + +public class Dreieck extends Vieleck { + + public Dreieck( double pX, double pY, Point2D... pEcken ) { + super(pX, pY, Arrays.copyOf(pEcken, 3)); + if( pEcken.length < 3 ) { + throw new IllegalArgumentException("Ein Dreieck muss genau drei Eckpunkte besitzen."); + } + } + + public Dreieck( Point2D... pEcken ) { + super(Arrays.copyOf(pEcken, 3)); + if( pEcken.length < 3 ) { + throw new IllegalArgumentException("Ein Dreieck muss genau drei Eckpunkte besitzen."); + } + } + + public Dreieck( Dreieck pDreieck ) { + super(pDreieck.x, pDreieck.y); + kopiere(pDreieck); + } + + @Override + public Form kopie() { + return new Dreieck(this); + } +} diff --git a/src/schule/ngb/zm/formen/Ellipse.java b/src/schule/ngb/zm/formen/Ellipse.java new file mode 100644 index 0000000..e0dd1e2 --- /dev/null +++ b/src/schule/ngb/zm/formen/Ellipse.java @@ -0,0 +1,93 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Ellipse2D; + +public class Ellipse extends Form { + + private double breite; + + private double hoehe; + + public Ellipse( double pX, double pY, double pBreite, double pHoehe ) { + super(pX, pY); + breite = pBreite; + hoehe = pHoehe; + setAnkerpunkt(ZENTRUM); + } + + public Ellipse( Ellipse pEllipse ) { + this(pEllipse.x, pEllipse.y, pEllipse.breite, pEllipse.hoehe); + kopiere(pEllipse); + } + + public double getBreite() { + return breite; + } + + public void setBreite( double breite ) { + this.breite = breite; + } + + public double getHoehe() { + return hoehe; + } + + public void setHoehe( double hoehe ) { + this.hoehe = hoehe; + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + if( pForm instanceof Ellipse ) { + Ellipse e = (Ellipse) pForm; + breite = e.breite; + hoehe = e.hoehe; + } + } + + @Override + public Ellipse kopie() { + return new Ellipse(this); + } + + @Override + public void skalieren( double pFaktor ) { + super.skalieren(pFaktor); + breite *= pFaktor; + hoehe *= pFaktor; + } + + @Override + public void setAnkerpunkt( byte pAnker ) { + ankerBerechnen(breite, hoehe, pAnker); + } + + @Override + public Shape getShape() { + Shape shape = new Ellipse2D.Double(0, 0, breite, hoehe); + return shape; + } + + @Override + public boolean equals( Object o ) { + if( this == o ) return true; + if( o == null || getClass() != o.getClass() ) return false; + Ellipse ellipse = (Ellipse) o; + return super.equals(o) && + Double.compare(ellipse.breite, breite) == 0 && + Double.compare(ellipse.hoehe, hoehe) == 0; + } + + @Override + public String toString() { + return getClass().getCanonicalName() + '[' + + "breite=" + breite + + ",hoehe=" + hoehe + + ",x=" + x + + ",y=" + y + + ']'; + } + +} diff --git a/src/schule/ngb/zm/formen/Form.java b/src/schule/ngb/zm/formen/Form.java new file mode 100644 index 0000000..31284e8 --- /dev/null +++ b/src/schule/ngb/zm/formen/Form.java @@ -0,0 +1,225 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +public abstract class Form extends Fuellform { + + + protected double x; + + protected double y; + + protected double drehwinkel = 0.0; + + protected double skalierung = 1.0; + + protected boolean sichtbar = true; + + protected Point2D.Double anker = new Point2D.Double(); + + FormGruppe gruppe = null; + + public Form( double pX, double pY ) { + x = pX; + y = pY; + } + + public Form() { + this(0.0, 0.0); + } + + public double getX() { + return x; + } + + public void setX( double x ) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY( double y ) { + this.y = y; + } + + public double getDrehwinkel() { + return drehwinkel; + } + + public double getSkalierung() { + return skalierung; + } + + public boolean istSichtbar() { + return sichtbar; + } + + public void verstecken() { + sichtbar = false; + } + + public void zeigen() { + sichtbar = true; + } + + public void umschalten() { + sichtbar = !sichtbar; + } + + public Point2D.Double getAnkerpunkt() { + return new Point2D.Double(anker.x, anker.y); + } + + public void setAnkerpunkt( byte pAnker ) { + Shape shape = getShape(); + if( shape != null ) { + Rectangle2D bounds = shape.getBounds2D(); + ankerBerechnen(bounds.getWidth(), bounds.getHeight(), pAnker); + } else { + anker.x = 0; + anker.y = 0; + } + } + + public void setAnkerpunkt( Point2D.Double pAnker ) { + anker.x = pAnker.x; + anker.y = pAnker.y; + } + + protected void ankerBerechnen( double pBreite, double pHoehe, byte pAnker ) { + double bHalb = pBreite * .5, hHalb = pHoehe * .5; + // pAnker == CENTER + anker.x = bHalb; + anker.y = hHalb; + if( (pAnker & NORDEN) == NORDEN ) { + anker.y -= hHalb; + } + if( (pAnker & SUEDEN) == SUEDEN ) { + anker.y += hHalb; + } + if( (pAnker & WESTEN) == WESTEN ) { + anker.x -= bHalb; + } + if( (pAnker & OSTEN) == OSTEN ) { + anker.x += bHalb; + } + } + + public void kopiere( Form pForm ) { + verschiebeNach(pForm); + setFuellfarbe(pForm.getFuellfarbe()); + setKonturFarbe(pForm.getKonturFarbe()); + setKonturDicke(pForm.getKonturDicke()); + setKonturArt(pForm.getKonturArt()); + sichtbar = pForm.istSichtbar(); + drehwinkel = pForm.drehwinkel; + skalieren(pForm.skalierung); + setAnkerpunkt(pForm.getAnkerpunkt()); + } + + public abstract Form kopie(); + + public Rechteck getBegrenzung() { + return new Rechteck(this); + } + + public void verschieben( double dx, double dy ) { + x += dx; + y += dy; + } + + public void verschiebeNach( double pX, double pY ) { + x = pX; + y = pY; + } + + public void verschiebeNach( Form pForm ) { + verschiebeNach(pForm.x, pForm.y); + } + + public void skalieren( double pFaktor ) { + skalierung = pFaktor; + anker.x *= pFaktor; + anker.y *= pFaktor; + } + + public void skalierenUm( double pFaktor ) { + skalieren(skalierung * pFaktor); + } + + public void drehen( double pWinkel ) { + drehwinkel += pWinkel % 360; + } + + public void drehenNach( double pWinkel ) { + drehwinkel = pWinkel % 360; + } + + /*public void scheren( double dx, double dy ) { + verzerrung.shear(dx, dy); + }*/ + + public AffineTransform getVerzerrung() { + AffineTransform verzerrung = new AffineTransform(); + verzerrung.translate(x, y); + verzerrung.rotate(Math.toRadians(drehwinkel)); + //verzerrung.scale(skalierung, skalierung); + verzerrung.translate(-anker.x, -anker.y); + return verzerrung; + } + + public final void zeichnen( Graphics2D graphics ) { + zeichnen(graphics, getVerzerrung()); + } + + /** + * Zeichnet die Form, aber wendet zuvor noch eine zusätzliche Transformations- + * matrix an. Wird u.A. von der {@link FormGruppe} verwendet. + * @param graphics + * @param pVerzerrung + */ + public void zeichnen( Graphics2D graphics, AffineTransform pVerzerrung ) { + if( !sichtbar ) { + return; + } + + Shape shape = getShape(); + if( shape != null ) { + if( pVerzerrung != null ) { + shape = pVerzerrung.createTransformedShape(shape); + } + + Color currentColor = graphics.getColor(); + if( fuellFarbe != null && fuellFarbe.getAlpha() > 0 ) { + graphics.setColor(fuellFarbe); + graphics.fill(shape); + } + if( konturFarbe != null && konturFarbe.getAlpha() > 0 + && konturDicke > 0.0 ) { + graphics.setColor(konturFarbe); + graphics.setStroke(createStroke()); + graphics.draw(shape); + } + graphics.setColor(currentColor); + } + } + + public abstract Shape getShape(); + + @Override + public boolean equals( Object o ) { + if( this == o ) return true; + if( o == null || getClass() != o.getClass() ) return false; + Form form = (Form) o; + return Double.compare(form.x, x) == 0 && + Double.compare(form.y, y) == 0 && + Double.compare(form.drehwinkel, drehwinkel) == 0 && + Double.compare(form.skalierung, skalierung) == 0; + } + +} diff --git a/src/schule/ngb/zm/formen/FormGruppe.java b/src/schule/ngb/zm/formen/FormGruppe.java new file mode 100644 index 0000000..437dc45 --- /dev/null +++ b/src/schule/ngb/zm/formen/FormGruppe.java @@ -0,0 +1,103 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.geom.Path2D; +import java.util.ArrayList; +import java.util.List; + +public class FormGruppe extends Form { + + private List
formen; + + public FormGruppe() { + super(); + formen = new ArrayList<>(10); + } + + public FormGruppe( double pX, double pY ) { + super(pX, pY); + formen = new ArrayList<>(10); + } + + public FormGruppe( double pX, double pY, Form... pFormen ) { + super(pX, pY); + formen = new ArrayList<>(pFormen.length); + for( Form form : pFormen ) { + formen.add(form); + form.gruppe = this; + } + setAnkerpunkt(ZENTRUM); + } + + public Form kopie() { + return null; + } + + public void hinzu( Form... pFormen ) { + for( Form form : pFormen ) { + hinzu(form, false); + } + } + + public void hinzu( Form pForm ) { + hinzu(pForm, false); + } + + public void hinzu( Form pForm, boolean pKoordinatenAnpassen ) { + if( pKoordinatenAnpassen ) { + pForm.x = pForm.x - x; + pForm.y = pForm.y - y; + } + formen.add(pForm); + pForm.gruppe = this; + } + + @Override + public void setAnkerpunkt( byte pAnker ) { + double minx = Double.MAX_VALUE, miny = Double.MAX_VALUE, + maxx = Double.MIN_VALUE, maxy = Double.MIN_VALUE; + for( Form form : formen ) { + Rechteck bounds = form.getBegrenzung(); + if( bounds.x < minx ) + minx = bounds.x; + if( bounds.y < miny ) + miny = bounds.y; + if( bounds.x+bounds.breite > maxx ) + maxx = bounds.x+bounds.breite; + if( bounds.y+bounds.hoehe > maxy ) + maxy = bounds.y+bounds.hoehe; + } + + ankerBerechnen(maxx-minx, maxy-miny, pAnker); + } + + @Override + public Shape getShape() { + Path2D.Double gruppe = new Path2D.Double(); + for( Form form : formen ) { + gruppe.append(form.getShape(), false); + } + return gruppe; + } + + @Override + public void zeichnen( Graphics2D graphics, AffineTransform pVerzerrung ) { + if( !sichtbar ) { + return; + } + + AffineTransform verzerrung = new AffineTransform(); + verzerrung.translate(x, y); + verzerrung.rotate(Math.toRadians(drehwinkel)); + //verzerrung.scale(skalierung, skalierung); + verzerrung.translate(-anker.x, -anker.y); + + for( Form f: formen ) { + AffineTransform af = f.getVerzerrung(); + af.preConcatenate(verzerrung); + f.zeichnen(graphics, af); + } + } + +} diff --git a/src/schule/ngb/zm/formen/Formenebene.java b/src/schule/ngb/zm/formen/Formenebene.java new file mode 100644 index 0000000..4285e75 --- /dev/null +++ b/src/schule/ngb/zm/formen/Formenebene.java @@ -0,0 +1,70 @@ +package schule.ngb.zm.formen; + +import schule.ngb.zm.Ebene; + +import java.awt.*; +import java.util.ArrayList; +import java.util.LinkedList; + +public class Formenebene extends Ebene { + + private LinkedList formen; + + public Formenebene() { + super(); + formen = new LinkedList(); + } + + public Formenebene( int pWidth, int pHeight ) { + super(pWidth, pHeight); + formen = new LinkedList(); + } + + public void anzeigen( Form... pFormen ) { + synchronized( formen ) { + for( Form f: pFormen ) { + formen.add(f); + } + } + } + + public void alleVerstecken() { + synchronized( formen ) { + for( Form form : formen ) { + form.verstecken(); + } + } + } + + public void alleZeigen() { + synchronized( formen ) { + for( Form form : formen ) { + form.zeigen(); + } + } + } + + public void leeren() { + Color currentColor = zeichnung.getBackground(); + zeichnung.setBackground(new Color(0, 0, 0, 0)); + zeichnung.clearRect(0, 0, puffer.getWidth(), puffer.getHeight()); + zeichnung.setBackground(currentColor); + } + + public java.util.List getShapes() { + return formen; + } + + @Override + public void zeichnen( Graphics2D pGraphics ) { + synchronized( formen ) { + for( Form form : formen ) { + if( form.istSichtbar() ) { + form.zeichnen(zeichnung); + } + } + } + + super.zeichnen(pGraphics); + } +} diff --git a/src/schule/ngb/zm/formen/Freiform.java b/src/schule/ngb/zm/formen/Freiform.java new file mode 100644 index 0000000..e79f7c0 --- /dev/null +++ b/src/schule/ngb/zm/formen/Freiform.java @@ -0,0 +1,40 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Path2D; + +public class Freiform extends Form { + + private Path2D.Double pfad; + + public Freiform(double pX, double pY) { + super(pX, pY); + pfad = new Path2D.Double(); + } + + public void linieNach( double pX, double pY ) { + pfad.lineTo(pX-x, pY-y); + } + + public void bogenNach( double pX1, double pY1, double pX2, double pY2 ) { + pfad.quadTo(pX1-x, pY1-y, pX2-x, pY2-y); + } + + public void kurveNach( double pX1, double pY1, double pX2, double pY2, double pX3, double pY3 ) { + pfad.curveTo(pX1-x, pY1-y, pX2-x, pY2-y, pX3-x, pY3-y); + } + + public void schliessen() { + pfad.lineTo(0,0); + } + + @Override + public Form kopie() { + return null; + } + + @Override + public Shape getShape() { + return new Path2D.Double(pfad); + } +} diff --git a/src/schule/ngb/zm/formen/Fuellform.java b/src/schule/ngb/zm/formen/Fuellform.java new file mode 100644 index 0000000..7e40cb2 --- /dev/null +++ b/src/schule/ngb/zm/formen/Fuellform.java @@ -0,0 +1,49 @@ +package schule.ngb.zm.formen; + +import java.awt.*; + +public abstract class Fuellform extends Konturform { + + public static final Color STD_FUELLFARBE = Color.WHITE; + + protected Color fuellFarbe = STD_FUELLFARBE; + + + public Color getFuellfarbe() { + return fuellFarbe; + } + + public void setFuellfarbe( Color pFuellFarbe) { + fuellFarbe = pFuellFarbe; + } + + public void keineFuellung() { + fuellFarbe = null; + } + + public void setFuellfarbe( int gray) { + setFuellfarbe(gray, gray, gray, 255); + } + + public void setFuellfarbe( int gray, int alpha) { + setFuellfarbe(gray, gray, gray, alpha); + } + + public void setFuellfarbe( int red, int green, int blue) { + setFuellfarbe(red, green, blue, 255); + } + + public void setFuellfarbe( int red, int green, int blue, int alpha) { + if (red < 0 || red >= 256) + throw new IllegalArgumentException("red must be between 0 and 255"); + if (green < 0 || green >= 256) + throw new IllegalArgumentException("green must be between 0 and 255"); + if (blue < 0 || blue >= 256) + throw new IllegalArgumentException("blue must be between 0 and 255"); + if (alpha < 0 || alpha >= 256) + throw new IllegalArgumentException("alpha must be between 0 and 255"); + + setFuellfarbe(new Color(red, green, blue, alpha)); + } + +} diff --git a/src/schule/ngb/zm/formen/Konturform.java b/src/schule/ngb/zm/formen/Konturform.java new file mode 100644 index 0000000..4ecb960 --- /dev/null +++ b/src/schule/ngb/zm/formen/Konturform.java @@ -0,0 +1,114 @@ +package schule.ngb.zm.formen; + +import schule.ngb.zm.Konstanten; +import schule.ngb.zm.Zeichenbar; + +import java.awt.*; + +public abstract class Konturform extends Konstanten implements Zeichenbar { + + public static final int DURCHGEZOGEN = 16; + public static final int GESTRICHELT = 17; + public static final int GEPUNKTET = 18; + + public static final Color STD_KONTURFABRE = Color.BLACK; + public static final double STD_KONTURDICKE = 1.0; + + + protected Color konturFarbe = STD_KONTURFABRE; + + protected double konturDicke = STD_KONTURDICKE; + + protected int konturArt = DURCHGEZOGEN; + + + public Color getKonturFarbe() { + return konturFarbe; + } + + public void setKonturFarbe(Color pKonturFarbe) { + this.konturFarbe = pKonturFarbe; + } + + public void keineKontur() { + konturFarbe = null; + } + + public void setKonturFarbe(int gray) { + setKonturFarbe(gray, gray, gray, 255); + } + + public void setKonturFarbe(int gray, int alpha) { + setKonturFarbe(gray, gray, gray, alpha); + } + + public void setKonturFarbe(int red, int green, int blue) { + setKonturFarbe(red, green, blue, 255); + } + + public void setKonturFarbe(int red, int green, int blue, int alpha) { + if (red < 0 || red >= 256) + throw new IllegalArgumentException("red must be between 0 and 255"); + if (green < 0 || green >= 256) + throw new IllegalArgumentException("green must be between 0 and 255"); + if (blue < 0 || blue >= 256) + throw new IllegalArgumentException("blue must be between 0 and 255"); + if (alpha < 0 || alpha >= 256) + throw new IllegalArgumentException("alpha must be between 0 and 255"); + + setKonturFarbe(new Color(red, green, blue, alpha)); + } + + public double getKonturDicke() { + return konturDicke; + } + + public void setKonturDicke(double pKonturDicke) { + this.konturDicke = pKonturDicke; + } + + public int getKonturArt() { + return konturArt; + } + + public void setKonturArt(int konturArt) { + switch (konturArt) { + case GESTRICHELT: + this.konturArt = GESTRICHELT; + break; + case GEPUNKTET: + this.konturArt = GEPUNKTET; + break; + default: + this.konturArt = DURCHGEZOGEN; + break; + } + + } + + public abstract void zeichnen(Graphics2D graphics); + + protected Stroke createStroke() { + switch(konturArt) { + case GEPUNKTET: + return new BasicStroke( + (float) konturDicke, + BasicStroke.CAP_ROUND, + BasicStroke.JOIN_ROUND, + 10.0f, new float[]{1.0f,5.0f}, 0.0f); + case GESTRICHELT: + return new BasicStroke( + (float) konturDicke, + BasicStroke.CAP_ROUND, + BasicStroke.JOIN_ROUND, + 10.0f, new float[]{5.0f}, 0.0f); + case DURCHGEZOGEN: + default: + return new BasicStroke( + (float) konturDicke, + BasicStroke.CAP_ROUND, + BasicStroke.JOIN_ROUND); + } + } + +} diff --git a/src/schule/ngb/zm/formen/Kreis.java b/src/schule/ngb/zm/formen/Kreis.java new file mode 100644 index 0000000..b25e5ab --- /dev/null +++ b/src/schule/ngb/zm/formen/Kreis.java @@ -0,0 +1,67 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Ellipse2D; + +public class Kreis extends Form { + + public double radius; + + public Kreis( double pX, double pY, double pRadius ) { + super(pX, pY); + radius = pRadius; + setAnkerpunkt(ZENTRUM); + } + + public Kreis( Kreis pKreis ) { + this(pKreis.x, pKreis.y, pKreis.radius); + kopiere(pKreis); + } + + @Override + public void skalieren( double pFaktor ) { + super.skalieren(pFaktor); + radius *= pFaktor; + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + if( pForm instanceof Kreis ) { + radius = ((Kreis) pForm).radius; + } + } + + @Override + public Kreis kopie() { + return new Kreis(this); + } + + @Override + public Shape getShape() { + return new Ellipse2D.Double(0, 0, radius * 2.0, radius * 2.0); + } + + @Override + public void setAnkerpunkt( byte pAnker ) { + ankerBerechnen(radius + radius, radius + radius, pAnker); + } + + @Override + public boolean equals( Object o ) { + if( this == o ) return true; + if( o == null || getClass() != o.getClass() ) return false; + Kreis kreis = (Kreis) o; + return super.equals(o) && Double.compare(kreis.radius, radius) == 0; + } + + @Override + public String toString() { + return getClass().getCanonicalName() + "[" + + "x=" + x + + ",y=" + y + + ",radius=" + radius + + ']'; + } + +} diff --git a/src/schule/ngb/zm/formen/Kurve.java b/src/schule/ngb/zm/formen/Kurve.java new file mode 100644 index 0000000..76b543c --- /dev/null +++ b/src/schule/ngb/zm/formen/Kurve.java @@ -0,0 +1,183 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.CubicCurve2D; +import java.awt.geom.Point2D; +import java.awt.geom.QuadCurve2D; +import java.util.Arrays; + +public class Kurve extends Form { + + private double[] koordinaten; + + public Kurve( double pX, double pY, double pCx, double pCy, double pX2, double pY2 ) { + super(pX, pY); + + koordinaten = new double[]{ + pCx, pCy, pX2, pY2 + }; + + keineFuellung(); + } + + public Kurve( double pX, double pY, double pCx1, double pCy1, double pCx2, double pCy2, double pX2, double pY2 ) { + super(pX, pY); + + koordinaten = new double[]{ + pCx1, pCy1, pCx2, pCy2, pX2, pY2 + }; + + keineFuellung(); + } + + public Kurve( Kurve pKurve ) { + super(pKurve.x, pKurve.y); + koordinaten = Arrays.copyOf(pKurve.koordinaten, pKurve.koordinaten.length); + } + + public Point2D getStartpunkt() { + return new Point2D.Double(x, y); + } + + public void setStartpunkt( double pX, double pY ) { + x = pX; + y = pY; + } + + public Point2D getEndpunkt() { + return new Point2D.Double( + koordinaten[koordinaten.length - 2], + koordinaten[koordinaten.length - 1] + ); + } + + public void setEndpunkt( double pX, double pY ) { + koordinaten[koordinaten.length - 2] = pX; + koordinaten[koordinaten.length - 1] = pY; + } + + public Point2D getKontrollpunkt1() { + return new Point2D.Double( + koordinaten[0], + koordinaten[1] + ); + } + + public void setKontrollpunkt1( double pX, double pY ) { + koordinaten[0] = pX; + koordinaten[1] = pY; + } + + public Point2D getKontrollpunkt2() { + return new Point2D.Double( + koordinaten[koordinaten.length - 4], + koordinaten[koordinaten.length - 3] + ); + } + + public void setKontrollpunkt2( double pX, double pY ) { + koordinaten[koordinaten.length - 4] = pX; + koordinaten[koordinaten.length - 3] = pY; + } + + public void setPunkte( double pX, double pY, double pCx, double pCy, double pX2, double pY2 ) { + setStartpunkt(pX, pY); + koordinaten = koordinaten = new double[]{ + pCx, pCy, pX2, pY2 + }; + } + + public void setPunkte( double pX, double pY, double pCx1, double pCy1, double pCx2, double pCy2, double pX2, double pY2 ) { + setStartpunkt(pX, pY); + koordinaten = new double[]{ + pCx1, pCy1, pCx2, pCy2, pX2, pY2 + }; + } + + public boolean istKubisch() { + return koordinaten.length == 6; + } + + public boolean istQuadratisch() { + return koordinaten.length == 4; + } + + @Override + public Form kopie() { + return new Kurve(this); + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + if( pForm instanceof Kurve ) { + Kurve k = (Kurve) pForm; + koordinaten = Arrays.copyOf(k.koordinaten, k.koordinaten.length); + } + } + + @Override + public Shape getShape() { + if( istKubisch() ) { + return new CubicCurve2D.Double( + 0, 0, + koordinaten[0] - x, koordinaten[1] - y, + koordinaten[2] - x, koordinaten[3] - y, + koordinaten[4] - x, koordinaten[5] - y + ); + } else { + return new QuadCurve2D.Double( + 0, 0, + koordinaten[0] - x, koordinaten[1] - y, + koordinaten[2] - x, koordinaten[3] - y + ); + } + } + + @Override + public void skalieren( double pFaktor ) { + super.skalieren(pFaktor); + koordinaten[koordinaten.length - 4] *= pFaktor; + koordinaten[koordinaten.length - 3] *= pFaktor; + koordinaten[koordinaten.length - 2] *= pFaktor; + koordinaten[koordinaten.length - 1] *= pFaktor; + } + + @Override + public void verschieben( double dx, double dy ) { + super.verschieben(dx, dy); + for( int i = 0; i < koordinaten.length; i += 2 ) { + koordinaten[i] = koordinaten[i] + dx; + koordinaten[i + 1] = koordinaten[i + 1] + dy; + } + } + + @Override + public void verschiebeNach( double pX, double pY ) { + double dx = pX - x, dy = pY - y; + verschieben(dx, dy); + } + + @Override + public boolean equals( Object o ) { + if( this == o ) return true; + if( o == null || getClass() != o.getClass() ) return false; + Kurve kurve = (Kurve) o; + return super.equals(o) && + getStartpunkt().equals(kurve.getStartpunkt()) && + getKontrollpunkt1().equals(kurve.getKontrollpunkt1()) && + getKontrollpunkt2().equals(kurve.getKontrollpunkt2()) && + getEndpunkt().equals(kurve.getEndpunkt()); + } + + @Override + public String toString() { + return getClass().getCanonicalName() + "[" + + "x=" + x + + ",y=" + y + + "x2=" + koordinaten[koordinaten.length - 2] + + ",y2=" + koordinaten[koordinaten.length - 1] + + ']'; + } + +} diff --git a/src/schule/ngb/zm/formen/Linie.java b/src/schule/ngb/zm/formen/Linie.java new file mode 100644 index 0000000..0082f0c --- /dev/null +++ b/src/schule/ngb/zm/formen/Linie.java @@ -0,0 +1,92 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Line2D; + +public class Linie extends Form { + + protected double x2; + + protected double y2; + + public Linie( double pX1, double pY1, double pX2, double pY2 ) { + super(pX1, pY1); + x2 = pX2; + y2 = pY2; + } + + public Linie( Linie pLinie ) { + this(pLinie.x, pLinie.y, pLinie.x2, pLinie.y2); + kopiere(pLinie); + } + + public void setX2( double pX ) { + this.x2 = x; + } + + public void setY2( double pY ) { + this.y2 = y; + } + + public double getX2() { + return x2; + } + + public double getY2() { + return y2; + } + + @Override + public void skalieren( double pFaktor ) { + super.skalieren(pFaktor); + x2 *= pFaktor; + y2 *= pFaktor; + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + if( pForm instanceof Linie ) { + Linie linie = (Linie) pForm; + x2 = linie.x2; + y2 = linie.y2; + } + } + + @Override + public Linie kopie() { + return new Linie(this); + } + + @Override + public void setAnkerpunkt( byte pAnker ) { + ankerBerechnen(x2-x, y2-y, pAnker); + } + + @Override + public Shape getShape() { + Line2D.Double linie = new Line2D.Double(0, 0, x2 - x, y2 - y); + return linie; + } + + @Override + public boolean equals( Object o ) { + if( this == o ) return true; + if( o == null || getClass() != o.getClass() ) return false; + Linie linie = (Linie) o; + return super.equals(o) && + Double.compare(linie.x2, x2) == 0 && + Double.compare(linie.y2, y2) == 0; + } + + @Override + public String toString() { + return getClass().getCanonicalName() + "[" + + "x1=" + x + + ",y1=" + y + + ",x2=" + x2 + + ",y2=" + y2 + + ']'; + } + +} diff --git a/src/schule/ngb/zm/formen/Pfeil.java b/src/schule/ngb/zm/formen/Pfeil.java new file mode 100644 index 0000000..69d5e69 --- /dev/null +++ b/src/schule/ngb/zm/formen/Pfeil.java @@ -0,0 +1,137 @@ +package schule.ngb.zm.formen; + +import schule.ngb.zm.Vektor; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.geom.Path2D; + +public class Pfeil extends Linie { + + public static final int OFFEN = 101; + public static final int GESCHLOSSEN = 102; + private static final double BASIS_PFEILGROESSE = 5.0; + protected int pfeilspitze = OFFEN; + + protected double pfeilgroesse = 1.0; + + public Pfeil( double pX1, double pY1, double pX2, double pY2 ) { + super(pX1, pY1, pX2, pY2); + } + + public Pfeil( Vektor pVektor ) { + this(0, 0, pVektor.x, pVektor.y); + } + + public Pfeil( double pX, double pY, Vektor pVektor ) { + this(pX, pY, pX + pVektor.x, pY + pVektor.y); + } + + public Pfeil( Linie pLinie ) { + this(pLinie.x, pLinie.y, pLinie.x2, pLinie.y2); + kopiere(pLinie); + } + + public double getPfeilgroesse() { + return pfeilgroesse; + } + + public void setPfeilgroesse( double pPfeilgroesse ) { + pfeilgroesse = pPfeilgroesse; + } + + public int getPfeilspitze() { + return pfeilspitze; + } + + public void setPfeilspitze( int pPfeilspitze ) { + this.pfeilspitze = pPfeilspitze; + } + + public void abbilden( Vektor pVektor ) { + x2 = x + pVektor.x; + y2 = y + pVektor.y; + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + if( pForm instanceof Pfeil ) { + Pfeil pfeil = (Pfeil) pForm; + pfeilgroesse = pfeil.pfeilgroesse; + pfeilspitze = pfeil.pfeilspitze; + } + } + + @Override + public Pfeil kopie() { + return new Pfeil(this); + } + + @Override + public Shape getShape() { + /*Path2D.Double gruppe = new Path2D.Double(); + gruppe.append(super.getShape(), false); + gruppe.append(getPfeilspitze(), false); + + return gruppe;*/ + return super.getShape(); + } + + protected Shape getSpitze() { + AffineTransform af; + switch( pfeilspitze ) { + case OFFEN: + double len = BASIS_PFEILGROESSE * pfeilgroesse; + Path2D.Double sOffen = new Path2D.Double(); + sOffen.moveTo(-len, -len); + sOffen.lineTo(0, 0); + sOffen.lineTo(-len, len); + + af = new AffineTransform(); + af.translate(x2, y2); + af.rotate(Math.atan2(y2 - y, x2 - x)); + return af.createTransformedShape(sOffen); + case GESCHLOSSEN: + default: + int ix = (int) x2, iy = (int) y2, pg = (int) (BASIS_PFEILGROESSE * pfeilgroesse); + Polygon sGeschlossen = new Polygon( + new int[]{0, -pg, -pg}, + new int[]{0, -pg, pg}, + 3 + ); + + af = new AffineTransform(); + af.translate(x2, y2); + af.rotate(Math.atan2(y2 - y, x2 - x)); + return af.createTransformedShape(sGeschlossen); + } + } + + @Override + public void zeichnen( Graphics2D graphics, AffineTransform pVerzerrung ) { + if( !sichtbar ) { + return; + } + + super.zeichnen(graphics); + + Shape spitze = getSpitze(); + if( pVerzerrung != null ) { + spitze = pVerzerrung.createTransformedShape(spitze); + } + + Color currentColor = graphics.getColor(); + if( konturFarbe != null && konturFarbe.getAlpha() > 0.0 ) { + graphics.setColor(konturFarbe); + graphics.setStroke(new BasicStroke((float) konturDicke)); + if( pfeilspitze == GESCHLOSSEN ) { + graphics.fill(spitze); + } else { + graphics.draw(spitze); + } + } + graphics.setColor(currentColor); + + } +} diff --git a/src/schule/ngb/zm/formen/Punkt.java b/src/schule/ngb/zm/formen/Punkt.java new file mode 100644 index 0000000..33ec9d6 --- /dev/null +++ b/src/schule/ngb/zm/formen/Punkt.java @@ -0,0 +1,34 @@ +package schule.ngb.zm.formen; + +import java.awt.geom.Point2D; + +public class Punkt extends Kreis { + + private static final double PUNKT_RADIUS = 2.0; + + + public Punkt( double pX, double pY ) { + super(pX, pY, PUNKT_RADIUS); + } + + public Punkt( Point2D pPunkt ) { + super(pPunkt.getX(), pPunkt.getY(), PUNKT_RADIUS); + } + + public Punkt( Form pForm ) { + super(pForm.getX(), pForm.getY(), PUNKT_RADIUS); + } + + @Override + public void skalieren( double pFaktor ) { + // Skalierung ist für Punkte deaktiviert + return; + } + + @Override + public void setAnkerpunkt( byte pAnker ) { + // Punkte sind immer im Zentrum verankert + ankerBerechnen(radius + radius, radius + radius, ZENTRUM); + } + +} diff --git a/src/schule/ngb/zm/formen/Raute.java b/src/schule/ngb/zm/formen/Raute.java new file mode 100644 index 0000000..7d95eb6 --- /dev/null +++ b/src/schule/ngb/zm/formen/Raute.java @@ -0,0 +1,38 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Path2D; + +public class Raute extends Drache { + + private double breite; + + private double hoehe; + + public Raute( double pX, double pY, double pBreite, double pHoehe ) { + super(pX, pY, pBreite, pHoehe, 0.5); + setAnkerpunkt(ZENTRUM); + } + + public Raute( Raute pRaute ) { + this(pRaute.x, pRaute.y, pRaute.breite, pRaute.hoehe); + kopiere(pRaute); + } + + @Override + public void setVerhaeltnis( double pVerhaeltnis ) { + super.setVerhaeltnis(0.5); + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + super.setVerhaeltnis(0.5); + } + + @Override + public Drache kopie() { + return new Drache(this); + } + +} diff --git a/src/schule/ngb/zm/formen/Rechteck.java b/src/schule/ngb/zm/formen/Rechteck.java new file mode 100644 index 0000000..4def6d7 --- /dev/null +++ b/src/schule/ngb/zm/formen/Rechteck.java @@ -0,0 +1,107 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Rectangle2D; + +public class Rechteck extends Form { + + protected double breite; + + protected double hoehe; + + public Rechteck( double pX, double pY, double pBreite, double pHoehe ) { + super(pX, pY); + breite = pBreite; + hoehe = pHoehe; + setAnkerpunkt(NORDWESTEN); + } + + public Rechteck( Rechteck pRechteck ) { + this( + pRechteck.x, pRechteck.y, + pRechteck.breite, pRechteck.hoehe); + kopiere(pRechteck); + } + + public Rechteck( Form pForm ) { + Shape s = pForm.getShape(); + s = pForm.getVerzerrung().createTransformedShape(s); + Rectangle2D bounds = s.getBounds2D(); + x = bounds.getX(); + y = bounds.getY(); + breite = bounds.getWidth(); + hoehe = bounds.getHeight(); + fuellFarbe = null; + konturArt = GESTRICHELT; + } + + public double getBreite() { + return breite; + } + + public void setBreite( double breite ) { + this.breite = breite; + } + + public double getHoehe() { + return hoehe; + } + + public void setHoehe( double hoehe ) { + this.hoehe = hoehe; + } + + + @Override + public Rechteck kopie() { + return new Rechteck(this); + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + if( pForm instanceof Rechteck ) { + Rechteck rechteck = (Rechteck) pForm; + breite = rechteck.breite; + hoehe = rechteck.hoehe; + } + } + + @Override + public void skalieren( double pFaktor ) { + super.skalieren(pFaktor); + breite *= pFaktor; + hoehe *= pFaktor; + } + + @Override + public Shape getShape() { + return new Rectangle2D.Double(0, 0, breite, hoehe); + } + + @Override + public void setAnkerpunkt( byte pAnker ) { + ankerBerechnen(breite, hoehe, pAnker); + } + + @Override + public boolean equals( Object o ) { + if( this == o ) return true; + if( o == null || getClass() != o.getClass() ) return false; + Rechteck rechteck = (Rechteck) o; + return super.equals(o) && + Double.compare(rechteck.breite, breite) == 0 && + Double.compare(rechteck.hoehe, hoehe) == 0; + } + + @Override + public String toString() { + return getClass().getCanonicalName() + "[" + + "x=" + x + + ",y=" + y + + ",breite=" + breite + + ",hoehe=" + hoehe + + ']'; + } + +} diff --git a/src/schule/ngb/zm/formen/Text.java b/src/schule/ngb/zm/formen/Text.java new file mode 100644 index 0000000..6370b33 --- /dev/null +++ b/src/schule/ngb/zm/formen/Text.java @@ -0,0 +1,134 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +public class Text extends Form { + + private static final int DFT_FONT_SIZE = 14; + + protected String text; + + protected Font schriftart; + + protected int breite = 0, hoehe = 0, ascent = 0; + + public Text( double pX, double pY, String pText ) { + super(pX, pY); + schriftart = new Font(Font.SANS_SERIF, Font.PLAIN, DFT_FONT_SIZE); + setText(pText); + } + + public Text( Text pText ) { + super(pText.getX(), pText.getY()); + kopiere(pText); + } + + public Form kopie() { + return new Text(this); + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + if( pForm instanceof Text ) { + Text pText = (Text)pForm; + this.text = pText.getText(); + this.schriftart = pText.getSchriftart(); + } + } + + @Override + public void skalieren( double pFaktor ) { + super.skalieren(pFaktor); + setSchriftgroesse(schriftart.getSize2D()*pFaktor); + } + + public Font getSchriftart() { + return schriftart; + } + + public void setSchriftgroesse( double pGroesse ) { + schriftart = schriftart.deriveFont((float)pGroesse); + setText(text); + } + + public String getText() { + return text; + } + + public void setText( String pText ) { + text = pText; + + Canvas metricsCanvas = new Canvas(); + FontMetrics metrics = metricsCanvas.getFontMetrics(schriftart); + breite = metrics.stringWidth(text); + hoehe = metrics.getDescent() + metrics.getAscent(); + ascent = metrics.getAscent(); + + setAnkerpunkt(ZENTRUM); + } + + public double getBreite() { + return breite; + } + + public double getHoehe() { + return hoehe; + } + + public void setAnkerpunkt( byte pAnker ) { + ankerBerechnen(breite, ascent - hoehe, pAnker); + } + + @Override + public Shape getShape() { + return new Rectangle2D.Double(0, 0, breite, hoehe); + } + + @Override + public void zeichnen( Graphics2D graphics, AffineTransform pVerzerrung ) { + if( !sichtbar ) { + return; + } + + // Aktuelle Werte speichern + Font currentFont = graphics.getFont(); + Color currentColor = graphics.getColor(); + AffineTransform af = graphics.getTransform(); + + // Neue Werte setzen + graphics.setFont(schriftart); + graphics.setColor(konturFarbe); + graphics.transform(getVerzerrung()); + + // Text zeichnen + FontMetrics fm = graphics.getFontMetrics(); + //graphics.drawString(text, (float) (x - fm.stringWidth(text)/2.0), (float) (y + fm.getDescent())); + graphics.drawString(text, 0, 0); + + // Alte Werte wiederherstellen + graphics.setTransform(af); + graphics.setColor(currentColor); + graphics.setFont(currentFont); + } + + @Override + public boolean equals( Object o ) { + if( this == o ) return true; + if( o == null || getClass() != o.getClass() ) return false; + Text text = (Text) o; + return super.equals(o) && + text.equals(text.text) && + schriftart.equals(text.schriftart); + } + + @Override + public String toString() { + return getClass().getCanonicalName() + "[" + + "text=" + text + + ']'; + } + +} diff --git a/src/schule/ngb/zm/formen/Vieleck.java b/src/schule/ngb/zm/formen/Vieleck.java new file mode 100644 index 0000000..7ef6158 --- /dev/null +++ b/src/schule/ngb/zm/formen/Vieleck.java @@ -0,0 +1,72 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.util.Arrays; + +public class Vieleck extends Form { + + protected Point2D[] ecken; + + public Vieleck( double pX, double pY, Point2D... pEcken ) { + super(pX, pY); + + ecken = new Point2D[pEcken.length]; + for( int i = 0; i < pEcken.length; i++ ) { + ecken[i] = new Point2D.Double(pEcken[i].getX()-pX, pEcken[i].getY()-pY); + } + } + + public Vieleck( Point2D... pEcken ) { + super(); + + ecken = new Point2D[pEcken.length]; + for( int i = 0; i < pEcken.length; i++ ) { + if( i == 0 ) { + x = pEcken[i].getX(); + y = pEcken[i].getY(); + } + ecken[i] = new Point2D.Double(pEcken[i].getX()-x, pEcken[i].getY()-y); + } + } + + public Vieleck( Vieleck pVieleck ) { + this(pVieleck.x, pVieleck.y); + kopiere(pVieleck); + } + + public Point2D[] getEcken() { + return ecken; + } + + @Override + public void kopiere( Form pForm ) { + super.kopiere(pForm); + if( pForm instanceof Vieleck ) { + Vieleck v = (Vieleck) pForm; + + ecken = new Point2D[v.ecken.length]; + for( int i = 0; i < v.ecken.length; i++ ) { + ecken[i] = new Point2D.Double(v.ecken[i].getX(), v.ecken[i].getY()); + } + } + } + + @Override + public Form kopie() { + return new Vieleck(this); + } + + @Override + public Shape getShape() { + Path2D shape = new Path2D.Double(); + shape.moveTo(ecken[0].getX(), ecken[0].getY()); + for( int i = 1; i < ecken.length; i++ ) { + shape.lineTo(ecken[i].getX(), ecken[i].getY()); + } + shape.closePath(); + return shape; + } + +} diff --git a/src/schule/ngb/zm/formen/Viereck.java b/src/schule/ngb/zm/formen/Viereck.java new file mode 100644 index 0000000..02a1fd2 --- /dev/null +++ b/src/schule/ngb/zm/formen/Viereck.java @@ -0,0 +1,34 @@ +package schule.ngb.zm.formen; + +import java.awt.*; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.util.Arrays; + +public class Viereck extends Vieleck { + + public Viereck( double pX, double pY, Point2D... pEcken ) { + super(pX, pY, Arrays.copyOf(pEcken, 4)); + if( pEcken.length < 4 ) { + throw new IllegalArgumentException("Ein Viereck muss genau vier Eckpunkte besitzen."); + } + } + + public Viereck( Point2D... pEcken ) { + super(Arrays.copyOf(pEcken, 4)); + if( pEcken.length < 4 ) { + throw new IllegalArgumentException("Ein Viereck muss genau vier Eckpunkte besitzen."); + } + } + + public Viereck( Viereck pViereck ) { + super(pViereck.x, pViereck.y); + kopiere(pViereck); + } + + @Override + public Form kopie() { + return new Viereck(this); + } + +}