Added new mesh class Rewrite mesh algorithms to be less error prone Make code more concise Tried to add some documentation Added half edge set
266 lines
10 KiB
Java
266 lines
10 KiB
Java
package com.aaaaahhhhhhh.bananapuncher714.tess4j;
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Graphics;
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
|
|
import javax.swing.JFrame;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.SwingUtilities;
|
|
|
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.Point;
|
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.Polygon;
|
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.Vector2d;
|
|
import com.aaaaahhhhhhh.bananapuncher714.tess4j.region.RegionSimple;
|
|
import com.aaaaahhhhhhh.bananapuncher714.tess4j.region.RegionSimple.GluWindingRule;
|
|
import com.aaaaahhhhhhh.bananapuncher714.tess4j.region.WindingRuleSimple;
|
|
|
|
public class Tess4jTest extends JPanel {
|
|
JFrame f;
|
|
|
|
private int windowWidth = 1200;
|
|
private int windowHeight = 1000;
|
|
|
|
private int centerX = 600;
|
|
private int centerY = 400;
|
|
|
|
private Graphics g;
|
|
|
|
private int scale = 100;
|
|
|
|
public static void main( String[] args ) {
|
|
SwingUtilities.invokeLater( new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
new Tess4jTest();
|
|
}
|
|
} );
|
|
}
|
|
|
|
public Tess4jTest() {
|
|
f = new JFrame( "Drawing Board" );
|
|
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
|
|
|
|
f.add( this );
|
|
|
|
f.setSize( windowWidth, windowHeight );
|
|
f.setVisible( true );
|
|
f.setResizable( true );
|
|
|
|
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
|
|
}
|
|
|
|
public void drawPoint( double x, double y ) {
|
|
g.fillRect( ( int ) x * scale, ( int ) y * scale, scale, scale );
|
|
}
|
|
|
|
private static Vector2d rotate( Vector2d a, double angle ) {
|
|
double cos = Math.cos( angle );
|
|
double sin = Math.sin( angle );
|
|
double ax = a.getX() * cos - a.getY() * sin;
|
|
double ay = a.getX() * sin + a.getY() * cos;
|
|
return new Vector2d( ax, ay );
|
|
}
|
|
|
|
@Override
|
|
public void paintComponent( Graphics g ) {
|
|
super.paintComponent( g );
|
|
this.g = g;
|
|
|
|
// Vertex v = null;
|
|
// for ( int i = 0; i < 100; i++ ) {
|
|
// double deg = Math.random() * 360;
|
|
// double dist = Math.random() * 100 + 100;
|
|
// double x = dist * Math.cos( Math.toRadians( deg ) );
|
|
// double y = dist * Math.sin( Math.toRadians( deg ) );
|
|
// HalfWing edge = new HalfWing();
|
|
// edge.getDest().setPosition( new Vector2d( x, y ) );
|
|
// if ( v == null ) {
|
|
// v = edge.getOrigin();
|
|
// } else {
|
|
// HalfWing.splice( edge, v.getWing() );
|
|
// }
|
|
// }
|
|
// v.update();
|
|
//
|
|
// HalfWing edge = v.getWing();
|
|
// int i = 0;
|
|
// double ic = 0;
|
|
// do {
|
|
// Vector2d dest = edge.getDest().getPosition();
|
|
// g.drawLine( centerX, centerY, ( int ) dest.getX() + centerX, ( int ) dest.getY() + centerY );
|
|
// dest = dest.normalized();
|
|
// g.drawString( i++ + "", ( int ) ( dest.x * 200 * ( ic + 1.1 ) ) + centerX, ( int ) ( dest.y * 200 * ( ic + 1.1 ) ) + centerY );
|
|
// ic = ( ic + 0.07 ) % .7;
|
|
// edge = edge.getPrev();
|
|
// } while ( edge != v.getWing() );
|
|
//
|
|
// v.sort();
|
|
//
|
|
// g.drawLine( centerX + 700, centerY, centerX + 700, centerY - 400 );
|
|
// edge = v.getWing();
|
|
// i = 0;
|
|
// ic = 0;
|
|
// do {
|
|
// Vector2d dest = edge.getDest().getPosition();
|
|
// g.drawLine( centerX + 700, centerY, ( int ) dest.getX() + centerX + 700, ( int ) dest.y + centerY );
|
|
// dest = dest.normalized();
|
|
// g.drawString( i++ + "", ( int ) ( dest.x * 200 * ( ic + 1.1 ) ) + centerX + 700, ( int ) ( dest.y * 200 * ( ic + 1.1 ) ) + centerY );
|
|
// ic = ( ic + 0.07 ) % .7;
|
|
// edge = edge.getPrev();
|
|
// } while ( edge != v.getWing() );
|
|
|
|
// Tess4j< RegionSimple > tess4j = new Tess4j< RegionSimple >( () -> { return new RegionSimple( GluWindingRule.ODD ); } );
|
|
Tess4j< RegionSimple > tess4j = new Tess4j< RegionSimple >( () -> { return new RegionSimple( GluWindingRule.ODD ); }, new Vector2dComparator() {
|
|
@Override
|
|
public double compareX( Vector2d a, Vector2d b ) {
|
|
a = rotate( a, 128 );
|
|
b = rotate( b, 128 );
|
|
return a.getX() - b.getX();
|
|
}
|
|
|
|
@Override
|
|
public double compareY(Vector2d a, Vector2d b ) {
|
|
a = rotate( a, 128 );
|
|
b = rotate( b, 128 );
|
|
return b.getY() - a.getY();
|
|
}
|
|
} );
|
|
// tess4j.addPolygon( new Polygon( Arrays.asList(
|
|
// new Point( -1, -1 ),
|
|
// new Point( 1, -1 ),
|
|
// new Point( 1, 1 ),
|
|
// new Point( -1, 1 )
|
|
// ) ), new WindingRuleSimple() );
|
|
// tess4j.addPolygon( new Polygon( Arrays.asList(
|
|
// new Point( -1, 1 ),
|
|
// new Point( 1, 1 ),
|
|
// new Point( 1, 3 ),
|
|
// new Point( -1, 3 )
|
|
// ) ), new WindingRuleSimple() );
|
|
// tess4j.addPolygon( new Polygon( Arrays.asList(
|
|
// new Point( -2, -1 ),
|
|
// new Point( -1, -1 ),
|
|
// new Point( -1, 2 ),
|
|
// new Point( -2, 2 )
|
|
// ) ), new WindingRuleSimple() );
|
|
// tess4j.addPolygon( new Polygon( Arrays.asList(
|
|
// new Point( -5, 0 ),
|
|
// new Point( -2, 0 ),
|
|
// new Point( -2, 1 ),
|
|
// new Point( -5, 1 )
|
|
// ) ), new WindingRuleSimple() );
|
|
// tess4j.addPolygon( new Polygon( Arrays.asList(
|
|
// new Point( -1.75, .5 ),
|
|
// new Point( 4.25, .5 ),
|
|
// new Point( -0.25, -2.5 ),
|
|
// new Point( 1.25, 2 ),
|
|
// new Point( 2.75, -2.5 )
|
|
// ) ), new WindingRuleSimple() );
|
|
// tess4j.addPolygon( new Polygon( Arrays.asList(
|
|
// new Point( -4, -2 ),
|
|
// new Point( -1, -2 ),
|
|
// new Point( -1, 1.5 ),
|
|
// new Point( -4, 1.5 )
|
|
// ) ), new WindingRuleSimple() );
|
|
// tess4j.addPolygon( new Polygon( Arrays.asList(
|
|
// new Point( -1, 0 ),
|
|
// new Point( 0, 1.5 ),
|
|
// new Point( 1, 0 )
|
|
// ) ), new WindingRuleSimple() );
|
|
// tess4j.addPolygon( new Polygon( Arrays.asList(
|
|
// new Point( 1, 0 ),
|
|
// new Point( 0, -2 ),
|
|
// new Point( -1, 0 )
|
|
// ) ), new WindingRuleSimple() );
|
|
for ( int i = 0; i < 4; i++ ) {
|
|
for ( int j = 0; j < 4; j++ ) {
|
|
tess4j.addPolygon( new Polygon( Arrays.asList(
|
|
new Point( i, j ),
|
|
new Point( i, j + 1 ),
|
|
new Point( i + 1, j + 1 ),
|
|
new Point( i + 1, j )
|
|
) ), new WindingRuleSimple() );
|
|
// tess4j.addPolygon( new Polygon( Arrays.asList(
|
|
// new Point( i, j ),
|
|
// new Point( i, j + 1 ),
|
|
// new Point( i + 1, j ),
|
|
// new Point( i + 1, j + 1 )
|
|
// ) ), new WindingRuleSimple() );
|
|
}
|
|
}
|
|
|
|
tess4j.tessellate();
|
|
|
|
List< Polygon > polygons = tess4j.getPolygons();
|
|
|
|
System.out.println( "Polygon count" );
|
|
System.out.println( polygons.size() );
|
|
for ( Polygon p : polygons ) {
|
|
System.out.println( p.getPoints().size() );
|
|
int size = p.getPoints().size();
|
|
int[] xPoints = new int[ size ];
|
|
int[] yPoints = new int[ size ];
|
|
|
|
for ( int i = 0; i < p.getPoints().size(); i++ ) {
|
|
Point point = p.getPoints().get( i );
|
|
|
|
System.out.println( point.getX() + ", " + point.getY() );
|
|
Vector2d pVec = new Vector2d( point.getX(), point.getY() );
|
|
pVec = rotate( pVec, 0 );
|
|
point = new Point( pVec.getX(), pVec.getY() );
|
|
|
|
xPoints[ i ] = ( int ) ( point.getX() * scale ) + centerX;
|
|
yPoints[ i ] = 100 - ( int ) ( point.getY() * scale ) + centerY;
|
|
}
|
|
|
|
g.setColor( new Color( ( int ) ( Math.random() * 0xFFFFFF ) ) );
|
|
g.fillPolygon( xPoints, yPoints, size );
|
|
}
|
|
|
|
g.setColor( Color.BLACK );
|
|
for ( Polygon p : polygons ) {
|
|
for ( Point point : p.getPoints() ) {
|
|
Vector2d pVec = new Vector2d( point.getX(), point.getY() );
|
|
pVec = rotate( pVec, 0 );
|
|
point = new Point( pVec.getX(), pVec.getY() );
|
|
|
|
double diff = scale * .05;
|
|
g.drawRect( ( int ) ( point.getX() * scale ) + centerX - ( int ) diff, 100 - ( int ) ( point.getY() * scale ) + centerY - ( int ) diff, ( int ) ( diff * 2 ), ( int ) ( diff * 2 ) );
|
|
}
|
|
}
|
|
|
|
g.drawLine( centerX, 0, centerX, 2000 );
|
|
g.drawLine( 0, centerY + 100, 2000, centerY + 100 );
|
|
|
|
// Point[] points = {
|
|
// new Point( 0, -2 ),
|
|
// new Point( 1.5, -3.0 ),
|
|
// new Point( 0.0, -2.0 ),
|
|
// new Point( 0.9545454545454546, -1.3636363636363638 ),
|
|
// new Point( -0.8333333333333334, -1.0 ),
|
|
// new Point( 0.8333333333333334, -1.0 ),
|
|
// new Point( -0.5, 0.0 ),
|
|
// new Point( 0.5, 0.0 ),
|
|
// new Point( -0.16666666666666669, 1.0 ),
|
|
// new Point( 0.16666666666666669, 1.0 ),
|
|
// new Point( -0.16666666666666669, 1.0 ),
|
|
// new Point( 1, 1 ),
|
|
// new Point( -0.16666666666666669, 1.0 ),
|
|
// new Point( 0, 1.5 ),
|
|
// new Point( 0, 1.5 ),
|
|
// new Point( 0.16666666666666669, 1.0 ),
|
|
// new Point( -1, 2 ),
|
|
// new Point( 1, 2 ),
|
|
// };
|
|
//
|
|
// int size = points.length >> 1;
|
|
// for ( int i = 0; i < size;i++ ) {
|
|
// Point a = points[ i << 1 ];
|
|
// Point b = points[ ( i << 1 ) + 1 ];
|
|
//
|
|
// g.drawLine( ( int ) ( a.x * scale ) + centerX, ( int ) ( a.y * scale ) + centerY, ( int ) ( b.x * scale ) + centerX, ( int ) ( b.y * scale ) + centerY );
|
|
// }
|
|
}
|
|
} |