net.sourceforge.plantuml.klimt.geom.RectangleArea Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of plantuml-gplv2 Show documentation
Show all versions of plantuml-gplv2 Show documentation
PlantUML is a component that allows to quickly write diagrams from text.
// THIS FILE HAS BEEN GENERATED BY A PREPROCESSOR.
/* +=======================================================================
* |
* | PlantUML : a free UML diagram generator
* |
* +=======================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/liberapay (only 1€ per month!)
* https://plantuml.com/paypal
*
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License V2.
*
* THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
* LICENSE ("AGREEMENT"). [GNU General Public License V2]
*
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
*
* You may obtain a copy of the License at
*
* https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* PlantUML can occasionally display sponsored or advertising messages. Those
* messages are usually generated on welcome or error images and never on
* functional diagrams.
* See https://plantuml.com/professional if you want to remove them
*
* Images (whatever their format : PNG, SVG, EPS...) generated by running PlantUML
* are owned by the author of their corresponding sources code (that is, their
* textual description in PlantUML language). Those images are not covered by
* this GPL v2 license.
*
* The generated images can then be used without any reference to the GPL v2 license.
* It is not even necessary to stipulate that they have been generated with PlantUML,
* although this will be appreciated by the PlantUML team.
*
* There is an exception : if the textual description in PlantUML language is also covered
* by any license, then the generated images are logically covered
* by the very same license.
*
* This is the IGY distribution (Install GraphViz by Yourself).
* You have to install GraphViz and to setup the GRAPHVIZ_DOT environment variable
* (see https://plantuml.com/graphviz-dot )
*
* Icons provided by OpenIconic : https://useiconic.com/open
* Archimate sprites provided by Archi : http://www.archimatetool.com
* Stdlib AWS provided by https://github.com/milo-minderbinder/AWS-PlantUML
* Stdlib Icons provided https://github.com/tupadr3/plantuml-icon-font-sprites
* ASCIIMathML (c) Peter Jipsen http://www.chapman.edu/~jipsen
* ASCIIMathML (c) David Lippman http://www.pierce.ctc.edu/dlippman
* CafeUndZopfli ported by Eugene Klyuchnikov https://github.com/eustas/CafeUndZopfli
* Brotli (c) by the Brotli Authors https://github.com/google/brotli
* Themes (c) by Brett Schwarz https://github.com/bschwarz/puml-themes
* Twemoji (c) by Twitter at https://twemoji.twitter.com/
*
*/
package net.sourceforge.plantuml.klimt.geom;
import net.sourceforge.plantuml.klimt.UTranslate;
import net.sourceforge.plantuml.utils.MathUtils;
public class RectangleArea {
private final double minX;
private final double minY;
private final double maxX;
private final double maxY;
public RectangleArea(double minX, double minY, double maxX, double maxY) {
this.minX = minX;
this.minY = minY;
this.maxX = maxX;
this.maxY = maxY;
}
public static RectangleArea build(XPoint2D pt1, XPoint2D pt2) {
return new RectangleArea(MathUtils.min(pt1.x, pt2.x), MathUtils.min(pt1.y, pt2.y), MathUtils.max(pt1.x, pt2.x),
MathUtils.max(pt1.y, pt2.y));
}
public RectangleArea move(double deltaX, double deltaY) {
return new RectangleArea(minX + deltaX, minY + deltaY, maxX + deltaX, maxY + deltaY);
}
public double getWidth() {
return maxX - minX;
}
public double getHeight() {
return maxY - minY;
}
public boolean contains(double x, double y) {
return x >= minX && x < maxX && y >= minY && y < maxY;
}
public RectangleArea merge(RectangleArea other) {
return new RectangleArea(Math.min(this.minX, other.minX), Math.min(this.minY, other.minY),
Math.max(this.maxX, other.maxX), Math.max(this.maxY, other.maxY));
}
public RectangleArea merge(XPoint2D point) {
final double x = point.getX();
final double y = point.getY();
return new RectangleArea(Math.min(this.minX, x), Math.min(this.minY, y), Math.max(this.maxX, x),
Math.max(this.maxY, y));
}
public boolean contains(XPoint2D p) {
return contains(p.getX(), p.getY());
}
@Override
public String toString() {
return "minX=" + minX + " maxX=" + maxX + " minY=" + minY + " maxY=" + maxY;
}
public final double getMinX() {
return minX;
}
public final double getMinY() {
return minY;
}
public final double getMaxX() {
return maxX;
}
public final double getMaxY() {
return maxY;
}
public PointDirected getIntersection(XCubicCurve2D bez) {
if (contains(bez.x1, bez.y1) == contains(bez.x2, bez.y2))
return null;
final double dist = bez.getP1().distance(bez.getP2());
if (dist < 2) {
final double angle = BezierUtils.getStartingAngle(bez);
return new PointDirected(bez.getP1(), angle);
}
final XCubicCurve2D left = XCubicCurve2D.none();
final XCubicCurve2D right = XCubicCurve2D.none();
bez.subdivide(left, right);
final PointDirected int1 = getIntersection(left);
if (int1 != null)
return int1;
final PointDirected int2 = getIntersection(right);
if (int2 != null)
return int2;
throw new IllegalStateException();
}
public XPoint2D getPointCenter() {
return new XPoint2D((minX + maxX) / 2, (minY + maxY) / 2);
}
public RectangleArea withMinX(double d) {
return new RectangleArea(d, minY, maxX, maxY);
}
public RectangleArea withMaxX(double d) {
return new RectangleArea(minX, minY, d, maxY);
}
public RectangleArea addMaxX(double d) {
return new RectangleArea(minX, minY, maxX + d, maxY);
}
public RectangleArea addMaxY(double d) {
return new RectangleArea(minX, minY, maxX, maxY + d);
}
public RectangleArea addMinX(double d) {
return new RectangleArea(minX + d, minY, maxX, maxY);
}
public RectangleArea addMinY(double d) {
return new RectangleArea(minX, minY + d, maxX, maxY);
}
public RectangleArea withMinY(double d) {
return new RectangleArea(minX, d, maxX, maxY);
}
public RectangleArea withMaxY(double d) {
return new RectangleArea(minX, minY, maxX, d);
}
// public XPoint2D getProjectionOnFrontier(XPoint2D pt) {
// final double x = pt.getX();
// final double y = pt.getY();
// if (x > maxX && y >= minY && y <= maxY)
// return new XPoint2D(maxX - 1, y);
//
// if (x < minX && y >= minY && y <= maxY)
// return new XPoint2D(minX + 1, y);
//
// if (y > maxY && x >= minX && x <= maxX)
// return new XPoint2D(x, maxY - 1);
//
// if (y < minY && x >= minX && x <= maxX)
// return new XPoint2D(x, minY + 1);
//
// return new XPoint2D(x, y);
// }
public RectangleArea delta(double m1, double m2) {
return new RectangleArea(minX, minY, maxX + m1, maxY + m2);
}
public XDimension2D getDimension() {
return new XDimension2D(maxX - minX, maxY - minY);
}
public UTranslate getPosition() {
return new UTranslate(getMinX(), getMinY());
}
// public boolean isPointJustUpper(XPoint2D pt) {
// if (pt.getX() >= minX && pt.getX() <= maxX && pt.getY() <= minY) {
// return true;
// }
// return false;
// }
public Side getClosestSide(XPoint2D pt) {
final double distNorth = Math.abs(minY - pt.getY());
final double distSouth = Math.abs(maxY - pt.getY());
final double distWest = Math.abs(minX - pt.getX());
final double distEast = Math.abs(maxX - pt.getX());
if (isSmallerThan(distNorth, distWest, distEast, distSouth))
return Side.NORTH;
if (isSmallerThan(distSouth, distNorth, distWest, distEast))
return Side.SOUTH;
if (isSmallerThan(distEast, distNorth, distWest, distSouth))
return Side.EAST;
if (isSmallerThan(distWest, distNorth, distEast, distSouth))
return Side.WEST;
return null;
}
private boolean isSmallerThan(double value, double a, double b, double c) {
return value <= a && value <= b && value <= c;
}
}