georegression.struct.shapes.Quadrilateral_F64 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of georegression Show documentation
Show all versions of georegression Show documentation
GeoRegression is a free Java based geometry library for scientific computing in fields such as robotics and computer vision with a focus on 2D/3D space.
/*
* Copyright (C) 2020, Peter Abeles. All Rights Reserved.
*
* This file is part of Geometric Regression Library (GeoRegression).
*
* 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 georegression.struct.shapes;
import georegression.metric.Area2D_F64;
import georegression.struct.line.LineSegment2D_F64;
import georegression.struct.point.Point2D_F64;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* A polygon with 4 vertices, a,b,c, and d. The vertices are in order sequential order of a,b,c,d.
*
*/
public class Quadrilateral_F64 implements Serializable {
public Point2D_F64 a;
public Point2D_F64 b;
public Point2D_F64 c;
public Point2D_F64 d;
public Quadrilateral_F64() {
a = new Point2D_F64();
b = new Point2D_F64();
c = new Point2D_F64();
d = new Point2D_F64();
}
public Quadrilateral_F64( Quadrilateral_F64 quad ) {
this();
a.setTo(quad.a);
b.setTo(quad.b);
c.setTo(quad.c);
d.setTo(quad.d);
}
public Quadrilateral_F64( double x0, double y0 , double x1, double y1 ,
double x2, double y2 , double x3, double y3 ) {
a = new Point2D_F64(x0,y0);
b = new Point2D_F64(x1,y1);
c = new Point2D_F64(x2,y2);
d = new Point2D_F64(x3,y3);
}
public Quadrilateral_F64(Point2D_F64 a, Point2D_F64 b, Point2D_F64 c, Point2D_F64 d ) {
this(a,b,c,d,true);
}
public Quadrilateral_F64(Point2D_F64 a, Point2D_F64 b, Point2D_F64 c, Point2D_F64 d, boolean copy ) {
if( copy ) {
this.a = new Point2D_F64(a);
this.b = new Point2D_F64(b);
this.c = new Point2D_F64(c);
this.d = new Point2D_F64(d);
} else {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
}
/**
* Returns the area of this quadrilateral
* @return area
*/
public double area() {
return Area2D_F64.quadrilateral(this);
}
public Point2D_F64 get( int index ) {
switch( index ) {
case 0: return a;
case 1: return b;
case 2: return c;
case 3: return d;
}
throw new IllegalArgumentException("Requested index out of range. "+index);
}
public Point2D_F64 getA() {
return a;
}
public void setA(Point2D_F64 a) {
this.a = a;
}
public Point2D_F64 getB() {
return b;
}
public void setB(Point2D_F64 b) {
this.b = b;
}
public Point2D_F64 getC() {
return c;
}
public void setC(Point2D_F64 c) {
this.c = c;
}
public Point2D_F64 getD() {
return d;
}
public void setD(Point2D_F64 d) {
this.d = d;
}
public LineSegment2D_F64 getLine( int which , LineSegment2D_F64 storage ) {
if( storage == null )
storage = new LineSegment2D_F64();
switch( which ) {
case 0: storage.a.setTo(a);storage.b.setTo(b);break;
case 1: storage.a.setTo(b);storage.b.setTo(c);break;
case 2: storage.a.setTo(c);storage.b.setTo(d);break;
case 3: storage.a.setTo(d);storage.b.setTo(a);break;
default:
throw new IllegalArgumentException("Requested index out of range. "+which);
}
return storage;
}
public double getSideLength( int which ) {
return Math.sqrt(getSideLength2(which));
}
public double getSideLength2( int which ) {
switch( which ) {
case 0: return a.distance2(b);
case 1: return b.distance2(c);
case 2: return c.distance2(d);
case 3: return d.distance2(a);
default:
throw new IllegalArgumentException("Requested index out of range. "+which);
}
}
public void setTo(Quadrilateral_F64 quad) {
this.a.setTo(quad.a);
this.b.setTo(quad.b);
this.c.setTo(quad.c);
this.d.setTo(quad.d);
}
/**
* Converts the polygon into a list.
*
* @param storage (Optional) storage to put the vertexes into
* @param copy If points will be copied otherwise a reference of points will be returned
* @return List of vertexes
*/
public List convert(@Nullable List storage , boolean copy ) {
if( storage == null )
storage = new ArrayList<>();
else
storage.clear();
if( copy ) {
for (int i = 0; i < 4; i++) {
storage.add( get(i).copy() );
}
} else {
for (int i = 0; i < 4; i++) {
storage.add( get(i) );
}
}
return storage;
}
/**
* Sets the polygon to be the same as the list. A true copy is created and no references
* to points in the list are saved.
* @param list List which the polygon will be set to
*/
public void setTo(List list ) {
if( list.size() != 4 )
throw new IllegalArgumentException("List must have size of 4");
a.setTo(list.get(0));
b.setTo(list.get(1));
c.setTo(list.get(2));
d.setTo(list.get(3));
}
public Quadrilateral_F64 copy() {
return new Quadrilateral_F64(this);
}
/**
* Returns true if the two quadrilaterals are equal to each other to within tolerance. Equality is defined
* by seeing if the distance between two equivalent vertexes is within tolerance.
*
* @param quad The second quadrilateral
* @param tol Maximum allowed distance between vertexes.
* @return true if equals or false if not
*/
public boolean isEquals( Quadrilateral_F64 quad , double tol ) {
tol *= tol;
if( a.distance2(quad.a) > tol )
return false;
if( b.distance2(quad.b) > tol )
return false;
if( c.distance2(quad.c) > tol )
return false;
return d.distance2(quad.d) <= tol;
}
@Override
public String toString() {
return getClass().getSimpleName()+"{" +
"a=" + a +
", b=" + b +
", c=" + c +
", d=" + d +
'}';
}
}