/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package connectionviewer;
import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author mrupp
*/
public class tikzGraphics2D extends EmptyGraphics2D
{
double xscale, yscale;
FileWriter file;
String colorstring, fillstring;
Color currentColor, setColor;
Rectangle baseRect;
String filename;
tikzGraphics2D(String filename, Rectangle baseRect, FileWriter file, double scaling) throws IOException
{
this.baseRect = baseRect;
this.file = file;
this.filename = filename;
setColor = currentColor = Color.BLACK;
file.write("\\begin{figure}\n"
+"\\begin{tikzpicture}\n"
+"\\centering\n"
+"\\def\\dy{0.0}\n");
fillstring=colorstring = "";
xscale= scaling;
yscale = -scaling;
}
void finish() throws IOException
{
file.write(
"\\end{tikzpicture}\n"
+"% from file "+filename+"\n"
+"\\end{figure}\n"
);
}
void filewrite(String s)
{
try {
file.write(s);
} catch (IOException ex) {
Logger.getLogger(tikzGraphics2D.class.getName()).log(Level.SEVERE, null, ex);
}
}
void checkColor()
{
if(currentColor == setColor) return;
if(currentColor.equals(setColor))
;
else if(setColor.equals(Color.BLACK))
fillstring=colorstring = "";
else
{
filewrite("\\definecolor{myc}{RGB}{" + setColor.getRed() + "," + setColor.getGreen() + "," + setColor.getBlue() + "}\n");
colorstring = "[draw=myc]";
fillstring = "[fill=myc]";
}
currentColor = setColor;
}
boolean clipLine(Line2D line, Rectangle2D rect)
{
double x1 = line.getX1();
double y1 = line.getY1();
double x2 = line.getX2();
double y2 = line.getY2();
double minX = rect.getMinX();
double maxX = rect.getMaxX();
double minY = rect.getMinY();
double maxY = rect.getMaxY();
int f1 = rect.outcode(x1, y1);
int f2 = rect.outcode(x2, y2);
while ((f1 | f2) != 0) {
if ((f1 & f2) != 0) {
return false;
}
double dx = (x2 - x1);
double dy = (y2 - y1);
// update (x1, y1), (x2, y2) and f1 and f2 using intersections
// then recheck
if (f1 != 0) {
// first point is outside, so we update it against one of the
// four sides then continue
if ((f1 & Rectangle2D.OUT_LEFT) == Rectangle2D.OUT_LEFT
&& dx != 0.0) {
y1 = y1 + (minX - x1) * dy / dx;
x1 = minX;
}
else if ((f1 & Rectangle2D.OUT_RIGHT) == Rectangle2D.OUT_RIGHT
&& dx != 0.0) {
y1 = y1 + (maxX - x1) * dy / dx;
x1 = maxX;
}
else if ((f1 & Rectangle2D.OUT_BOTTOM) == Rectangle2D.OUT_BOTTOM
&& dy != 0.0) {
x1 = x1 + (maxY - y1) * dx / dy;
y1 = maxY;
}
else if ((f1 & Rectangle2D.OUT_TOP) == Rectangle2D.OUT_TOP
&& dy != 0.0) {
x1 = x1 + (minY - y1) * dx / dy;
y1 = minY;
}
f1 = rect.outcode(x1, y1);
}
else if (f2 != 0) {
// second point is outside, so we update it against one of the
// four sides then continue
if ((f2 & Rectangle2D.OUT_LEFT) == Rectangle2D.OUT_LEFT
&& dx != 0.0) {
y2 = y2 + (minX - x2) * dy / dx;
x2 = minX;
}
else if ((f2 & Rectangle2D.OUT_RIGHT) == Rectangle2D.OUT_RIGHT
&& dx != 0.0) {
y2 = y2 + (maxX - x2) * dy / dx;
x2 = maxX;
}
else if ((f2 & Rectangle2D.OUT_BOTTOM) == Rectangle2D.OUT_BOTTOM
&& dy != 0.0) {
x2 = x2 + (maxY - y2) * dx / dy;
y2 = maxY;
}
else if ((f2 & Rectangle2D.OUT_TOP) == Rectangle2D.OUT_TOP
&& dy != 0.0) {
x2 = x2 + (minY - y2) * dx / dy;
y2 = minY;
}
f2 = rect.outcode(x2, y2);
}
}
line.setLine(x1, y1, x2, y2);
return true; // the line is visible - if it wasn't, we'd have
// returned false from within the while loop above
}
Rectangle clipRectangle(int x, int y, int dx, int dy)
{
Rectangle r = new Rectangle(x, y, dx, dy);
if(baseRect.intersects(r))
{
Rectangle result = new Rectangle();
Rectangle.intersect(baseRect, r, result);
return result;
}
else
return null;
}
boolean clipPoint(double x, double y)
{
return baseRect.contains(x, y);
}
@Override
public void drawLine(int x, int y, int x2, int y2) {
Line2D l = new Line2D.Double(x, y, x2, y2);
if(clipLine(l, baseRect))
{
checkColor();
filewrite("\\draw"+colorstring+"(" + l.getX1()/xscale + ", " + l.getY1()/yscale + ") -- ("
+ (l.getX2())/xscale + ", " + (l.getY2())/yscale + "+\\dy);\n");
}
}
@Override
public void fillRect(int x, int y, int dx, int dy) {
Rectangle r = clipRectangle(x, y, dx, dy);
if(r != null)
{
checkColor();
filewrite("\\fill"+fillstring+"("+r.x/xscale+4+","+r.y/yscale+") rectangle ("+(r.x+r.width)/xscale+","+(r.y+r.height)/yscale+");\n");
}
}
@Override
public void fillPolygon(int[] x, int[] y, int N)
{
checkColor();
filewrite("\\draw[draw=myc, fill=myc] ");
for(int i=0; i<N; i++)
filewrite("("+x[i]/xscale + "," + y[i]/yscale + ") -- ");
filewrite("(" + x[0]/xscale + "," + y[0]/yscale + ");\n");
}
@Override
public void drawString(String string, int x, int y) {
this.drawString(string, (float)x, (float)y);
}
@Override
public void drawString(String string, float x, float y) {
if(!clipPoint(x, y)) return;
//filewrite("\\draw("+x/xscale+","+y/yscale+") node {\\verb@"+string+"@};\n");
filewrite("\\draw("+((x+4)/xscale)+","+((y+4)/yscale)+") node {"+string+"};\n");
}
@Override
public void setColor(Color color) {
setColor = color;
}
}