package org.geogebra.common.geogebra3D.euclidian3D.draw;
import org.geogebra.common.euclidian.draw.DrawConicSection;
import org.geogebra.common.geogebra3D.euclidian3D.EuclidianView3D;
import org.geogebra.common.geogebra3D.euclidian3D.openGL.PlotterBrush;
import org.geogebra.common.geogebra3D.euclidian3D.openGL.PlotterSurface;
import org.geogebra.common.geogebra3D.kernel3D.geos.GeoConicSection;
import org.geogebra.common.kernel.Matrix.Coords;
public class DrawConicSection3D extends DrawConic3D {
public DrawConicSection3D(EuclidianView3D view3d, GeoConicSection conic) {
super(view3d, conic);
}
protected double getStart(int i) {
return ((GeoConicSection) getGeoElement()).getParameterStart(i);
}
protected double getExtent(int i) {
return ((GeoConicSection) getGeoElement()).getParameterExtent(i);
}
protected double getEnd(int i) {
return ((GeoConicSection) getGeoElement()).getParameterEnd(i);
}
@Override
protected void updateCircle(PlotterBrush brush) {
updateEllipse(brush);
}
@Override
protected boolean updateForItSelf() {
if (points[0] == null) {
for (int i = 0; i < 4; i++) {
points[i] = new Coords(4);
}
}
return super.updateForItSelf();
}
@Override
protected void updateEllipse(PlotterBrush brush) {
double start0 = getStart(0);
double extent0 = getExtent(0);
double start1 = getStart(1);
double extent1 = getExtent(1);
if (!Double.isNaN(start0)) { // there is at least one hole
brush.arcEllipse(m, ev1, ev2, e1, e2, start0, extent0);
if (!Double.isNaN(start1)) { // there is two holes
brush.setAffineTexture(0.5f, 0.25f);
brush.segment(
DrawConicSection.ellipsePoint(m, ev1, ev2, e1, e2,
start0 + extent0),
DrawConicSection.ellipsePoint(m, ev1, ev2, e1, e2,
start1));
brush.arcEllipse(m, ev1, ev2, e1, e2, start1, extent1);
brush.setAffineTexture(0.5f, 0.25f);
brush.segment(
DrawConicSection.ellipsePoint(m, ev1, ev2, e1, e2,
start1 + extent1),
DrawConicSection.ellipsePoint(m, ev1, ev2, e1, e2,
start0));
} else {
brush.setAffineTexture(0.5f, 0.25f);
brush.segment(
DrawConicSection.ellipsePoint(m, ev1, ev2, e1, e2,
start0 + extent0),
DrawConicSection.ellipsePoint(m, ev1, ev2, e1, e2,
start0));
}
} else { // no hole
super.updateEllipse(brush);
}
// updateSectorSegments(brush, conic.getConicPartType(), m, ev0, ev1,
// r0, r1, start0, start0+extent0);
}
@Override
protected void updateEllipse(PlotterSurface surface) {
double start0 = getStart(0);
double extent0 = getExtent(0);
double start1 = getStart(1);
double extent1 = getExtent(1);
if (!Double.isNaN(start0)) { // there is at least one hole
surface.ellipsePart(m, ev1, ev2, e1, e2, start0, extent0, false);
if (!Double.isNaN(start1)) { // there is two holes
surface.ellipsePart(m, ev1, ev2, e1, e2, start1, extent1,
false);
surface.drawQuad(
DrawConicSection.ellipsePoint(m, ev1, ev2, e1, e2,
start0),
DrawConicSection.ellipsePoint(m, ev1, ev2, e1, e2,
start0 + extent0),
DrawConicSection.ellipsePoint(m, ev1, ev2, e1, e2,
start1),
DrawConicSection.ellipsePoint(m, ev1, ev2, e1, e2,
start1 + extent1));
}
} else { // no hole
super.updateEllipse(surface);
}
}
@Override
protected double[] getLineMinMax(int i) {
return new double[] { getStart(i), getEnd(i) };
}
@Override
protected void updateLines(PlotterBrush brush) {
super.updateLines(brush);
brush.segment(points[1], points[2]);
brush.segment(points[3], points[0]);
}
@Override
protected void updateHyperbola(PlotterBrush brush) {
// first branch
double start = getStart(0);
if (!Double.isNaN(start)) {
double end = getEnd(0);
brush.hyperbolaBranch(m, ev1, ev2, e1, e2, start, end);
brush.setAffineTexture(0.5f, 0.25f);
brush.segment(
m.add(ev1.mul(e1 * Math.cosh(start)))
.add(ev2.mul(e2 * Math.sinh(start))),
m.add(ev1.mul(e1 * Math.cosh(end)))
.add(ev2.mul(e2 * Math.sinh(end))));
}
// second branch
start = getStart(1);
if (!Double.isNaN(start)) {
double end = getEnd(1);
brush.hyperbolaBranch(m, ev1.mul(-1), ev2, e1, e2, start, end);
brush.setAffineTexture(0.5f, 0.25f);
brush.segment(
m.add(ev1.mul(-e1 * Math.cosh(start)))
.add(ev2.mul(e2 * Math.sinh(start))),
m.add(ev1.mul(-e1 * Math.cosh(end)))
.add(ev2.mul(e2 * Math.sinh(end))));
}
}
@Override
protected void updateHyperbola(PlotterSurface surface) {
// first branch
double start = getStart(0);
if (!Double.isNaN(start)) {
surface.hyperbolaPart(m, ev1, ev2, e1, e2, start, getEnd(0));
}
// second branch
start = getStart(1);
if (!Double.isNaN(start)) {
surface.hyperbolaPart(m, ev1.mul(-1), ev2, e1, e2, start,
getEnd(1));
}
}
@Override
protected void updateIntersectingLines(PlotterSurface surface) {
surface.drawTriangle(points[0], points[1], points[3]);
}
@Override
protected double[] getParabolaMinMax() {
return new double[] { getStart(0), getEnd(0) };
}
@Override
protected void updateParabola(PlotterBrush brush) {
super.updateParabola(brush);
brush.setAffineTexture(0.5f, 0.25f);
brush.segment(points[0], points[1]);
}
}