/* * $Id$ * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc * * Copyright (c) 2000-2012 Stephane GALLAND. * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports, * Universite de Technologie de Belfort-Montbeliard. * Copyright (c) 2013-2016 The original authors, and other authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * 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. */ package org.arakhne.afc.math.geometry.d2.dfx; import javafx.beans.binding.Bindings; import javafx.beans.property.DoubleProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleObjectProperty; import org.eclipse.xtext.xbase.lib.Pure; import org.arakhne.afc.math.geometry.MathFXAttributeNames; import org.arakhne.afc.math.geometry.d2.Point2D; import org.arakhne.afc.math.geometry.d2.Vector2D; import org.arakhne.afc.math.geometry.d2.afp.Parallelogram2afp; import org.arakhne.afc.vmutil.asserts.AssertMessages; /** Parallelogram with 2 double precision floating-point FX properties. * * @author $Author: sgalland$ * @author $Author: ngaud$ * @author $Author: mgrolleau$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ * @since 13.0 */ public class Parallelogram2dfx extends AbstractShape2dfx<Parallelogram2dfx> implements Parallelogram2afp<Shape2dfx<?>, Parallelogram2dfx, PathElement2dfx, Point2dfx, Vector2dfx, Rectangle2dfx> { private static final long serialVersionUID = -3880367245218796375L; /** * Center of the parallelogram. */ private Point2dfx center = new Point2dfx(); /** * The first axis of the parallelogram. */ private UnitVectorProperty raxis; /** * The second axis of the parallelogram. */ private UnitVectorProperty saxis; /** * Half-size of the first axis of the parallelogram. */ private DoubleProperty extentR; /** * Half-size of the second axis of the parallelogram. */ private DoubleProperty extentS; /** Create an empty parallelogram. */ public Parallelogram2dfx() { // } /** Create an parallelogram from the given parallelogram. * * @param parallelogram the parallelogram to copy. */ public Parallelogram2dfx(Parallelogram2afp<?, ?, ?, ?, ?, ?> parallelogram) { assert parallelogram != null : AssertMessages.notNullParameter(); set(parallelogram.getCenterX(), parallelogram.getCenterY(), parallelogram.getFirstAxisX(), parallelogram.getFirstAxisY(), parallelogram.getFirstAxisExtent(), parallelogram.getSecondAxisX(), parallelogram.getSecondAxisY(), parallelogram.getSecondAxisExtent()); } /** Construct a parallelogram from the given cloud of points. * * @param pointCloud - the cloud of points. */ public Parallelogram2dfx(Iterable<? extends Point2D<?, ?>> pointCloud) { setFromPointCloud(pointCloud); } /** Construct a parallelogram from the given cloud of points. * * @param pointCloud - the cloud of points. */ public Parallelogram2dfx(Point2D<?, ?>... pointCloud) { setFromPointCloud(pointCloud); } /** Construct a parallelogram. * * @param centerX is the X coordinate of the parallelogram center. * @param centerY is the Y coordinate of the parallelogram center. * @param axis1X is the X coordinate of first axis of the parallelogram. * @param axis1Y is the Y coordinate of first axis of the parallelogram. * @param axis1Extent is the extent of the first parallelogram. * @param axis2X is the X coordinate of second axis of the parallelogram. * @param axis2Y is the Y coordinate of second axis of the parallelogram. * @param axis2Extent is the extent of the second parallelogram. */ @SuppressWarnings("checkstyle:magicnumber") public Parallelogram2dfx(double centerX, double centerY, double axis1X, double axis1Y, double axis1Extent, double axis2X, double axis2Y, double axis2Extent) { assert Vector2D.isUnitVector(axis1X, axis1Y) : AssertMessages.normalizedParameters(2, 3); assert Vector2D.isUnitVector(axis2X, axis2Y) : AssertMessages.normalizedParameters(5, 6); assert axis1Extent >= 0. : AssertMessages.positiveOrZeroParameter(4); assert axis2Extent >= 0. : AssertMessages.positiveOrZeroParameter(7); set(centerX, centerY, axis1X, axis1Y, axis1Extent, axis2X, axis2Y, axis2Extent); } /** Construct a parallelogram. * * @param center is the parallelogram center. * @param axis1 is the first axis of the parallelogram. * @param axis1Extent is the extent of the first axis. * @param axis2 is the second axis of the parallelogram. * @param axis2Extent is the extent of the second axis. */ public Parallelogram2dfx(Point2D<?, ?> center, Vector2D<?, ?> axis1, double axis1Extent, Vector2D<?, ?> axis2, double axis2Extent) { set(center, axis1, axis1Extent, axis2, axis2Extent); } @Override public Parallelogram2dfx clone() { final Parallelogram2dfx clone = super.clone(); if (clone.center != null) { clone.center = null; clone.center = this.center.clone(); } if (clone.raxis != null) { clone.raxis = null; clone.firstAxisProperty().set(getFirstAxis()); } if (clone.extentR != null) { clone.extentR = null; clone.firstAxisExtentProperty().set(getFirstAxisExtent()); } if (clone.saxis != null) { clone.saxis = null; clone.secondAxisProperty().set(getSecondAxis()); } if (clone.extentS != null) { clone.extentS = null; clone.secondAxisExtentProperty().set(getSecondAxisExtent()); } return clone; } @Pure @Override public int hashCode() { int bits = 1; bits = 31 * bits + Double.hashCode(getCenterX()); bits = 31 * bits + Double.hashCode(getCenterY()); bits = 31 * bits + Double.hashCode(getFirstAxisX()); bits = 31 * bits + Double.hashCode(getFirstAxisY()); bits = 31 * bits + Double.hashCode(getFirstAxisExtent()); bits = 31 * bits + Double.hashCode(getSecondAxisX()); bits = 31 * bits + Double.hashCode(getSecondAxisY()); bits = 31 * bits + Double.hashCode(getSecondAxisExtent()); return bits ^ (bits >> 31); } /** Replies the property for the x coordinate of the center. * * @return the property. */ public DoubleProperty centerXProperty() { return this.center.xProperty(); } /** Replies the property for the y coordinate of the center. * * @return the property. */ public DoubleProperty centerYProperty() { return this.center.yProperty(); } @Pure @Override public Point2dfx getCenter() { return this.center; } @Pure @Override public double getCenterX() { return this.center.getX(); } @Override public void setCenterX(double cx) { this.center.setX(cx); } @Override public void setCenterY(double cy) { this.center.setY(cy); } @Pure @Override public double getCenterY() { return this.center.getY(); } @Override public void setCenter(double cx, double cy) { this.center.setX(cx); this.center.setY(cy); } /** Set the center. * * @param point the new center */ public void setCenter(Point2dfx point) { assert point != null : AssertMessages.notNullParameter(0); this.center = point; } /** Replies the property for the first axis. * * @return the property. */ public UnitVectorProperty firstAxisProperty() { if (this.raxis == null) { this.raxis = new UnitVectorProperty(this, MathFXAttributeNames.FIRST_AXIS, getGeomFactory()); } return this.raxis; } @Pure @Override public Vector2dfx getFirstAxis() { return firstAxisProperty().get(); } @Pure @Override public double getFirstAxisX() { return this.raxis == null ? 1 : this.raxis.getX(); } @Pure @Override public double getFirstAxisY() { return this.raxis == null ? 0 : this.raxis.getY(); } /** Replies the property for the second axis. * * @return the property. */ public UnitVectorProperty secondAxisProperty() { if (this.saxis == null) { this.saxis = new UnitVectorProperty(this, MathFXAttributeNames.SECOND_AXIS, getGeomFactory()); } return this.saxis; } @Pure @Override public Vector2dfx getSecondAxis() { return secondAxisProperty().get(); } @Pure @Override public double getSecondAxisX() { return this.saxis == null ? 0 : this.saxis.getX(); } @Pure @Override public double getSecondAxisY() { return this.saxis == null ? 1 : this.saxis.getY(); } /** Replies the property for the extent of the first axis. * * @return the firstAxisExtent property. */ @Pure public DoubleProperty firstAxisExtentProperty() { if (this.extentR == null) { this.extentR = new SimpleDoubleProperty(this, MathFXAttributeNames.FIRST_AXIS_EXTENT) { @Override protected void invalidated() { if (get() < 0.) { set(0.); } } }; } return this.extentR; } @Pure @Override public double getFirstAxisExtent() { return this.extentR == null ? 0 : this.extentR.get(); } @Override public void setFirstAxisExtent(double extent) { assert extent >= 0. : AssertMessages.positiveOrZeroParameter(); firstAxisExtentProperty().set(extent); } /** Replies the property for the extent of the second axis. * * @return the secondAxisExtent property. */ @Pure public DoubleProperty secondAxisExtentProperty() { if (this.extentS == null) { this.extentS = new SimpleDoubleProperty(this, MathFXAttributeNames.SECOND_AXIS_EXTENT) { @Override protected void invalidated() { if (get() < 0.) { set(0.); } } }; } return this.extentS; } @Pure @Override public double getSecondAxisExtent() { return this.extentS == null ? 0 : this.extentS.get(); } @Override public void setSecondAxisExtent(double extent) { assert extent >= 0. : AssertMessages.positiveOrZeroParameter(); secondAxisExtentProperty().set(extent); } @Override public void setFirstAxis(double x, double y, double extent) { assert Vector2D.isUnitVector(x, y) : AssertMessages.normalizedParameters(0, 1); assert extent >= 0. : AssertMessages.positiveOrZeroParameter(2); firstAxisProperty().set(x, y); firstAxisExtentProperty().set(extent); } @Override public void setSecondAxis(double x, double y, double extent) { assert Vector2D.isUnitVector(x, y) : AssertMessages.normalizedParameters(0, 1); assert extent >= 0. : AssertMessages.positiveOrZeroParameter(2); secondAxisProperty().set(x, y); secondAxisExtentProperty().set(extent); } @Override @SuppressWarnings("checkstyle:magicnumber") public void set(double centerX, double centerY, double axis1x, double axis1y, double axis1Extent, double axis2x, double axis2y, double axis2Extent) { assert Vector2D.isUnitVector(axis1x, axis1y) : AssertMessages.normalizedParameters(2, 3); assert Vector2D.isUnitVector(axis2x, axis2y) : AssertMessages.normalizedParameters(5, 6); assert axis1Extent >= 0. : AssertMessages.positiveOrZeroParameter(4); assert axis2Extent >= 0. : AssertMessages.positiveOrZeroParameter(7); centerXProperty().set(centerX); centerYProperty().set(centerY); firstAxisProperty().set(axis1x, axis1y); firstAxisExtentProperty().set(axis1Extent); secondAxisProperty().set(axis2x, axis2y); secondAxisExtentProperty().set(axis2Extent); } @Override public ObjectProperty<Rectangle2dfx> boundingBoxProperty() { if (this.boundingBox == null) { this.boundingBox = new SimpleObjectProperty<>(this, MathFXAttributeNames.BOUNDING_BOX); this.boundingBox.bind(Bindings.createObjectBinding(() -> toBoundingBox(), centerXProperty(), centerYProperty(), firstAxisProperty(), firstAxisExtentProperty(), secondAxisProperty(), secondAxisExtentProperty())); } return this.boundingBox; } }