/*
This file is part of GeoGebra.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation.
*/
package org.geogebra.common.export.pstricks;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import org.geogebra.common.awt.GAffineTransform;
import org.geogebra.common.awt.GColor;
import org.geogebra.common.awt.GFont;
import org.geogebra.common.awt.GPathIterator;
import org.geogebra.common.awt.GShape;
import org.geogebra.common.euclidian.DrawableND;
import org.geogebra.common.euclidian.draw.DrawPoint;
import org.geogebra.common.export.UnicodeTeX;
import org.geogebra.common.factories.AwtFactory;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.MyPoint;
import org.geogebra.common.kernel.StringTemplate;
import org.geogebra.common.kernel.Matrix.Coords;
import org.geogebra.common.kernel.algos.AlgoAngleLines;
import org.geogebra.common.kernel.algos.AlgoAnglePoints;
import org.geogebra.common.kernel.algos.AlgoAngleVector;
import org.geogebra.common.kernel.algos.AlgoAngleVectors;
import org.geogebra.common.kernel.algos.AlgoBoxPlot;
import org.geogebra.common.kernel.algos.AlgoElement;
import org.geogebra.common.kernel.algos.AlgoFunctionAreaSums;
import org.geogebra.common.kernel.algos.AlgoIntersectAbstract;
import org.geogebra.common.kernel.algos.AlgoSlope;
import org.geogebra.common.kernel.arithmetic.Function;
import org.geogebra.common.kernel.arithmetic.FunctionalNVar;
import org.geogebra.common.kernel.arithmetic.Inequality;
import org.geogebra.common.kernel.cas.AlgoIntegralDefinite;
import org.geogebra.common.kernel.cas.AlgoIntegralFunctions;
import org.geogebra.common.kernel.geos.GeoAngle;
import org.geogebra.common.kernel.geos.GeoAngle.AngleStyle;
import org.geogebra.common.kernel.geos.GeoConic;
import org.geogebra.common.kernel.geos.GeoConicPart;
import org.geogebra.common.kernel.geos.GeoCurveCartesian;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoElement.FillType;
import org.geogebra.common.kernel.geos.GeoFunction;
import org.geogebra.common.kernel.geos.GeoLine;
import org.geogebra.common.kernel.geos.GeoLocus;
import org.geogebra.common.kernel.geos.GeoNumeric;
import org.geogebra.common.kernel.geos.GeoPoint;
import org.geogebra.common.kernel.geos.GeoPolyLine;
import org.geogebra.common.kernel.geos.GeoPolygon;
import org.geogebra.common.kernel.geos.GeoRay;
import org.geogebra.common.kernel.geos.GeoSegment;
import org.geogebra.common.kernel.geos.GeoText;
import org.geogebra.common.kernel.geos.GeoTransferFunction;
import org.geogebra.common.kernel.geos.GeoVec3D;
import org.geogebra.common.kernel.geos.GeoVector;
import org.geogebra.common.kernel.implicit.GeoImplicit;
import org.geogebra.common.kernel.kernelND.GeoConicND;
import org.geogebra.common.kernel.kernelND.GeoConicNDConstants;
import org.geogebra.common.kernel.kernelND.GeoPointND;
import org.geogebra.common.kernel.kernelND.GeoVectorND;
import org.geogebra.common.main.App;
import org.geogebra.common.plugin.EuclidianStyleConstants;
import org.geogebra.common.util.StringTokenizer;
import org.geogebra.common.util.StringUtil;
import org.geogebra.common.util.lang.Unicode;
/**
* @author Le Coq loic
*/
public abstract class GeoGebraToPstricks extends GeoGebraExport {
private boolean eurosym = false;
private static final int FORMAT_BEAMER = 1;
private StringBuilder codeBeginPic;
/**
* Constructor for GeoGeBra export
*
* @param app
* GeoGeBra Application
*/
public GeoGebraToPstricks(App app) {
super(app);
}
@Override
public void generateAllCode() {
format = frame.getFormat();
// init unit variables
try {
xunit = frame.getXUnit();
yunit = frame.getYUnit();
} catch (NullPointerException e2) {
xunit = 1;
yunit = 1;
}
// scaleratio=yunit/xunit;
// Initialize new StringBuilder for Pstricks code
// and CustomColor
code = new StringBuilder();
codePoint = new StringBuilder();
codePreamble = new StringBuilder();
codeFilledObject = new StringBuilder();
codeBeginDoc = new StringBuilder();
codeBeginPic = new StringBuilder();
customColor = new HashMap<GColor, String>();
if (format == GeoGebraToPstricks.FORMAT_BEAMER) {
codePreamble.append(
"\\documentclass[" + frame.getFontSize() + "pt]{beamer}\n");
} else {
codePreamble.append("\\documentclass[" + frame.getFontSize()
+ "pt]{article}\n");
}
codePreamble.append("\\usepackage{pstricks-add}\n\\pagestyle{empty}\n");
codeBeginDoc.append("\\begin{document}\n");
if (format == GeoGebraToPstricks.FORMAT_BEAMER) {
codeBeginDoc.append("\\begin{frame}\n");
}
initUnitAndVariable();
// Environment pspicture
codeBeginPic.append("\\begin{pspicture*}(");
codeBeginPic.append(format(xmin));
codeBeginPic.append(",");
codeBeginPic.append(format(ymin));
codeBeginPic.append(")(");
codeBeginPic.append(format(xmax));
codeBeginPic.append(",");
codeBeginPic.append(format(ymax));
codeBeginPic.append(")\n");
if (euclidianView.getShowGrid()) {
drawGrid();
}
// Draw axis
if (euclidianView.getShowXaxis() || euclidianView.getShowYaxis()) {
drawAxis();
}
/*
* get all objects from construction and "draw" them by creating
* pstricks code
*/
drawAllElements();
/*
* Object [] geos =
* kernel.getConstruction().getGeoSetConstructionOrder().toArray(); for
* (int i=0;i<geos.length;i++){ GeoElement g = (GeoElement)(geos[i]);
* drawGeoElement(g,false); // System.out.println(g+" "
* +beamerSlideNumber); }
*/
// add code for Points and Labels
if (codePoint.length() != 0) {
codePoint.insert(0, "\\begin{scriptsize}\n");
codePoint.append("\\end{scriptsize}\n");
}
code.append(codePoint);
// Close Environment pspicture
code.append("\\end{pspicture*}\n");
/*
* String formatFont=resizeFont(app.getFontSize()); if
* (null!=formatFont){ codeBeginPic.insert(0,formatFont+"\n");
* code.append("}\n"); }
*/
code.insert(0, codeFilledObject + "");
code.insert(0, codeBeginPic + "");
code.insert(0, codeBeginDoc + "");
code.insert(0, codePreamble + "");
if (format == GeoGebraToPstricks.FORMAT_BEAMER) {
code.append("\\end{frame}\n");
}
code.append("\\end{document}");
frame.write(code);
}
@Override
protected void drawLocus(GeoLocus g) {
ArrayList<MyPoint> ll = g.getPoints();
Iterator<MyPoint> it = ll.iterator();
startBeamer(code);
code.append("\\pscustom");
code.append(lineOptionCode(g, true));
code.append("{");
boolean first = true;
boolean out = false;
while (it.hasNext()) {
MyPoint mp = it.next();
if (mp.x > xmin && mp.x < xmax && mp.y > ymin && mp.y < ymax) {
String x = format(mp.x);
String y = format(mp.y);
boolean b = mp.getLineTo();
if (first) {
code.append("\\moveto(");
first = false;
} else if (b) {
code.append("\\lineto(");
} else {
code.append("\\moveto(");
}
code.append(x);
code.append(",");
code.append(y);
code.append(")\n");
out = false;
} else if (!first && mp.getLineTo() && !out) {
out = true;
String x = format(mp.x);
String y = format(mp.y);
code.append("\\lineto(");
code.append(x);
code.append(",");
code.append(y);
code.append(")\n");
} else {
first = true;
out = false;
}
}
code.append("}\n");
endBeamer(code);
}
@Override
protected void drawBoxPlot(GeoNumeric geo) {
AlgoBoxPlot algo = ((AlgoBoxPlot) geo.getParentAlgorithm());
double y = algo.getA().getDouble();
double height = algo.getB().getDouble();
double[] lf = algo.getLeftBorders();
double min = lf[0];
double q1 = lf[1];
double med = lf[2];
double q3 = lf[3];
double max = lf[4];
startBeamer(code);
// Min vertical bar
drawLine(min, y - height, min, y + height, geo);
// Max vertical bar
drawLine(max, y - height, max, y + height, geo);
// Med vertical bar
drawLine(med, y - height, med, y + height, geo);
// Min-q1 horizontal
drawLine(min, y, q1, y, geo);
// q3-max
drawLine(q3, y, max, y, geo);
endBeamer(code);
// Rectangle q1-q3
startBeamer(codeFilledObject);
codeFilledObject.append("\\psframe");
codeFilledObject.append(lineOptionCode(geo, true));
codeFilledObject.append("(");
codeFilledObject.append(format(q1));
codeFilledObject.append(",");
codeFilledObject.append(y - height);
codeFilledObject.append(")(");
codeFilledObject.append(format(q3));
codeFilledObject.append(",");
codeFilledObject.append(format(y + height));
codeFilledObject.append(")\n");
endBeamer(codeFilledObject);
}
@Override
protected void drawSumTrapezoidal(GeoNumeric geo) {
AlgoFunctionAreaSums algo = (AlgoFunctionAreaSums) geo
.getParentAlgorithm();
int n = algo.getIntervals();
double[] y = algo.getValues();
double[] x = algo.getLeftBorder();
startBeamer(codeFilledObject);
for (int i = 0; i < n; i++) {
codeFilledObject.append("\\pspolygon");
codeFilledObject.append(lineOptionCode(geo, true));
codeFilledObject.append("(");
codeFilledObject.append(format(x[i]));
codeFilledObject.append(",0)(");
codeFilledObject.append(format(x[i + 1]));
codeFilledObject.append(",0)(");
codeFilledObject.append(format(x[i + 1]));
codeFilledObject.append(",");
codeFilledObject.append(format(y[i + 1]));
codeFilledObject.append(")(");
codeFilledObject.append(format(x[i]));
codeFilledObject.append(",");
codeFilledObject.append(format(y[i]));
codeFilledObject.append(")\n");
if (i != n - 1 && isBeamer) {
codeFilledObject.append(" ");
}
}
endBeamer(codeFilledObject);
}
@Override
protected void drawSumUpperLower(GeoNumeric geo) {
AlgoFunctionAreaSums algo = (AlgoFunctionAreaSums) geo
.getParentAlgorithm();
int n = algo.getIntervals();
double step = algo.getStep();
double[] y = algo.getValues();
double[] x = algo.getLeftBorder();
startBeamer(codeFilledObject);
for (int i = 0; i < n; i++) {
codeFilledObject.append("\\psframe");
codeFilledObject.append(lineOptionCode(geo, true));
codeFilledObject.append("(");
codeFilledObject.append(format(x[i]));
codeFilledObject.append(",0)(");
codeFilledObject.append(format(x[i] + step));
codeFilledObject.append(",");
codeFilledObject.append(format(y[i]));
codeFilledObject.append(")\n");
if (i != n - 1 && isBeamer) {
codeFilledObject.append(" ");
}
}
endBeamer(codeFilledObject);
}
@Override
protected void drawIntegralFunctions(GeoNumeric geo) {
// command:
// \pscustom[option]{\pstplot{a}{b}{f(x)}\lineto(b,g(b))\pstplot{b}{a}{g(x)}
// \lineto(a,f(a))\closepath}
AlgoIntegralFunctions algo = (AlgoIntegralFunctions) geo
.getParentAlgorithm();
// function f
GeoFunction f = algo.getF();
// function g
GeoFunction g = algo.getG();
// double a and b
double a = algo.getA().getDouble();
double b = algo.getB().getDouble();
// String output for a and b
String sa = format(a);
String sb = format(b);
// String Expression of f and g
String valueF = f.toValueString(getStringTemplate());
valueF = killSpace(StringUtil.toLaTeXString(valueF, true));
String valueG = g.toValueString(getStringTemplate());
valueG = killSpace(StringUtil.toLaTeXString(valueG, true));
// String expressions for f(a) and g(b)
String fa = format(f.value(a));
String gb = format(g.value(b));
startBeamer(codeFilledObject);
codeFilledObject.append("\\pscustom");
codeFilledObject.append(lineOptionCode(geo, true));
codeFilledObject.append("{\\psplot{");
codeFilledObject.append(sa);
codeFilledObject.append("}{");
codeFilledObject.append(sb);
codeFilledObject.append("}{");
codeFilledObject.append(valueF);
codeFilledObject.append("}\\lineto(");
codeFilledObject.append(sb);
codeFilledObject.append(",");
codeFilledObject.append(gb);
codeFilledObject.append(")\\psplot{");
codeFilledObject.append(sb);
codeFilledObject.append("}{");
codeFilledObject.append(sa);
codeFilledObject.append("}{");
codeFilledObject.append(valueG);
codeFilledObject.append("}\\lineto(");
codeFilledObject.append(sa);
codeFilledObject.append(",");
codeFilledObject.append(fa);
codeFilledObject.append(")\\closepath}\n");
endBeamer(codeFilledObject);
}
@Override
protected void drawIntegral(GeoNumeric geo) {
// command:
// \pscutom[option]{\pstplot{a}{b}{f(x)}\lineto(b,0)\lineto(a,0)\closepath}
AlgoIntegralDefinite algo = (AlgoIntegralDefinite) geo
.getParentAlgorithm();
// function f
GeoFunction f = algo.getFunction();
// between a and b
String a = format(algo.getA().getDouble());
String b = format(algo.getB().getDouble());
String value = f.toValueString(getStringTemplate());
value = killSpace(StringUtil.toLaTeXString(value, true));
if (a.substring(a.length() - 1).equals("" + Unicode.INFINITY)) {
a = format(xmin);
}
if (b.substring(b.length() - 1).equals("" + Unicode.INFINITY)) {
b = format(xmax);
}
startBeamer(codeFilledObject);
if (!isLatexFunction(f.toValueString(StringTemplate.noLocalDefault))) {
double af = xmin;
double bf = xmax;
if (f.hasInterval()) {
af = f.getIntervalMin();
bf = f.getIntervalMax();
}
f.setInterval(kernel.getAlgebraProcessor().evaluateToDouble(a),
kernel.getAlgebraProcessor().evaluateToDouble(b));
code.append("\\pscustom");
f.setInterval(algo.getA().getDouble(), algo.getB().getDouble());
drawFunction(f, true, geo);
f.setInterval(af, bf);
if (f.isEuclidianVisible()) {
drawFunction(f, false, geo);
}
/*
* if (f.isEuclidianVisible()) { String liop = LineOptionCode(geo,
* true); GColor col = geo.getObjectColor();
* geo.setObjColor(f.getObjectColor()); String liopf =
* LineOptionCode(f, true); if (!"".equals(liopf)) { int beginf =
* liopf.indexOf("linecolor"); int endf = liopf.indexOf(",",
* beginf); if (endf < 0 && beginf >-1) { endf = liopf.indexOf("]",
* beginf); } else{ if (beginf<0){ liopf="linecolor=black";
* beginf=0; endf=liopf.length(); } } liopf =
* liopf.substring(beginf, endf); liop = liop.replace("]", "," +
* liopf + "]"); } else { int beginl = liop.indexOf("linecolor");
* int endl = liop.indexOf(",", beginl); liop =
* liop.replace(liop.substring(beginl, endl), ""); }
* code.append(liop); geo.setObjColor(col); } else {
* code.append(LineOptionCode(geo, true)); } code.append("{");
* drawFunction(f); x=algo.getB().getDouble(); if
* (algo.getB().getDouble() > xmax) { String last =
* code.substring(code.lastIndexOf("line") + 4); x =
* Double.parseDouble(last.split(",")[1].split("\\(")[1]); }
* code.append("\\psline(" + x + "," + 0 + ")\n");
* code.append("\\psline(" + algo.getA().getDouble() + "," + 0 +
* ")\n"); code.append("\\closepath}\n"); f.setInterval(af, bf); if
* (f.isEuclidianVisible()) { code.append("\\psline" +
* LineOptionCode(geo, true) + "(" + x + "," + 0 + ")\n");
* code.append("\\psline" + LineOptionCode(geo, true) + "(" +
* algo.getA().getDouble() + "," + 0 + ")\n"); drawFunction(f); }
*/
} else {
codeFilledObject.append("\\pscustom");
codeFilledObject.append(lineOptionCode(geo, true));
codeFilledObject.append("{\\psplot{");
codeFilledObject.append(a);
codeFilledObject.append("}{");
codeFilledObject.append(b);
codeFilledObject.append("}{");
codeFilledObject.append(value);
codeFilledObject.append("}\\lineto(");
codeFilledObject.append(b);
codeFilledObject.append(",0)\\lineto(");
codeFilledObject.append(a);
codeFilledObject.append(",0)\\closepath}\n");
}
endBeamer(codeFilledObject);
}
@Override
protected void drawSlope(GeoNumeric geo) {
int slopeTriangleSize = geo.getSlopeTriangleSize();
double rwHeight = geo.getValue() * slopeTriangleSize;
double height = euclidianView.getYscale() * rwHeight;
double[] coords = new double[2];
if (Math.abs(height) > Float.MAX_VALUE) {
return;
}
// get point on line g
((AlgoSlope) geo.getParentAlgorithm()).getInhomPointOnLine(coords);
// draw slope triangle
double x = coords[0];
double y = coords[1];
double xright = x + slopeTriangleSize;
startBeamer(codeFilledObject);
codeFilledObject.append("\\pspolygon");
codeFilledObject.append(lineOptionCode(geo, true));
codeFilledObject.append("(");
codeFilledObject.append(format(x));
codeFilledObject.append(",");
codeFilledObject.append(format(y));
codeFilledObject.append(")");
codeFilledObject.append("(");
codeFilledObject.append(format(xright));
codeFilledObject.append(",");
codeFilledObject.append(format(y));
codeFilledObject.append(")");
codeFilledObject.append("(");
codeFilledObject.append(format(xright));
codeFilledObject.append(",");
codeFilledObject.append(format(y + rwHeight));
codeFilledObject.append(")");
codeFilledObject.append("\n");
endBeamer(codeFilledObject);
// draw Label
double xLabelHor = (x + xright) / 2;
double yLabelHor = y - ((euclidianView.getFont().getSize() + 2)
/ euclidianView.getYscale());
GColor geocolor = geo.getObjectColor();
startBeamer(codePoint);
codePoint.append("\\rput[bl](");
codePoint.append(format(xLabelHor));
codePoint.append(",");
codePoint.append(format(yLabelHor));
codePoint.append("){");
if (!geocolor.equals(GColor.BLACK)) {
codePoint.append("\\");
colorCode(geocolor, codePoint);
codePoint.append("{");
}
codePoint.append(slopeTriangleSize);
if (!geocolor.equals(GColor.BLACK)) {
codePoint.append("}");
}
codePoint.append("}\n");
endBeamer(codePoint);
}
@Override
protected void drawAngle(GeoAngle geo) {
int arcSize = geo.getArcSize();
AlgoElement algo = geo.getParentAlgorithm();
GeoPointND vertex, point;
GeoVectorND v;
GeoPoint tempPoint = new GeoPoint(construction);
tempPoint.setCoords(0.0, 0.0, 1.0);
double[] firstVec = new double[2];
double[] m = new double[2];
// angle defines with three points
if (algo instanceof AlgoAnglePoints) {
AlgoAnglePoints pa = (AlgoAnglePoints) algo;
vertex = pa.getB();
point = pa.getA();
vertex.getInhomCoords(m);
// first vec
Coords coords = point.getInhomCoordsInD3();
firstVec[0] = coords.getX() - m[0];
firstVec[1] = coords.getY() - m[1];
}
// angle between two vectors
else if (algo instanceof AlgoAngleVectors) {
AlgoAngleVectors va = (AlgoAngleVectors) algo;
v = va.getv();
// vertex
vertex = v.getStartPoint();
if (vertex == null) {
vertex = tempPoint;
}
vertex.getInhomCoords(m);
// first vec
v.getInhomCoords(firstVec);
}
// angle between two lines
else if (algo instanceof AlgoAngleLines) {
AlgoAngleLines la = (AlgoAngleLines) algo;
vertex = tempPoint;
la.updateDrawInfo(m, firstVec, null);
}
// angle of a single vector or a single point
else if (algo instanceof AlgoAngleVector) {
AlgoAngleVector va = (AlgoAngleVector) algo;
GeoVec3D vec = va.getVec3D();
if (vec instanceof GeoVector) {
v = (GeoVector) vec;
// vertex
vertex = v.getStartPoint();
if (vertex == null) {
vertex = tempPoint;
}
vertex.getInhomCoords(m);
} else if (vec instanceof GeoPoint) {
vertex = tempPoint;
// vertex
vertex.getInhomCoords(m);
}
firstVec[0] = 1;
firstVec[1] = 0;
}
tempPoint.remove(); // Michael Borcherds 2008-08-20
double angSt = Math.atan2(firstVec[1], firstVec[0]);
// Michael Borcherds 2007-10-21 BEGIN
// double angExt = geo.getValue();
double angExt = geo.getRawAngle();
if (angExt > Math.PI * 2) {
angExt -= Math.PI * 2;
}
// if (geo.getAngleStyle() == GeoAngle.ANGLE_ISCLOCKWISE) {
// angSt += angExt;
// angExt = 2.0 * Math.PI - angExt;
// }
if (geo.getAngleStyle() == AngleStyle.NOTREFLEX) {
if (angExt > Math.PI) {
angSt += angExt;
angExt = 2.0 * Math.PI - angExt;
}
}
if (geo.getAngleStyle() == AngleStyle.ISREFLEX) {
if (angExt < Math.PI) {
angSt += angExt;
angExt = 2.0 * Math.PI - angExt;
}
}
// if (geo.changedReflexAngle()) {
// angSt = angSt - angExt;
// }
// Michael Borcherds 2007-10-21 END
angExt += angSt;
double r = arcSize / euclidianView.getXscale();
// if angle=90degrees and decoration=little square
if (Kernel.isEqual(geo.getValue(), Kernel.PI_HALF)
&& geo.isEmphasizeRightAngle() && euclidianView
.getRightAngleStyle() == EuclidianStyleConstants.RIGHT_ANGLE_STYLE_SQUARE) {
r = r / Math.sqrt(2);
double[] x = new double[8];
x[0] = m[0] + r * Math.cos(angSt);
x[1] = m[1] + r * Math.sin(angSt);
x[2] = m[0]
+ r * Math.sqrt(2) * Math.cos(angSt + Kernel.PI_HALF / 2);
x[3] = m[1]
+ r * Math.sqrt(2) * Math.sin(angSt + Kernel.PI_HALF / 2);
x[4] = m[0] + r * Math.cos(angSt + Kernel.PI_HALF);
x[5] = m[1] + r * Math.sin(angSt + Kernel.PI_HALF);
x[6] = m[0];
x[7] = m[1];
// command: \pspolygon[par](x0,y0)....(xn,yn)
startBeamer(codeFilledObject);
codeFilledObject.append("\\pspolygon");
codeFilledObject.append(lineOptionCode(geo, true));
for (int i = 0; i < 4; i++) {
codeFilledObject.append("(");
codeFilledObject.append(format(x[2 * i]));
codeFilledObject.append(",");
codeFilledObject.append(format(x[2 * i + 1]));
codeFilledObject.append(")");
}
codeFilledObject.append("\n");
endBeamer(codeFilledObject);
}
// draw arc for the angle
else {
// set arc in real world coords
GColor geocolor = geo.getObjectColor();
startBeamer(code);
if (!geocolor.equals(GColor.BLACK)) {
code.append("\\pscustom");
code.append(lineOptionCode(geo, true));
code.append("{\n");
}
code.append("\\parametricplot{");
code.append(angSt);
code.append("}{");
code.append(angExt);
code.append("}{");
code.append(format(r));
code.append("*cos(t)+");
code.append(format(m[0]));
code.append("|");
code.append(format(r));
code.append("*sin(t)+");
code.append(format(m[1]));
code.append("}\n");
if (!geocolor.equals(GColor.BLACK)) {
code.append("\\lineto(");
code.append(format(m[0]));
code.append(",");
code.append(format(m[1]));
code.append(")\\closepath}\n");
}
endBeamer(code);
/*
* startBeamer(code); code.append("\\pscustom");
* code.append(LineOptionCode(geo, true));
* code.append("{\\parametricplot{"); code.append(angSt);
* code.append("}{"); code.append(angExt); code.append("}{");
* code.append(format(r)); code.append("*cos(t)+");
* code.append(format(m[0])); code.append("|");
* code.append(format(r)); code.append("*sin(t)+");
* code.append(format(m[1])); code.append("}");
* code.append("\\lineto("); code.append(format(m[0]));
* code.append(","); code.append(format(m[1]));
* code.append(")\\closepath}\n"); endBeamer(code);
*/
// draw the dot if angle= 90 and decoration=dot
if (Kernel.isEqual(geo.getValue(), Kernel.PI_HALF)
&& geo.isEmphasizeRightAngle() && euclidianView
.getRightAngleStyle() == EuclidianStyleConstants.RIGHT_ANGLE_STYLE_DOT) {
double diameter = geo.getLineThickness()
/ euclidianView.getXscale();
double radius = arcSize / euclidianView.getXscale() / 1.7;
double labelAngle = (angSt + angExt) / 2.0;
double x1 = m[0] + radius * Math.cos(labelAngle);
double x2 = m[1] + radius * Math.sin(labelAngle);
// draw an ellipse
// command: \psellipse(0,0)(20.81,-10.81)}
startBeamer(code);
code.append("\\psellipse*");
code.append(lineOptionCode(geo, true));
code.append("(");
code.append(format(x1));
code.append(",");
code.append(format(x2));
code.append(")(");
code.append(format(diameter));
code.append(",");
code.append(format(diameter));
code.append(")\n");
endBeamer(code);
}
}
int deco = geo.getDecorationType();
if (deco != GeoElement.DECORATION_NONE) {
startBeamer(code);
markAngle(geo, r, m, angSt, angExt);
endBeamer(code);
}
}
@Override
protected void drawArrowArc(GeoAngle geo, double[] vertex, double angSt,
double angEnd, double r, boolean anticlockwise) {
// The arrow head goes away from the line.
// Arrow Winset=0.25, see PStricks spec for arrows
double arrowHeight = (geo.getLineThickness() * 0.8 + 3) * 1.4 * 3 / 4;
double angle = Math
.asin(arrowHeight / 2 / euclidianView.getXscale() / r);
double angSpan = angEnd - angle;
startBeamer(code);
code.append("\\psellipticarc");
code.append(lineOptionCode(geo, false));
if (anticlockwise) {
code.append("{->}(");
} else {
code.append("{<-}(");
}
code.append(format(vertex[0]));
code.append(",");
code.append(format(vertex[1]));
code.append(")(");
code.append(format(r));
code.append(",");
code.append(format(r));
code.append("){");
code.append(format(Math.toDegrees(angSt)));
code.append("}{");
code.append(format(Math.toDegrees(angSpan)));
code.append("}\n");
endBeamer(code);
}
@Override
protected void drawArc(GeoAngle geo, double[] vertex, double angSt,
double angEnd, double r) {
if (isBeamer) {
code.append(" ");
}
code.append("\\parametricplot");
code.append(lineOptionCode(geo, false));
code.append("{");
code.append(angSt);
code.append("}{");
code.append(angEnd);
code.append("}{");
code.append(format(r));
code.append("*cos(t)+");
code.append(format(vertex[0]));
code.append("|");
code.append(format(r));
code.append("*sin(t)+");
code.append(format(vertex[1]));
code.append("}\n");
}
@Override
protected void drawTick(GeoAngle geo, double[] vertex, double angle) {
double sin = Math.sin(-angle);
double cos = Math.cos(angle);
double radius = geo.getArcSize();
double diff = 2.5 + geo.getLineThickness() / 4d;
double x1 = euclidianView.toRealWorldCoordX(vertex[0] + (radius - diff)
* cos);
double x2 = euclidianView.toRealWorldCoordX(vertex[0] + (radius + diff)
* cos);
double y1 = euclidianView.toRealWorldCoordY(vertex[1] + (radius - diff)
* sin * euclidianView.getScaleRatio());
double y2 = euclidianView.toRealWorldCoordY(vertex[1] + (radius + diff)
* sin * euclidianView.getScaleRatio());
if (isBeamer) {
code.append(" ");
}
code.append("\\psline");
code.append(lineOptionCode(geo, false));
code.append("(");
code.append(format(x1));
code.append(",");
code.append(format(y1));
code.append(")(");
code.append(format(x2));
code.append(",");
code.append(format(y2));
code.append(")\n");
}
@Override
protected void drawSlider(GeoNumeric geo) {
boolean horizontal = geo.isSliderHorizontal();
double max = geo.getIntervalMax();
double min = geo.getIntervalMin();
double value = geo.getValue();
double width = geo.getSliderWidth();
double x = geo.getSliderX();
double y = geo.getSliderY();
// start point of horizontal line for slider
if (geo.isAbsoluteScreenLocActive()) {
x = euclidianView.toRealWorldCoordX(x);
y = euclidianView.toRealWorldCoordY(y);
width = horizontal ? width / euclidianView.getXscale()
: width / euclidianView.getYscale();
}
// create point for slider
GeoPoint geoPoint = new GeoPoint(construction);
geoPoint.setObjColor(geo.getObjectColor());
String label = StringUtil.toLaTeXString(geo.getLabelDescription(),
true);
geoPoint.setLabel(label);
double param = (value - min) / (max - min);
geoPoint.setPointSize(2 + (geo.getLineThickness() + 1) / 3);
geoPoint.setLabelVisible(geo.isLabelVisible());
if (horizontal) {
geoPoint.setCoords(x + width * param, y, 1.0);
} else {
geoPoint.setCoords(x, y + width * param, 1.0);
}
DrawPoint drawPoint = new DrawPoint(euclidianView, geoPoint);
drawPoint.setGeoElement(geo);
if (geo.isLabelVisible()) {
if (horizontal) {
drawPoint.xLabel -= 15;
drawPoint.yLabel -= 5;
} else {
drawPoint.xLabel += 5;
drawPoint.yLabel += 2 * geoPoint.getPointSize() + 4;
}
}
drawGeoPoint(geoPoint);
drawLabel(geoPoint, drawPoint);
geoPoint.remove(); // Michael Borcherds 2008-08-20
startBeamer(code);
// draw Line for Slider
code.append("\\psline");
code.append(lineOptionCode(geo, true));
code.append("(");
code.append(format(x));
code.append(",");
code.append(format(y));
code.append(")(");
if (horizontal) {
x += width;
} else {
y += width;
}
code.append(format(x));
code.append(",");
code.append(format(y));
code.append(")\n");
endBeamer(code);
}
@Override
protected void drawPolygon(GeoPolygon geo) {
// command: \pspolygon[par](x0,y0)....(xn,yn)
double alpha = geo.getAlphaValue();
if (alpha == 0.0f && geo.getFillType() == FillType.IMAGE) {
return;
}
startBeamer(codeFilledObject);
codeFilledObject.append("\\pspolygon");
codeFilledObject.append(lineOptionCode(geo, true));
GeoPointND[] points = geo.getPoints();
for (int i = 0; i < points.length; i++) {
Coords coords = points[i].getCoordsInD2();
double x = coords.getX(), y = coords.getY(), z = coords.getZ();
x = x / z;
y = y / z;
codeFilledObject.append("(");
codeFilledObject.append(format(x));
codeFilledObject.append(",");
codeFilledObject.append(format(y));
codeFilledObject.append(")");
}
codeFilledObject.append("\n");
endBeamer(codeFilledObject);
}
@Override
protected void drawText(GeoText geo) {
boolean isLatex = geo.isLaTeX();
String st = geo.getTextString();
GColor geocolor = geo.getObjectColor();
int style = geo.getFontStyle();
int size = (int) (geo.getFontSizeMultiplier() * getApp().getFontSize());
GeoPoint gp;
double x, y;
// compute location of text
if (geo.isAbsoluteScreenLocActive()) {
x = geo.getAbsoluteScreenLocX();
y = geo.getAbsoluteScreenLocY();
} else {
gp = (GeoPoint) geo.getStartPoint();
if (gp == null) {
x = (int) euclidianView.getXZero();
y = (int) euclidianView.getYZero();
} else {
if (!gp.isDefined()) {
return;
}
x = euclidianView.toScreenCoordX(gp.inhomX);
y = euclidianView.toScreenCoordY(gp.inhomY);
}
x += geo.labelOffsetX;
y += geo.labelOffsetY;
}
x = euclidianView.toRealWorldCoordX(x);
y = euclidianView
.toRealWorldCoordY(y - euclidianView.getFont().getSize());
int id = st.indexOf("\n");
startBeamer(code);
// One line
if (id == -1 || isLatex) {
code.append("\\rput[tl](");
code.append(format(x));
code.append(",");
code.append(format(y));
code.append("){");
addText(st, isLatex, style, geocolor);
code.append("}\n");
}
// MultiLine
else {
StringBuilder sb = new StringBuilder();
StringTokenizer stk = new StringTokenizer(st, "\n");
int width = 0;
GFont font = AwtFactory.getPrototype().newFont(
geo.isSerifFont() ? "Serif" : "SansSerif", style, size);
while (stk.hasMoreTokens()) {
String line = stk.nextToken();
width = Math.max(width, (int) Math.ceil(
StringUtil.getPrototype().estimateLength(line, font)));
sb.append(line);
if (stk.hasMoreTokens()) {
sb.append(" \\\\ ");
}
}
code.append("\\rput[lt](");
code.append(format(x));
code.append(",");
code.append(format(y));
code.append("){\\parbox{");
code.append(format(
width * (xmax - xmin) * xunit / euclidianView.getWidth()
+ 1));
code.append(" cm}{");
addText(new String(sb), isLatex, style, geocolor);
code.append("}}\n");
}
endBeamer(code);
}
@Override
protected void drawGeoConicPart(GeoConicPart geo) {
double r1 = geo.getHalfAxes()[0];
double r2 = geo.getHalfAxes()[1];
double startAngle = geo.getParameterStart();
double endAngle = geo.getParameterEnd();
// Get all coefficients form the transform matrix
GAffineTransform af = geo.getAffineTransform();
double m11 = af.getScaleX();
double m22 = af.getScaleY();
double m12 = af.getShearX();
double m21 = af.getShearY();
double tx = af.getTranslateX();
double ty = af.getTranslateY();
startBeamer(code);
// Sector command:
// \pscustom[options]{\parametricplot{startAngle}{endAngle}{x+r*cos(t),y+r*sin(t)}\lineto(x,y)\closepath}
if (geo.getConicPartType() == GeoConicNDConstants.CONIC_PART_SECTOR) {
code.append("\\pscustom");
code.append(lineOptionCode(geo, true));
code.append("{\\parametricplot{");
} else if (geo
.getConicPartType() == GeoConicNDConstants.CONIC_PART_ARC) {
code.append("\\parametricplot");
code.append(lineOptionCode(geo, true));
code.append("{");
}
if (startAngle > endAngle) {
startAngle -= Math.PI * 2;
}
StringBuilder sb1 = new StringBuilder();
sb1.append(format(r1));
sb1.append("*cos(t)");
StringBuilder sb2 = new StringBuilder();
sb2.append(format(r2));
sb2.append("*sin(t)");
code.append(startAngle);
code.append("}{");
code.append(endAngle);
code.append("}{");
code.append(format(m11));
code.append("*");
code.append(sb1);
code.append("+");
code.append(format(m12));
code.append("*");
code.append(sb2);
code.append("+");
code.append(format(tx));
code.append("|");
code.append(format(m21));
code.append("*");
code.append(sb1);
code.append("+");
code.append(format(m22));
code.append("*");
code.append(sb2);
code.append("+");
code.append(format(ty));
code.append("}");
if (geo.getConicPartType() == GeoConicNDConstants.CONIC_PART_SECTOR) {
code.append("\\lineto(");
code.append(format(tx));
code.append(",");
code.append(format(ty));
code.append(")\\closepath}");
}
code.append("\n");
// }
endBeamer(code);
}
@Override
protected void drawSingleCurveCartesian(GeoCurveCartesian geo,
boolean trasparency) {
double start = geo.getMinParameter();
double end = geo.getMaxParameter();
// boolean isClosed=geo.isClosedPath();
String fx = geo.getFunX(getStringTemplate());
fx = killSpace(StringUtil.toLaTeXString(fx, true));
String fy = geo.getFunY(getStringTemplate());
fy = killSpace(StringUtil.toLaTeXString(fy, true));
String variable = geo.getVarString(getStringTemplate());
boolean warning = !("t".equals(variable));
startBeamer(code);
if (warning) {
code.append(
"% WARNING: You have to use the special variable t in parametric plot");
}
code.append("\\parametricplot");
code.append(lineOptionCode(geo, trasparency));
int index = code.lastIndexOf("]");
if (index == code.length() - 1) {
code.deleteCharAt(index);
code.append("]{");
} else {
code.append("{");
}
code.append(start);
code.append("}{");
code.append(end);
code.append("}{");
code.append(fx);
code.append("|");
code.append(fy);
code.append("}\n");
endBeamer(code);
}
@Override
protected void drawFunction(GeoFunction geo) {
drawFunction(geo, false, null);
}
/**
* @param geo
* function
* @param integral
* whether to shade are below
* @param geo1
* integral
*/
protected void drawFunction(GeoFunction geo, boolean integral,
GeoNumeric geo1) {
// line contains the row that define function
StringBuilder line = new StringBuilder();
Function f = geo.getFunction();
if (null == f) {
return;
}
String value = f.toValueString(getStringTemplate());
value = killSpace(StringUtil.toLaTeXString(value, true));
double a = xmin;
double b = xmax;
if (geo.hasInterval()) {
a = Math.max(a, geo.getIntervalMin());
b = Math.min(b, geo.getIntervalMax());
}
double xrangemax = a, xrangemin = a;
while (xrangemax < b) {
xrangemin = firstDefinedValue(geo, a, b);
// Application.debug("xrangemin "+xrangemin);
if (xrangemin == b) {
break;
}
xrangemax = maxDefinedValue(geo, xrangemin, b);
// Application.debug("xrangemax "+xrangemax);
startBeamer(code);
line.append("\\psplot");
// loc contains style, size etc.
// is used in the case of non latex function, to assign lines style
String liopco = lineOptionCode(geo, true);
int index = liopco.lastIndexOf("]");
if (index != -1 && index == liopco.length() - 1) {
liopco = liopco.substring(0, liopco.length() - 1);
liopco += ",plotpoints=200]{";
} else {
liopco += "[plotpoints=200]{";
}
line.append(liopco);
line.append(xrangemin);
line.append("}{");
line.append(xrangemax);
line.append("}{");
line.append(value);
line.append("}\n");
xrangemax += PRECISION_XRANGE_FUNCTION;
String s = line.toString();
// if is'n latex function draws the function as a set of lines
if (!isLatexFunction(
f.toValueString(StringTemplate.noLocalDefault))) {
liopco = liopco.replace(",plotpoints=200]{", "]");
liopco = liopco.replace("[plotpoints=200]{", "");
String pre = "";
String post = "";
String template = "\\psline" + liopco + "(%0,%1)(%2,%3)\n";
StringBuilder lineBuilder = drawNoLatexFunction(geo, xrangemax,
xrangemin, 200, template);
s = lineBuilder.toString();
if (integral) {
code.append(lineOptionCode(geo1, true));
pre = "{";
post = "(" + b + "," + f.value(b) + ")(" + b + ",0)\n";
post += "(" + b + ",0)(" + a + ",0)\n";
post += "(" + a + ",0)(" + a + "," + f.value(a) + ")}\n";
}
s = pre + s + post;
code.append(s);
} else {
code.append(line);
}
a = xrangemax;
endBeamer(code);
}
}
/**
* We have to rewrite the function - kill spaces - add character * when
* needed - rename several functions (done in #ExpressionNode.toString()) -
* rename constants
*/
private static String killSpace(String name) {
// 2 x +3 ----> 2*x+3
StringBuilder sb = new StringBuilder();
boolean operand = false;
boolean space = false;
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
if ("*/+-".indexOf(c) != -1) {
sb.append(c);
operand = true;
space = false;
} else if (c == ' ') {
if (!operand) {
space = true;
} else {
space = false;
operand = false;
}
} else {
if (space && !name.contains("If")) {
sb.append("*");
}
sb.append(c);
space = false;
operand = false;
}
}
// for exponential in new Geogbra version.
renameFunc(sb, Unicode.EULER_STRING, "2.718281828");
renameFunc(sb, "\\pi", "PI");
return new String(sb);
}
@Override
protected void drawGeoVector(GeoVector geo) {
GeoPointND pointStart = geo.getStartPoint();
String x1, y1;
if (null == pointStart) {
x1 = "0";
y1 = "0";
} else {
Coords c = pointStart.getCoords();
x1 = format(c.getX() / c.getZ());
y1 = format(c.getY() / c.getZ());
}
double[] coord = new double[3];
geo.getCoords(coord);
String x2 = format(
coord[0] + kernel.getAlgebraProcessor().evaluateToDouble(x1));
String y2 = format(
coord[1] + kernel.getAlgebraProcessor().evaluateToDouble(y1));
startBeamer(code);
code.append("\\psline");
code.append(lineOptionCode(geo, true));
code.append("{->}(");
code.append(x1);
code.append(",");
code.append(y1);
code.append(")(");
code.append(x2);
code.append(",");
code.append(y2);
code.append(")\n");
endBeamer(code);
}
private void drawCircle(GeoConic geo) {
StringBuilder s = new StringBuilder();
if (xunit == yunit) {
// draw a circle
// command: \pscircle[options](x_center,y_center){Radius)}
double x = geo.getTranslationVector().getX();
double y = geo.getTranslationVector().getY();
double r = geo.getHalfAxes()[0];
startBeamer(s);
s.append("\\pscircle");
s.append(lineOptionCode(geo, true));
s.append("(");
s.append(format(x));
s.append(",");
s.append(format(y));
s.append("){");
String tmpr = format(r * xunit);
if (kernel.getAlgebraProcessor().evaluateToDouble(tmpr) != 0) {
s.append(tmpr);
} else {
s.append(r);
}
s.append("}\n");
endBeamer(s);
} else {
// draw an ellipse
// command: \psellipse(0,0)(20.81,-10.81)}
double x1 = geo.getTranslationVector().getX();
double y1 = geo.getTranslationVector().getY();
double r1 = geo.getHalfAxes()[0];
double r2 = geo.getHalfAxes()[1];
startBeamer(s);
s.append("\\psellipse");
s.append(lineOptionCode(geo, true));
s.append("(");
s.append(format(x1));
s.append(",");
s.append(format(y1));
s.append(")(");
s.append(format(r1));
s.append(",");
s.append(format(r2));
s.append(")\n");
endBeamer(s);
}
if (geo.getAlphaValue() > 0.0f) {
codeFilledObject.append(s);
} else {
code.append(s);
}
}
@Override
protected void drawGeoConic(GeoConic geo) {
switch (geo.getType()) {
default:
// do nothing
break;
// if conic is a circle
case GeoConicNDConstants.CONIC_CIRCLE:
drawCircle(geo);
break;
// if conic is an ellipse
case GeoConicNDConstants.CONIC_ELLIPSE:
// command:
// \rput{angle}(x_center,y_center){\psellipse(0,0)(20.81,-10.81)}
GAffineTransform at = geo.getAffineTransform();
double eigenvecX = at.getScaleX();
double eigenvecY = at.getShearY();
double x1 = geo.getTranslationVector().getX();
double y1 = geo.getTranslationVector().getY();
double r1 = geo.getHalfAxes()[0];
double r2 = geo.getHalfAxes()[1];
double angle = Math.toDegrees(Math.atan2(eigenvecY, eigenvecX));
startBeamer(code);
code.append("\\rput{");
code.append(format(angle));
code.append("}(");
code.append(format(x1));
code.append(",");
code.append(format(y1));
code.append("){\\psellipse");
code.append(lineOptionCode(geo, true));
code.append("(0,0)(");
code.append(format(r1));
code.append(",");
code.append(format(r2));
code.append(")}\n");
endBeamer(code);
break;
// if conic is a parabola
case GeoConicNDConstants.CONIC_PARABOLA:
// command:
// \rput{angle_rotation}(x_origin,y_origin){\pstplot{xmin}{xmax}{x^2/2/p}}
// parameter of the parabola
double p = geo.p;
at = geo.getAffineTransform();
// first eigenvec
eigenvecX = at.getScaleX();
eigenvecY = at.getShearY();
// vertex
x1 = geo.getTranslationVector().getX();
y1 = geo.getTranslationVector().getY();
// calculate the x range to draw the parabola
double x0 = Math.max(Math.abs(x1 - xmin), Math.abs(x1 - xmax));
x0 = Math.max(x0, Math.abs(y1 - ymin));
x0 = Math.max(x0, Math.abs(y1 - ymax));
// avoid sqrt by choosing x = k*p with
// i = 2*k is quadratic number
// make parabola big enough: k*p >= 2*x0 -> 2*k >= 4*x0/p
x0 = 4 * x0 / p;
int i = 4;
int k2 = 16;
while (k2 < x0) {
i += 2;
k2 = i * i;
}
// x0 = k2/2 * p; // x = k*p
x0 = i * p; // y = sqrt(2k p^2) = i p
angle = Math.toDegrees(Math.atan2(eigenvecY, eigenvecX)) - 90;
startBeamer(code);
code.append("\\rput{");
code.append(format(angle));
code.append("}(");
code.append(format(x1));
code.append(",");
code.append(format(y1));
code.append("){\\psplot");
code.append(lineOptionCode(geo, true));
code.append("{");
code.append(format(-x0));
code.append("}{");
code.append(format(x0));
code.append("}");
code.append("{x^2/2/");
code.append(format(p));
code.append("}}\n");
endBeamer(code);
break;
case GeoConicNDConstants.CONIC_HYPERBOLA:
// command:
// \rput{angle_rotation}(x_origin,y_origin){\parametric{-1}{1}{a(1+t^2)/(1-t^2)|2bt/(1-t^2)}
at = geo.getAffineTransform();
eigenvecX = at.getScaleX();
eigenvecY = at.getShearY();
x1 = geo.getTranslationVector().getX();
y1 = geo.getTranslationVector().getY();
r1 = geo.getHalfAxes()[0];
r2 = geo.getHalfAxes()[1];
angle = Math.toDegrees(Math.atan2(eigenvecY, eigenvecX));
startBeamer(code);
code.append("\\rput{");
code.append(format(angle));
code.append("}(");
code.append(format(x1));
code.append(",");
code.append(format(y1));
code.append("){\\parametricplot");
code.append(lineOptionCode(geo, true));
code.append("{-0.99}{0.99}{");
code.append(format(r1));
code.append("*(1+t^2)/(1-t^2)|");
code.append(format(r2));
code.append("*2*t/(1-t^2)");
code.append("}}\n");
code.append("\\rput{");
code.append(format(angle));
code.append("}(");
code.append(format(x1));
code.append(",");
code.append(format(y1));
code.append("){\\parametricplot");
code.append(lineOptionCode(geo, true));
code.append("{-0.99}{0.99}{");
code.append(format(r1));
code.append("*(-1-t^2)/(1-t^2)|");
code.append(format(r2));
code.append("*(-2)*t/(1-t^2)");
code.append("}}\n");
endBeamer(code);
break;
}
}
@Override
protected void drawGeoPoint(GeoPoint gp) {
if (frame.getExportPointSymbol()) {
startBeamer(codePoint);
double x = gp.getX();
double y = gp.getY();
double z = gp.getZ();
x = x / z;
y = y / z;
codePoint.append("\\psdots");
PointOptionCode(gp);
codePoint.append("(");
codePoint.append(format(x));
codePoint.append(",");
codePoint.append(format(y));
codePoint.append(")\n");
endBeamer(codePoint);
}
// In case of trimmed intersection
if (gp.getShowTrimmedIntersectionLines()) {
AlgoElement algo = gp.getParentAlgorithm();
if (algo instanceof AlgoIntersectAbstract) {
GeoElement[] geos = algo.getInput();
double x1 = euclidianView.toScreenCoordXd(gp.getInhomX());
double y1 = euclidianView.toScreenCoordYd(gp.getInhomY());
double x2 = euclidianView.toScreenCoordXd(gp.getInhomX()) + 30;
double y2 = euclidianView.toScreenCoordYd(gp.getInhomY()) + 30;
x1 = euclidianView.toRealWorldCoordX(x1);
x2 = euclidianView.toRealWorldCoordX(x2);
y1 = euclidianView.toRealWorldCoordY(y1);
y2 = euclidianView.toRealWorldCoordY(y2);
double r1 = Math.abs(x2 - x1);
double r2 = Math.abs(y2 - y1);
StringBuilder s = new StringBuilder(
"\\psclip{\\psellipse[linestyle=none](");
s.append(format(x1));
s.append(",");
s.append(format(y1));
s.append(")(");
s.append(format(r1));
s.append(",");
s.append(format(r2));
s.append(")}\n");
String end = "\\endpsclip\n";
boolean fill1 = false;
boolean draw = !geos[0].isEuclidianVisible();
if (draw) {
fill1 = geos[0].isFillable()
&& geos[0].getAlphaValue() > 0.0f;
if (fill1) {
codeFilledObject.append(s);
} else {
code.append(s);
}
drawGeoElement(geos[0], false, true);
}
if (geos.length > 1 && !geos[1].isEuclidianVisible()) {
boolean fill2 = geos[1].isFillable()
&& (geos[1].getAlphaValue() > 0.0f);
if (draw) {
if (fill1 == fill2) {
drawGeoElement(geos[1], false, true);
if (fill1) {
codeFilledObject.append(end);
} else {
code.append(end);
}
} else {
if (fill1) {
codeFilledObject.append(end);
} else {
code.append(end);
}
if (fill2) {
codeFilledObject.append(s);
} else {
code.append(s);
}
drawGeoElement(geos[1], false, true);
if (fill2) {
codeFilledObject.append(end);
} else {
code.append(end);
}
}
} else {
if (fill2) {
codeFilledObject.append(s);
} else {
code.append(s);
}
drawGeoElement(geos[1], false, true);
if (fill2) {
codeFilledObject.append(end);
} else {
code.append(end);
}
}
} else if (draw) {
if (fill1) {
codeFilledObject.append(end);
} else {
code.append(end);
}
}
}
}
}
@Override
protected void drawGeoLine(GeoLine geo) {
double x = geo.getX();
double y = geo.getY();
double z = geo.getZ();
startBeamer(code);
if (y != 0) {
code.append("\\psplot");
} else {
code.append("\\psline");
}
code.append(lineOptionCode(geo, true));
if (y != 0) {
code.append("{");
code.append(format(xmin));
code.append("}{");
code.append(format(xmax));
code.append("}{(-");
code.append(format(z));
code.append("-");
code.append(format(x));
code.append("*x)/");
String tmpy = format(y);
if (kernel.getAlgebraProcessor().evaluateToDouble(tmpy) != 0) {
code.append(tmpy);
} else {
code.append(y);
}
code.append("}\n");
} else {
String s = format(-z / x);
code.append("(");
code.append(s);
code.append(",");
code.append(format(ymin));
code.append(")(");
code.append(s);
code.append(",");
code.append(format(ymax));
code.append(")\n");
}
endBeamer(code);
}
@Override
protected void drawGeoSegment(GeoSegment geo) {
double[] A = new double[2];
double[] B = new double[2];
GeoPoint pointStart = geo.getStartPoint();
GeoPoint pointEnd = geo.getEndPoint();
pointStart.getInhomCoords(A);
pointEnd.getInhomCoords(B);
String x1 = format(A[0]);
String y1 = format(A[1]);
String x2 = format(B[0]);
String y2 = format(B[1]);
startBeamer(code);
code.append("\\psline");
code.append(lineOptionCode(geo, true));
code.append("(");
code.append(x1);
code.append(",");
code.append(y1);
code.append(")(");
code.append(x2);
code.append(",");
code.append(y2);
code.append(")\n");
int deco = geo.getDecorationType();
if (deco != GeoElement.DECORATION_NONE) {
mark(A, B, deco, geo);
}
endBeamer(code);
}
@Override
protected void drawLine(double x1, double y1, double x2, double y2,
GeoElement geo) {
String sx1 = format(x1);
String sy1 = format(y1);
String sx2 = format(x2);
String sy2 = format(y2);
if (isBeamer) {
code.append(" ");
}
code.append("\\psline");
code.append(lineOptionCode(geo, true));
code.append("(");
code.append(sx1);
code.append(",");
code.append(sy1);
code.append(")(");
code.append(sx2);
code.append(",");
code.append(sy2);
code.append(")\n");
}
@Override
protected void drawGeoRay(GeoRay geo) {
GeoPoint pointStart = geo.getStartPoint();
double x1 = pointStart.getX();
double z1 = pointStart.getZ();
x1 = x1 / z1;
String y1 = format(pointStart.getY() / z1);
double x = geo.getX();
double y = geo.getY();
double z = geo.getZ();
startBeamer(code);
if (y != 0) {
code.append("\\psplot");
} else {
code.append("\\psline");
}
code.append(lineOptionCode(geo, true));
double inf = xmin, sup = xmax;
if (y > 0) {
inf = x1;
} else {
sup = x1;
}
if (y != 0) {
code.append("{");
code.append(format(inf));
code.append("}{");
code.append(format(sup));
code.append("}{(-");
code.append(format(z));
code.append("-");
code.append(format(x));
code.append("*x)/");
String tmpy = format(y);
if (kernel.getAlgebraProcessor().evaluateToDouble(tmpy) != 0) {
code.append(tmpy);
} else {
code.append(y);
}
code.append("}\n");
} else {
if (-x > 0) {
sup = ymax;
} else {
sup = ymin;
}
code.append("(");
code.append(format(x1));
code.append(",");
code.append(y1);
code.append(")(");
code.append(format(x1));
code.append(",");
code.append(format(sup));
code.append(")\n");
}
endBeamer(code);
}
private void initUnitAndVariable() {
// Initaialze uits, dot style, dot size ....
codeBeginPic.append("\\psset{xunit=");
codeBeginPic.append(sci2dec(xunit));
codeBeginPic.append("cm,yunit=");
codeBeginPic.append(sci2dec(yunit));
codeBeginPic
.append("cm,algebraic=true,dimen=middle,dotstyle=o,dotsize=");
codeBeginPic.append(EuclidianStyleConstants.DEFAULT_POINT_SIZE);
codeBeginPic.append("pt 0");
codeBeginPic.append(",linewidth=");
codeBeginPic.append(format(
EuclidianStyleConstants.DEFAULT_LINE_THICKNESS / 2 * 0.8));
codeBeginPic.append("pt,arrowsize=3pt 2,arrowinset=0.25}\n");
}
// if label is Visible, draw it
@Override
protected void drawLabel(GeoElement geo, DrawableND drawGeo0) {
DrawableND drawGeo = drawGeo0;
try {
if (geo.isLabelVisible()) {
String name = geo.getLabelDescription();
if (geo.getLabelMode() == GeoElement.LABEL_CAPTION) {
String nameSym = name;
for (int i = 0; i < name.length(); i++) {
char uCode = name.charAt(i);
if (UnicodeTeX.getMap().containsKey(uCode)) {
nameSym = nameSym.replaceAll("\\" + uCode, "\\$\\\\"
+ UnicodeTeX.getMap().get(uCode) + "\\$");
}
}
nameSym = nameSym.replace("$\\euro$", "\\euro");
name = nameSym;
if (!eurosym && name.contains("\\euro")) {
codePreamble.append("\\usepackage{eurosym}\n");
}
if (name.contains("_")) {
name = "$" + name + "$";
}
} else {
name = "$" + StringUtil.toLaTeXString(
geo.getLabelDescription(), true) + "$";
}
if (name.indexOf(Unicode.DEGREE) != -1) {
name = name.replaceAll(Unicode.DEGREE,
"\\\\textrm{\\\\degre}");
if (codePreamble.indexOf("\\degre") == -1) {
codePreamble.append(
"\\newcommand{\\degre}{\\ensuremath{^\\circ}}\n");
}
}
if (null == drawGeo) {
drawGeo = euclidianView.getDrawableFor(geo);
}
double xLabel = drawGeo.getxLabel();
double yLabel = drawGeo.getyLabel();
xLabel = euclidianView.toRealWorldCoordX(Math.round(xLabel));
yLabel = euclidianView.toRealWorldCoordY(Math.round(yLabel));
GColor geocolor = geo.getObjectColor();
startBeamer(codePoint);
codePoint.append("\\rput[bl](");
codePoint.append(format(xLabel));
codePoint.append(",");
codePoint.append(format(yLabel));
codePoint.append("){");
if (!geocolor.equals(GColor.BLACK)) {
codePoint.append("\\");
colorCode(geocolor, codePoint);
codePoint.append("{");
}
codePoint.append(name);
if (!geocolor.equals(GColor.BLACK)) {
codePoint.append("}");
}
codePoint.append("}\n");
endBeamer(codePoint);
}
}
catch (NullPointerException e) {
// For GeoElement that don't have a Label
// For example (created with geoList)
}
}
private void drawGrid() {
GColor GridCol = euclidianView.getGridColor();
double[] GridDist = euclidianView.getGridDistances();
double myx = xmin;
long truncx = (long) myx;
double myy = ymin;
long truncy = (long) myy;
double RX = Math.abs(xmax - xmin) / GridDist[0] + 1;
long repx = (long) RX;
double RY = Math.abs(ymax - ymin) / GridDist[1] + 1;
long repy = (long) RY;
// My Grid eje y\multips(0,ymin)(0,griddisy){numero de
// repeticiones}{\psline(xmin,0)(xmax,0)}
codeBeginPic.append("\\multips(0,");
codeBeginPic.append(truncy);
codeBeginPic.append(")(0,");
codeBeginPic.append(sci2dec(GridDist[1]));
codeBeginPic.append("){");
codeBeginPic.append(repy);
codeBeginPic.append(
"}{\\psline[linestyle=dashed,linecap=1,dash=1.5pt 1.5pt,linewidth=0.4pt,linecolor=");
colorCode(GridCol, codeBeginPic);
codeBeginPic.append("]{c-c}(");
codeBeginPic.append(format(xmin));
codeBeginPic.append(",0)(");
codeBeginPic.append(format(xmax));
codeBeginPic.append(",0)}\n");
// My Grid eje
// x\multips(xmin,0)(griddisx,0){num}{\psline(0,ymin)(0,ymax)}
codeBeginPic.append("\\multips(");
codeBeginPic.append(truncx);
codeBeginPic.append(",0)(");
codeBeginPic.append(sci2dec(GridDist[0]));
codeBeginPic.append(",0){");
codeBeginPic.append(repx);
codeBeginPic.append(
"}{\\psline[linestyle=dashed,linecap=1,dash=1.5pt 1.5pt,linewidth=0.4pt,linecolor=");
colorCode(GridCol, codeBeginPic);
codeBeginPic.append("]{c-c}(0,");
codeBeginPic.append(format(ymin));
codeBeginPic.append(")(0,");
codeBeginPic.append(format(ymax));
codeBeginPic.append(")}\n");
}
// Draw the grid
/*
* private void drawGrid() { geogebra.common.awt.GColor GridCol =
* euclidianView.getGridColor(); double[] GridDist =
* euclidianView.getGridDistances(); // int
* GridLine=euclidianView.getGridLineStyle();
*
* // Set Units for grid codeBeginPic.append("\\psset{xunit="); //
* Application.debug(GridDist[0]*xunit);
* codeBeginPic.append(sci2dec(GridDist[0] * xunit));
* codeBeginPic.append("cm,yunit="); codeBeginPic.append(sci2dec(GridDist[1]
* * yunit)); codeBeginPic.append("cm}\n");
*
* // environment pspicture codeBeginPic.append("\\begin{pspicture*}(");
* codeBeginPic.append(format(xmin / GridDist[0]));
* codeBeginPic.append(","); codeBeginPic.append(format(ymin /
* GridDist[1])); codeBeginPic.append(")("); codeBeginPic.append(format(xmax
* / GridDist[0])); codeBeginPic.append(",");
* codeBeginPic.append(format(ymax / GridDist[1]));
* codeBeginPic.append(")\n");
*
* // Draw Grid
* codeBeginPic.append("\\psgrid[subgriddiv=0,gridlabels=0,gridcolor=");
* ColorCode(GridCol, codeBeginPic); codeBeginPic.append("](0,0)(");
* codeBeginPic.append(format(xmin / GridDist[0]));
* codeBeginPic.append(","); codeBeginPic.append(format(ymin /
* GridDist[1])); codeBeginPic.append(")("); codeBeginPic.append(format(xmax
* / GridDist[0])); codeBeginPic.append(",");
* codeBeginPic.append(format(ymax / GridDist[1]));
* codeBeginPic.append(")\n");
*
* // Set units for the pspicture initUnitAndVariable(); /*
* code.append("\\psset{xunit="); code.append(xunit);
* code.append("cm,yunit="); code.append(yunit); code.append("cm}\n");
*/
// }
// Draw Axis
private void drawAxis() {
boolean[] positiveOnly = euclidianView.getPositiveAxes();
boolean xAxis = euclidianView.getShowXaxis();
boolean yAxis = euclidianView.getShowYaxis();
// \psaxes[Dx=5,Dy=0.5]{->}(0,0)(-10.5,-0.4)(10.5,1.2)
double Dx = euclidianView.getAxesNumberingDistances()[0];
double Dy = euclidianView.getAxesNumberingDistances()[1];
String[] label = euclidianView.getAxesLabels(false);
String styleAx = "";
if ((euclidianView.getAxesLineStyle()
& EuclidianStyleConstants.AXES_BOLD) == EuclidianStyleConstants.AXES_BOLD) {
styleAx = "linewidth=1.4pt,";
}
codeBeginPic.append(
"\\psaxes[" + styleAx + "labelFontSize=\\scriptstyle,xAxis=");
codeBeginPic.append(xAxis);
codeBeginPic.append(",yAxis=");
codeBeginPic.append(yAxis);
codeBeginPic.append(',');
boolean bx = euclidianView.getShowAxesNumbers()[0];
boolean by = euclidianView.getShowAxesNumbers()[1];
if (!bx && !by) {
codeBeginPic.append("labels=none,");
} else if (bx && !by) {
codeBeginPic.append("labels=x,");
} else if (!bx && by) {
codeBeginPic.append("labels=y,");
}
codeBeginPic.append("Dx=");
codeBeginPic.append(format(Dx));
codeBeginPic.append(",Dy=");
codeBeginPic.append(format(Dy));
codeBeginPic.append(",ticksize=-2pt 0,subticks=2]{");
styleAx = "";
if ((euclidianView.getAxesLineStyle()
& EuclidianStyleConstants.AXES_RIGHT_ARROW) == EuclidianStyleConstants.AXES_RIGHT_ARROW) {
styleAx = "->";
}
if ((euclidianView.getAxesLineStyle()
& EuclidianStyleConstants.AXES_LEFT_ARROW) == EuclidianStyleConstants.AXES_LEFT_ARROW) {
styleAx = "<" + styleAx;
}
codeBeginPic.append(styleAx);
codeBeginPic.append("}(0,0)(");
double assignMin = xmin;
if (positiveOnly[0]) {
assignMin = 0;
}
codeBeginPic.append(format(assignMin));
codeBeginPic.append(",");
assignMin = ymin;
if (positiveOnly[0]) {
assignMin = 0;
}
codeBeginPic.append(format(assignMin));
codeBeginPic.append(")(");
codeBeginPic.append(format(xmax));
codeBeginPic.append(",");
codeBeginPic.append(format(ymax));
codeBeginPic.append(")");
if (null != label[0] || null != label[1]) {
codeBeginPic.append("[");
if (null != label[0]) {
codeBeginPic.append(label[0]);
}
codeBeginPic.append(",140] [");
if (null != label[1]) {
codeBeginPic.append(label[1]);
}
codeBeginPic.append(",-40]");
}
codeBeginPic.append("\n");
}
private void PointOptionCode(GeoPoint geo) {
GColor dotcolor = geo.getObjectColor();
int dotsize = geo.getPointSize();
int dotstyle = geo.getPointStyle();
if (dotstyle == -1) { // default
dotstyle = EuclidianStyleConstants.POINT_STYLE_DOT;
}
boolean coma = false;
boolean bracket = false;
if (dotsize != EuclidianStyleConstants.DEFAULT_POINT_SIZE) {
// coma needed
coma = true;
// bracket needed
bracket = true;
codePoint.append("[dotsize=");
codePoint.append(dotsize);
codePoint.append("pt 0");
}
if (dotstyle != EuclidianStyleConstants.POINT_STYLE_CIRCLE) {
if (coma) {
codePoint.append(",");
}
if (!bracket) {
codePoint.append("[");
}
coma = true;
bracket = true;
codePoint.append("dotstyle=");
switch (dotstyle) {
case EuclidianStyleConstants.POINT_STYLE_CROSS:
codePoint.append("x");
break;
case EuclidianStyleConstants.POINT_STYLE_DOT:
codePoint.append("*");
break;
case EuclidianStyleConstants.POINT_STYLE_EMPTY_DIAMOND:
codePoint.append("square,dotangle=45");
break;
case EuclidianStyleConstants.POINT_STYLE_FILLED_DIAMOND:
codePoint.append("square*,dotangle=45");
break;
case EuclidianStyleConstants.POINT_STYLE_PLUS:
codePoint.append("+");
break;
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_EAST:
codePoint.append("triangle*,dotangle=270");
break;
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_NORTH:
codePoint.append("triangle*");
break;
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_SOUTH:
codePoint.append("triangle*,dotangle=180");
break;
case EuclidianStyleConstants.POINT_STYLE_TRIANGLE_WEST:
codePoint.append("triangle*,dotangle=90");
break;
default:
codePoint.append("*");
break;
}
}
if (!dotcolor.equals(GColor.BLACK)) {
if (coma) {
codePoint.append(",");
}
if (!bracket) {
codePoint.append("[");
}
bracket = true;
codePoint.append("linecolor=");
colorCode(dotcolor, codePoint);
}
if (bracket) {
codePoint.append("]");
}
}
/**
* @param geo
* element
* @param transparency
* whether to use transparency
* @return line style code
*/
public String lineOptionCode(GeoElement geo, boolean transparency) {
StringBuilder sb = new StringBuilder();
int linethickness = geo.getLineThickness();
int linestyle = geo.getLineType();
Info info = new Info(geo);
boolean coma = false;
boolean bracket = false;
if (linethickness != EuclidianStyleConstants.DEFAULT_LINE_THICKNESS) {
// coma needed
coma = true;
// bracket needed
bracket = true;
sb.append("[linewidth=");
sb.append(format(linethickness / 2.0 * 0.8));
sb.append("pt");
}
if (linestyle != EuclidianStyleConstants.DEFAULT_LINE_TYPE) {
if (coma) {
sb.append(",");
} else {
coma = true;
}
if (!bracket) {
sb.append("[");
}
bracket = true;
LinestyleCode(linestyle, sb);
}
if (!info.getLinecolor().equals(GColor.BLACK)) {
if (coma) {
sb.append(",");
} else {
coma = true;
}
if (!bracket) {
sb.append("[");
}
bracket = true;
sb.append("linecolor=");
colorCode(info.getLinecolor(), sb);
}
// System.out.println(geo.isFillable()+" "+transparency+"
// "+geo.getObjectType());
if (geo.isFillable() && transparency) {
switch (info.getFillType()) {
default:
case STANDARD:
if (info.getAlpha() > 0.0f) {
if (coma) {
sb.append(",");
} else {
coma = true;
}
if (!bracket) {
sb.append("[");
}
bracket = true;
sb.append("fillcolor=");
colorCode(info.getLinecolor(), sb);
sb.append(",fillstyle=solid,opacity=");
sb.append(info.getAlpha());
}
break;
case SYMBOLS:
case CHESSBOARD:
case HONEYCOMB:
case BRICK:
case WEAVING:
case DOTTED:
bracket = appendHatch(sb, info, ",fillstyle=dots*,hatchangle=",
bracket, coma);
break;
case CROSSHATCHED:
bracket = appendHatch(sb, info,
",fillstyle=crosshatch,hatchangle=", bracket, coma);
break;
case HATCH:
bracket = appendHatch(sb, info, ",fillstyle=hlines,hatchangle=",
bracket, coma);
break;
}
}
if (bracket) {
sb.append("]");
}
return new String(sb);
}
private boolean appendHatch(StringBuilder sb, Info info, String style,
boolean bracket, boolean coma) {
if (coma) {
sb.append(",");
}
if (!bracket) {
sb.append("[");
}
sb.append("hatchcolor=");
colorCode(info.getLinecolor(), sb);
sb.append(style);
sb.append(info.getAngle());
sb.append(",hatchsep=");
// double x0=euclidianView.toRealWorldCoordX(0);
double y0 = euclidianView.toRealWorldCoordY(0);
double y = euclidianView.toRealWorldCoordY(info.getY());
sb.append(format(Math.abs((y - y0))));
return true;
}
// Append the linestyle to PSTricks code
private void LinestyleCode(int linestyle, StringBuilder sb) {
switch (linestyle) {
default:
// do nothing
break;
case EuclidianStyleConstants.LINE_TYPE_DOTTED:
sb.append("linestyle=dotted");
break;
case EuclidianStyleConstants.LINE_TYPE_DASHED_SHORT:
// sb.append("linestyle=dashed,dash=4pt 4pt");
sb.append("linestyle=dashed,dash=");
int size = resizePt(4);
sb.append(size);
sb.append("pt ");
sb.append(size);
sb.append("pt");
break;
case EuclidianStyleConstants.LINE_TYPE_DASHED_LONG:
// sb.append("linestyle=dashed,dash=8pt 8pt");
sb.append("linestyle=dashed,dash=");
size = resizePt(8);
sb.append(size);
sb.append("pt ");
sb.append(size);
sb.append("pt");
break;
case EuclidianStyleConstants.LINE_TYPE_DASHED_DOTTED:
// sb.append("linestyle=dashed,dash=1pt 4pt 8pt 4pt");
sb.append("linestyle=dashed,dash=");
int size1 = resizePt(1);
int size2 = resizePt(4);
int size3 = resizePt(8);
sb.append(size1);
sb.append("pt ");
sb.append(size2);
sb.append("pt ");
sb.append(size3);
sb.append("pt ");
sb.append(size2);
sb.append("pt ");
break;
}
}
// Append the name color to StringBuilder sb
@Override
protected void colorCode(GColor c, StringBuilder sb) {
if (frame.isGrayscale()) {
String colorname = "";
int red = c.getRed();
int green = c.getGreen();
int blue = c.getBlue();
int grayscale = (red + green + blue) / 3;
GColor gray = GColor.newColor(grayscale, grayscale, grayscale);
if (customColor.containsKey(c)) {
colorname = customColor.get(c).toString();
} else {
colorname = createCustomColor(grayscale, grayscale, grayscale);
codeBeginDoc.append("\\newrgbcolor{" + colorname + "}{"
+ format(grayscale / 255d) + " "
+ format(grayscale / 255d) + " "
+ format(grayscale / 255d) + "}\n");
customColor.put(gray, colorname);
}
if (gray.equals(GColor.BLACK)) {
sb.append("black");
} else if (gray.equals(GColor.DARK_GRAY)) {
sb.append("darkgray");
} else if (gray.equals(GColor.GRAY)) {
sb.append("gray");
} else if (gray.equals(GColor.LIGHT_GRAY)) {
sb.append("lightgray");
} else if (gray.equals(GColor.WHITE)) {
sb.append("white");
} else {
sb.append(colorname);
}
} else {
// final String
// suffix="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (c.equals(GColor.BLACK)) {
sb.append("black");
} else if (c.equals(GColor.DARK_GRAY)) {
sb.append("darkgray");
} else if (c.equals(GColor.GRAY)) {
sb.append("gray");
} else if (c.equals(GColor.LIGHT_GRAY)) {
sb.append("lightgray");
} else if (c.equals(GColor.WHITE)) {
sb.append("white");
} else if (c.equals(GColor.RED)) {
sb.append("red");
} else if (c.equals(GColor.GREEN)) {
sb.append("green");
} else if (c.equals(GColor.BLUE)) {
sb.append("blue");
} else if (c.equals(GColor.CYAN)) {
sb.append("cyan");
} else if (c.equals(GColor.MAGENTA)) {
sb.append("magenta");
} else if (c.equals(GColor.YELLOW)) {
sb.append("yellow");
} else {
String colorname = "";
if (customColor.containsKey(c)) {
colorname = customColor.get(c).toString();
} else {
int red = c.getRed();
int green = c.getGreen();
int blue = c.getBlue();
colorname = createCustomColor(red, green, blue);
codeBeginDoc.append("\\newrgbcolor{" + colorname + "}{"
+ format(red / 255d) + " " + format(green / 255d)
+ " " + format(blue / 255d) + "}\n");
customColor.put(c, colorname);
}
sb.append(colorname);
}
}
}
/*
* // Resize text // Keep the ratio between font size and picture height
* private String resizeFont(int fontSize){ int
* latexFont=frame.getFontSize(); double
* height_geogebra=euclidianView.getHeight()/30; double
* height_latex=frame.getLatexHeight(); double
* ratio=height_latex/height_geogebra; int
* theoric_size=(int)Math.round(ratio*fontSize); String st=null;
* switch(latexFont){ case 10: if (theoric_size<=5) st="\\tiny{"; else if
* (theoric_size<=7) st="\\scriptsize{"; else if (theoric_size<=8)
* st="\\footnotesize{"; else if (theoric_size<=9) st="\\small{"; else if
* (theoric_size<=10) ; else if (theoric_size<=12) st="\\large{"; else if
* (theoric_size<=14) st="\\Large{"; else if (theoric_size<=17)
* st="\\LARGE{"; else if (theoric_size<=20) st="\\huge{"; else
* st="\\Huge{"; break; case 11: if (theoric_size<=6) st="\\tiny{"; else if
* (theoric_size<=8) st="\\scriptsize{"; else if (theoric_size<=9)
* st="\\footnotesize{"; else if (theoric_size<=10) st="\\small{"; else if
* (theoric_size<=11) ; else if (theoric_size<=12) st="\\large{"; else if
* (theoric_size<=14) st="\\Large{"; else if (theoric_size<=17)
* st="\\LARGE{"; else if (theoric_size<=20) st="\\huge{"; else
* st="\\Huge{"; break; case 12: if (theoric_size<=6) st="\\tiny{"; else if
* (theoric_size<=8) st="\\scriptsize{"; else if (theoric_size<=10)
* st="\\footnotesize{"; else if (theoric_size<=11) st="\\small{"; else if
* (theoric_size<=12) ; else if (theoric_size<=14) st="\\large{"; else if
* (theoric_size<=17) st="\\Large{"; else if (theoric_size<=20)
* st="\\LARGE{"; else if (theoric_size<=25) st="\\huge{"; else
* st="\\Huge{"; break; } return st; }
*/
/*
* private void defineTransparency(){ String str=
* "\\makeatletter\n\\define@key[psset]{}{transpalpha}{\\pst@checknum{#1}\\pstranspalpha}\n"
* + "\\psset{transpalpha=1}\n"+ "\\def\\psfs@transp{%\n"+
* " \\addto@pscode{/Normal .setblendmode \\pstranspalpha .setshapealpha }%\n"
* + " \\psfs@solid}\n"; if (!transparency) codePreamble.append(str);
* transparency=true; }
*/
private void addText(String st0, boolean isLatex, int style,
GColor geocolor) {
String st = st0;
if (isLatex) {
st = st.replaceAll("\n", " ");
}
if (isLatex) {
if (!st.startsWith("$")) {
code.append("$");
}
String stSym = st;
for (int i = 0; i < st.length(); i++) {
char uCode = st.charAt(i);
if (UnicodeTeX.getMap().containsKey(uCode)) {
addTextPackage();
stSym = stSym.replaceAll("\\" + uCode,
"\\\\" + UnicodeTeX.getMap().get(uCode) + " ");
}
}
st = stSym;
}
// Replace all backslash symbol with \textbackslash
else {
st = st.replaceAll("\\\\", "\\\\textbackslash ");
String stSym = st;
for (int i = 0; i < st.length(); i++) {
char uCode = st.charAt(i);
if (UnicodeTeX.getMap().containsKey(uCode)) {
addTextPackage();
stSym = stSym.replaceAll("\\" + uCode, "\\$\\\\"
+ UnicodeTeX.getMap().get(uCode) + "\\$ ");
}
}
st = stSym;
if (!eurosym && st.contains("$\\euro$")) {
codePreamble.append("\\usepackage{eurosym}\n");
st = st.replace("$\\euro$", "\\euro");
}
}
switch (style) {
default:
// do nothing
break;
case 1:
if (isLatex) {
code.append("\\mathbf{");
} else {
code.append("\\textbf{");
}
break;
case 2:
if (isLatex) {
code.append("\\mathit{");
} else {
code.append("\\textit{");
}
break;
case 3:
if (isLatex) {
code.append("\\mathit{\\mathbf{");
} else {
code.append("\\textit{\\textbf{");
}
break;
}
if (!geocolor.equals(GColor.BLACK)) {
code.append("\\");
colorCode(geocolor, code);
code.append("{");
}
/*
* if (size!=app.getFontSize()) { String formatFont=resizeFont(size); if
* (null!=formatFont) code.append(formatFont); }
*/
code.append(st);
// if (size!=app.getFontSize()) code.append("}");
if (!geocolor.equals(GColor.BLACK)) {
code.append("}");
}
switch (style) {
default:
// do nothing
break;
case 1:
case 2:
code.append("}");
break;
case 3:
code.append("}}");
break;
}
if (isLatex && !st.endsWith("$")) {
code.append("$");
}
}
/**
* Export PSTricks code for implicit polynom (degree greater than 2)
*/
@Override
protected void drawImplicitPoly(GeoImplicit geo) {
if (codePreamble.indexOf("pst-func") == -1) {
codePreamble.append("\\usepackage{pst-func}\n");
}
code.append("\\psplotImp");
code.append(lineOptionCode(geo.toGeoElement(), true));
code.append("(");
code.append(Math.floor(xmin) - 1);
code.append(",");
code.append(Math.floor(ymin) - 1);
code.append(")(");
code.append(Math.floor(xmax) + 1);
code.append(",");
code.append(Math.floor(ymax) + 1);
code.append("){");
code.append(getImplicitExpr(geo));
code.append("}\n");
}
@Override
protected void drawPolyLine(GeoPolyLine geo) {
GeoPointND[] path = geo.getPoints();
if (path.length < 2) {
return;
}
startBeamer(code);
code.append("\\psline");
code.append(lineOptionCode(geo, true));
for (int i = 0; i < path.length; i++) {
Coords coords = path[i].getInhomCoords();
String x1 = format(coords.getX());
String y1 = format(coords.getY());
if (x1.contains("?") || y1.contains("?")) {
code.append("\n\\psline");
code.append(lineOptionCode(geo, true));
} else {
code.append("(");
code.append(x1);
code.append(",");
code.append(y1);
code.append(")");
}
}
code.append("\n");
endBeamer(code);
}
@Override
protected void drawHistogramOrBarChartBox(double[] y, double[] x,
int length, double width, GeoNumeric g) {
String command = g.getDefinition(StringTemplate.noLocalDefault);
startBeamer(codeFilledObject);
if (command.contains("Binomial") && command.contains("true")) {
codeFilledObject.append("\\psline");
codeFilledObject.append(lineOptionCode(g, true));
codeFilledObject.append("(");
codeFilledObject.append(format(x[0] + width / 2));
codeFilledObject.append(",0)(");
codeFilledObject.append(format(x[0] + width / 2));
codeFilledObject.append(",");
codeFilledObject.append(format(y[0]));
codeFilledObject.append(")\n");
for (int i = 0; i < length - 1; i++) {
codeFilledObject.append("\\psline");
codeFilledObject.append(lineOptionCode(g, true));
codeFilledObject.append("(");
codeFilledObject.append(format(x[i] + width / 2));
codeFilledObject.append("," + format(y[i]) + ")(");
codeFilledObject.append(format(x[i + 1] + width / 2));
codeFilledObject.append(",");
codeFilledObject.append(format(y[i]));
codeFilledObject.append(")\n");
if (i != x.length - 2 && isBeamer) {
codeFilledObject.append(" ");
}
codeFilledObject.append("\\psline");
codeFilledObject.append(lineOptionCode(g, true));
codeFilledObject.append("(");
codeFilledObject.append(format(x[i + 1] + width / 2));
codeFilledObject.append(",");
codeFilledObject.append(format(y[i]));
codeFilledObject.append(")");
codeFilledObject.append("(");
codeFilledObject.append(format(x[i + 1] + width / 2));
codeFilledObject.append(",");
codeFilledObject.append(format(y[i + 1]));
codeFilledObject.append(")\n");
}
} else {
for (int i = 0; i < length; i++) {
barNumber = i + 1;
codeFilledObject.append("\\psframe");
codeFilledObject.append(lineOptionCode(g, true));
codeFilledObject.append("(");
codeFilledObject.append(format(x[i]));
codeFilledObject.append(",0)(");
if (x.length == length) {
codeFilledObject.append(format(x[i] + width));
} else {
codeFilledObject.append(format(x[i + 1]));
}
codeFilledObject.append(",");
codeFilledObject.append(format(y[i]));
codeFilledObject.append(")\n");
if (i != x.length - 2 && isBeamer) {
codeFilledObject.append(" ");
}
}
}
endBeamer(codeFilledObject);
}
@Override
protected void drawNyquist(GeoTransferFunction g) {
startBeamer(code);
String liopco = lineOptionCode(g, true);
String template = "\\psline" + liopco + "" + Unicode.SECTION_SIGN
+ "arrows" + Unicode.SECTION_SIGN + "(%0,%1)(%2,%3)\n";
StringBuilder lineBuilder = drawNyquistDiagram(g, template, ""
+ Unicode.SECTION_SIGN + "arrows" + Unicode.SECTION_SIGN + "",
"{<-}", "{->}");
code.append(lineBuilder.toString());
endBeamer(code);
}
/**
* @param curves
* curves to fill
*/
@Override
protected boolean fillSpline(GeoCurveCartesian[] curves) {
String liopco = lineOptionCode(curves[0], true);
if (!liopco.contains("fill")) {
return false;
}
StringBuilder fill = new StringBuilder("\\pscustom");
fill.append(liopco);
fill.append("\n{\n");
code.append(fill);
for (int i = 0; i < curves.length; i++) {
drawSingleCurveCartesian(curves[i], false);
}
code.append("}\n");
return true;
}
/**
* @param s
* shape
* @param ineq
* inequality
* @param geo
* inequality function
* @param ds
* view bounds
*/
public void superFill(GShape s, Inequality ineq, FunctionalNVar geo,
double[] ds) {
((GeoElement) geo).setLineType(ineq.getBorder().lineType);
switch (ineq.getType()) {
default:
// do nothing
break;
case INEQUALITY_CONIC:
GeoConicND conic = ineq.getConicBorder();
if (conic.getType() == GeoConicNDConstants.CONIC_ELLIPSE
|| conic.getType() == GeoConicNDConstants.CONIC_CIRCLE) {
((GeoElement) conic)
.setObjColor(((GeoElement) geo).getObjectColor());
((GeoElement) conic)
.setAlphaValue(((GeoElement) geo).getAlphaValue());
conic.setType(GeoConicNDConstants.CONIC_ELLIPSE);
((GeoElement) conic).setHatchingAngle(
(int) ((GeoElement) geo).getHatchingAngle());
((GeoElement) conic).setHatchingDistance(
((GeoElement) geo).getHatchingDistance());
((GeoElement) conic)
.setFillType(((GeoElement) geo).getFillType());
drawGeoConic((GeoConic) conic);
break;
}
case INEQUALITY_PARAMETRIC_Y:
case INEQUALITY_PARAMETRIC_X:
case INEQUALITY_1VAR_X:
case INEQUALITY_1VAR_Y:
case INEQUALITY_LINEAR:
double[] coords = new double[2];
double zeroY = ds[5] * ds[3];
double zeroX = ds[4] * (-ds[0]);
GPathIterator path = s.getPathIterator(null);
code.append("\\pspolygon");
code.append(lineOptionCode((GeoElement) geo, true));
double precX = Integer.MAX_VALUE;
double precY = Integer.MAX_VALUE;
while (!path.isDone()) {
path.currentSegment(coords);
if (coords[0] == precX && coords[1] == precY) {
code.append("\\pspolygon");
code.append(lineOptionCode((GeoElement) geo, true));
} else {
code.append("(");
code.append(format((coords[0] - zeroX) / ds[4]));
code.append(",");
code.append(format(-(coords[1] - zeroY) / ds[5]));
code.append(")");
}
precX = coords[0];
precY = coords[1];
path.next();
}
int i = code.lastIndexOf(")");
code.delete(i + 1, code.length());
code.append("\n");
break;
}
}
}