Initial commit for historical purposes
This commit is contained in:
194
src/main/java/com/aaaaahhhhhhh/bananapuncher714/tess4j/Util.java
Normal file
194
src/main/java/com/aaaaahhhhhhh/bananapuncher714/tess4j/Util.java
Normal file
@@ -0,0 +1,194 @@
|
||||
package com.aaaaahhhhhhh.bananapuncher714.tess4j;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.joml.Math;
|
||||
|
||||
public class Util {
|
||||
protected static String toString( Object obj ) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append( obj.getClass().getSimpleName() );
|
||||
builder.append( '{' );
|
||||
List< Field > fields = new ArrayList< Field >();
|
||||
fields.addAll( Arrays.asList( obj.getClass().getDeclaredFields() ) );
|
||||
fields.addAll( Arrays.asList( obj.getClass().getFields() ) );
|
||||
|
||||
for ( Iterator< Field > it = fields.iterator(); it.hasNext(); builder.append( "," ) ) {
|
||||
Field field = it.next();
|
||||
builder.append( field.getName() );
|
||||
builder.append( '=' );
|
||||
try {
|
||||
builder.append( field.get( obj ) );
|
||||
} catch ( IllegalArgumentException | IllegalAccessException e ) {
|
||||
builder.append( "?" );
|
||||
}
|
||||
}
|
||||
|
||||
builder.append( '}' );
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static Optional< Point > intersection( final VertexOld x1, final VertexOld x2, final VertexOld x3, final VertexOld x4 ) {
|
||||
Point point = null;
|
||||
|
||||
final Vector2dOld p = x1.toVector();
|
||||
final Vector2dOld r = x2.subtract( x1 );
|
||||
final Vector2dOld q = x3.toVector();
|
||||
final Vector2dOld s = x4.subtract( x3 );
|
||||
|
||||
final Vector2dOld qp = q.subtract( p );
|
||||
final double qpr = qp.cross( r );
|
||||
final double rs = r.cross( s );
|
||||
|
||||
// Are the two lines parallel
|
||||
if ( rs == 0 ) {
|
||||
final Vector2dOld u = x2.toVector();
|
||||
final Vector2dOld v = x4.toVector();
|
||||
|
||||
// For normalizing against pr
|
||||
final double rr = r.dot( r );
|
||||
|
||||
// t0 and t1 represent the distance of the second edge endpoints relative to the first edge normalized by r
|
||||
// t0 = ( ( q - p ) . r ) / rr;
|
||||
double t0 = qp.dot( r ) / rr;
|
||||
// t1 = ( ( q + s - p ) . r ) / rr
|
||||
double t1 = v.subtract( p ).dot( r ) / rr;
|
||||
|
||||
// If the vectors are pointing in the opposite directions, then swap t0 and t1
|
||||
final boolean inverted = s.dot( r ) < 0;
|
||||
if ( inverted ) {
|
||||
double temp = t0;
|
||||
t0 = t1;
|
||||
t1 = temp;
|
||||
}
|
||||
|
||||
if ( qpr == 0 ) {
|
||||
if ( t0 < 1 & t1 > 0 ) {
|
||||
final double midt = Math.max( t0, 0 ) + Math.min( t1, 1 ) / 2.0;
|
||||
final Vector2dOld midpoint = r.multiply( midt ).add( p );
|
||||
point = midpoint.toPoint();
|
||||
} else {
|
||||
final Vector2dOld pu = t0 > 1 ? u : p;
|
||||
// Same as the first edge but the second edge may be inverted
|
||||
final Vector2dOld qv = ( inverted ^ t0 > 1 ) ? q : v;
|
||||
final Vector2dOld midpoint = pu.add( qv ).divide( 2.0 );
|
||||
point = midpoint.toPoint();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Calculate t and u
|
||||
final double t = qp.cross( s ) / rs;
|
||||
final double u = qpr / rs;
|
||||
|
||||
// Do the line segments intersect
|
||||
if ( t >= 0 && t <= 1 && u >= 0 && u <= 1 ) {
|
||||
// Calculate the point of intersection
|
||||
final Vector2dOld intersection = r.multiply( t ).add( p );
|
||||
point = intersection.toPoint();
|
||||
}
|
||||
}
|
||||
return Optional.ofNullable( point );
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
|
||||
// Vector based closest intersection method
|
||||
public static Point closestPoint( final VertexOld x1, final VertexOld x2, final VertexOld x3, final VertexOld x4 ) {
|
||||
Point point = new Point( 0, 0 );
|
||||
|
||||
final Vector2dOld p = x1.toVector();
|
||||
final Vector2dOld r = x2.subtract( x1 );
|
||||
final Vector2dOld q = x3.toVector();
|
||||
final Vector2dOld s = x4.subtract( x3 );
|
||||
|
||||
final Vector2dOld qp = q.subtract( p );
|
||||
final double qpr = qp.cross( r );
|
||||
final double rs = r.cross( s );
|
||||
|
||||
// Are the two lines parallel
|
||||
if ( rs == 0 ) {
|
||||
final Vector2dOld u = x2.toVector();
|
||||
final Vector2dOld v = x4.toVector();
|
||||
|
||||
// For normalizing against pr
|
||||
final double rr = r.dot( r );
|
||||
|
||||
// t0 and t1 represent the distance of the second edge endpoints relative to the first edge normalized by r
|
||||
// t0 = ( ( q - p ) . r ) / rr;
|
||||
double t0 = qp.dot( r ) / rr;
|
||||
// t1 = ( ( q + s - p ) . r ) / rr
|
||||
double t1 = v.subtract( p ).dot( r ) / rr;
|
||||
|
||||
// If the vectors are pointing in the opposite directions, then swap t0 and t1
|
||||
final boolean inverted = s.dot( r ) < 0;
|
||||
if ( inverted ) {
|
||||
double temp = t0;
|
||||
t0 = t1;
|
||||
t1 = temp;
|
||||
}
|
||||
|
||||
// Do the lines overlap
|
||||
if ( t0 < 1 && t1 > 0 ) {
|
||||
// The midpoint is an arbitrary point that just happens to look good as an intersection
|
||||
// Find the midpoint between the overlapping region
|
||||
final double midt = Math.max( t0, 0 ) + Math.min( t1, 1 ) / 2.0;
|
||||
// If colinear
|
||||
if ( qpr == 0 ) {
|
||||
// Do not need to calculate the distance between the two parallel lines since it is 0
|
||||
final Vector2dOld midpoint = r.multiply( midt ).add( p );
|
||||
point.x = midpoint.x;
|
||||
point.y = midpoint.y;
|
||||
} else {
|
||||
// Calculate the midpoint along pr
|
||||
final Vector2dOld midp = r.multiply( midt ).add( p );
|
||||
// Calculate the perpendicular distance between both lines
|
||||
final Vector2dOld perp = r.perpendicular();
|
||||
final Vector2dOld z = perp.multiply( qp.dot( perp ) / rr );
|
||||
// Sum the components
|
||||
final Vector2dOld midpoint = midp.add( z.divide( 2.0 ) );
|
||||
point.x = midpoint.x;
|
||||
point.y = midpoint.y;
|
||||
}
|
||||
} else {
|
||||
// The lines aren't really anywhere close to each other, so just find the midpoint between the 2 closest points
|
||||
// If t0 > 1, then the second edge must lie to the right of the first edge
|
||||
final Vector2dOld pu = t0 > 1 ? u : p;
|
||||
// Same as the first edge but the second edge may be inverted
|
||||
final Vector2dOld qv = ( inverted ^ t0 > 1 ) ? q : v;
|
||||
final Vector2dOld midpoint = pu.add( qv ).divide( 2.0 );
|
||||
point.x = midpoint.x;
|
||||
point.y = midpoint.y;
|
||||
}
|
||||
} else {
|
||||
// Calculate t and u
|
||||
final double t = qp.cross( s ) / rs;
|
||||
final double u = qpr / rs;
|
||||
|
||||
// Do the line segments intersect
|
||||
if ( t >= 0 && t <= 1 && u >= 0 && u <= 1 ) {
|
||||
// Calculate the point of intersection
|
||||
final Vector2dOld intersection = r.multiply( t ).add( p );
|
||||
point.x = intersection.x;
|
||||
point.y = intersection.y;
|
||||
} else {
|
||||
// No intersection, so calculate the closest point between the two segments
|
||||
// We have t and u, which we can use to find the closest endpoints
|
||||
final double nearT = Math.max( Math.min( t, 1 ), 0 );
|
||||
final double nearU = Math.max( Math.min( u, 1 ), 0 );
|
||||
|
||||
final Vector2dOld nearP = r.multiply( nearT ).add( p );
|
||||
final Vector2dOld nearQ = s.multiply( nearU ).add( q );
|
||||
|
||||
point.x = ( nearP.x + nearQ.x ) / 2.0;
|
||||
point.y = ( nearP.y + nearQ.y ) / 2.0;
|
||||
}
|
||||
}
|
||||
return point;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user