package ddddbb.math; import java.awt.Color; import java.util.List; import java.util.Vector; import ddddbb.comb.ACell; import ddddbb.comb.DLocation; import ddddbb.comb.DCell; import ddddbb.game.Compound; public abstract class D3Graphics { protected D2GraphicsIF g2; protected Color lColor = Color.WHITE; protected Color rColor = Color.WHITE; protected Color LCOLOR; protected Color RCOLOR; private double brightness; //between 0 and 1 private List<DLocation> lines = new Vector<DLocation>(); private Camera3d c3; public abstract boolean screenProj(Point3d p,Point2d pl, Point2d pr); public D3Graphics(D2GraphicsIF _g,Camera3d c,Color _LCOLOR,Color _RCOLOR) { g2 = _g; c3 = c; LCOLOR = _LCOLOR; RCOLOR = _RCOLOR; setBrightness(0.75); } public Color setBrightness(Color c) { return new Color( (int)Math.round(c.getRed()*brightness), (int)Math.round(c.getGreen()*brightness), (int)Math.round(c.getBlue()*brightness) ); } public void setBrightness(double _brightness) { brightness = _brightness; lColor = setBrightness(LCOLOR); rColor = setBrightness(RCOLOR); } public double getBrightness() { return brightness; } public void clear() { lines.clear(); } // public boolean proj(Point3d p, D2Tupel l, D2Tupel r) { // Point2d pl=new Point2d(),pr=new Point2d(); // if (!screenProj(p,pl,pr)) { return false; } // g2.proj(pl,l); // g2.proj(pr,r); // return true; // } public void drawString(String s, Point3d p) { Point2d l=new Point2d(),r=new Point2d(); screenProj(p,l,r); g2.setColor(lColor); g2.drawString(s,l); g2.setColor(rColor); g2.drawString(s,r); } public void drawEndString(String s, Point3d p, Point3d from) { Point2d l=new Point2d(),r=new Point2d(); screenProj(p,l,r); Point2d lfrom=new Point2d(), rfrom=new Point2d(); screenProj(from,lfrom,rfrom); double x = (l.x1+r.x1-lfrom.x1-rfrom.x1)/2; double y = (l.x2+r.x2-lfrom.x2-rfrom.x2)/2; if (y>0 && y>Math.abs(x)) { g2.setColor(lColor); g2.drawStringNorth(s,l); g2.setColor(rColor); g2.drawStringNorth(s,r); } if (y<0 && -y>Math.abs(x)) { g2.setColor(lColor); g2.drawStringSouth(s,l); g2.setColor(rColor); g2.drawStringSouth(s,r); } if (x>0 && x>Math.abs(y)) { g2.setColor(lColor); g2.drawStringEast(s,l); g2.setColor(rColor); g2.drawStringEast(s,r); } if (x<0 && -x>Math.abs(y)) { g2.setColor(lColor); g2.drawStringWest(s,l); g2.setColor(rColor); g2.drawStringWest(s,r); } } public boolean screenProj(Point3d _p, double e, double s, Point2d pl, Point2d pr) { Point3d p = _p.clone(); p.subtract(c3.eye); double x = c3.v[0].sc(p); double y = c3.v[1].sc(p); double z = c3.v[2].sc(p); // pl.x1 = (x*s-z*e)/(z+s); //-e // pl.x2 = y * s/(z+s);//0 // pr.x1 = (x*s+z*e)/(z+s); //+e // pr.x2 = pl.x2; // return z+s > 0; pl.x1 = (x*s-(z-s)*e)/z; //-e pl.x2 = y * s/z;//0 pr.x1 = (x*s+(z-s)*e)/z; //+e pr.x2 = pl.x2; return z > 0; } public void drawLine(Point3d a,Point3d b) { Point2d pal=new Point2d(),par=new Point2d(),pbl=new Point2d(),pbr=new Point2d(); if ( screenProj(a,pal,par) && screenProj(b,pbl,pbr) ) { g2.setColor(lColor); g2.drawLine(pal,pbl); g2.setColor(rColor); g2.drawLine(par,pbr); } } public static final double dx=0.2; public static final double dd=0.05; public static final Point3d[] xArrowTip = { new Point3d(-dx,dd,dd), new Point3d(-dx,-dd,dd), new Point3d(-dx,-dd,-dd), new Point3d(-dx,dd,-dd) }; public void drawArrow(Point3d src, Point3d dst) { drawLine(src,dst); Point3d[] arrowTip = new Point3d[xArrowTip.length]; Point3d dir = dst.clone(); dir.subtract(src).normalize(); for (int i=0;i<xArrowTip.length;i++) { arrowTip[i] = xArrowTip[i].clone(); arrowTip[i].rotate(AOP.D100,dir); arrowTip[i].add(dst); drawLine(arrowTip[i],dst); } drawLine(arrowTip[0],arrowTip[1]); drawLine(arrowTip[1],arrowTip[2]); drawLine(arrowTip[2],arrowTip[3]); drawLine(arrowTip[3],arrowTip[0]); } public void drawArrow(Point3d src, Point3d dst, String label) { drawArrow(src,dst); drawEndString(label, dst, src); } public void drawBlob(Point3d dot3d) { Point2d dot2l = new Point2d(); Point2d dot2r = new Point2d(); if ( screenProj(dot3d,dot2l,dot2r) ) { g2.setColor(lColor); g2.drawBlob(dot2l); g2.setColor(rColor); g2.drawBlob(dot2r); } // for (int i=0;i<4;i++) { // double[] a = new double[4], b= new double[4]; // for (int ix=0;ix<3;ix++) { // a[ix]=dot[ix]; // b[ix]=a[ix]; // if (ix==i) { // a[ix]-=blobRadius; // b[ix]+=blobRadius; // } // } // drawLine(new Point3d(a),new Point3d(b)); // } } public void drawPoint(Point3d dot3d) { double blobRadius = 0.1; for (int i=0;i<4;i++) { double[] a = new double[3], b= new double[3]; for (int ix=0;ix<3;ix++) { a[ix]=dot3d.x[ix]; b[ix]=a[ix]; if (ix==i) { a[ix]-=blobRadius; b[ix]+=blobRadius; } } drawLine((Point3d) Point.wrap(a),(Point3d) Point.wrap(b)); } } public void drawLine(ACell a,ACell b) { if ( a.location().p2AheadEye && b.location().p2AheadEye ) { g2.setColor(lColor); g2.drawLine(a.location().p2l,b.location().p2l); g2.setColor(rColor); g2.drawLine(a.location().p2r,b.location().p2r); } } public void draw1dFacet(DCell line) { if (lines.contains(line.location)) { return; } drawLine(line.facets[0][0],line.facets[1][0]); if (!lines.contains(line.location)) { lines.add(line.location); } } /** draws a 3 dimensional facet */ public void render3dFacet(DCell f3) { draw3dFacet(f3); } // public void intersect(Facet line,OFacet f3,Camera4d c) { // Point3d[] v = new Point3d[3]; // Point3d l0 = new Point3d(); // c.proj(line.faces[0].origin,l0); // Point3d l1 = new Point3d(); // c.proj(line.faces[1].origin,l1); // v[0] = new Point3d(l0); v[0].translate(l1,-1); // Point3d[] cut = new Point3d[2]; // int cuti=0; // for (int s=0;s<2;s++) for (int a=0;a<3;a++) { // OFacet f2 = f3.faces[s][a]; // Point f2o = f2.origin(c); // List spat = f2.spat(c); // v[1] = new Point3d(((Point)spat.get(0)).x); // v[2] = new Point3d(((Point)spat.get(1)).x); // Matrix m = new Matrix(3,3); // for (int i=0;i<3;i++) for (int j=0;j<3;j++) { // m.set(j,i,v[i].x[j]); // } // Matrix b = new Matrix(3,1); // for (int i=0;i<3;i++) { // m.set(i,0,l0.minus(f2o).x[i]); // } // if (Math.abs(m.det())>Main.opt.ERR) { // Matrix r = m.solve(b); // Point3d is = new Point3d(l0); // is.translate(v[0],r.get(0,0)); // Point3d f2or = new Point3d(f2o); // f2or.translate(v[1],r.get(1,0)); // f2or.translate(v[2],r.get(2,0)); // Point3d l0r = new Point3d(l0); // l0r.translate(v[0],-r.get(0,0)); // if(!f2or.equals(l0r)) { // System.out.println("wrong computation"); // } // System.out.println(r.get(0,0)); // m.print(2,3); // boolean inF2 = true; // for (int s2=0;s2<2;s2++) for (int a2=0;a2<2;a2++) { // Point d = f2.faces[s2][a2].orth(c).get(0); // Point o = f2.faces[s2][a2].origin(c); // if (is.minus(o).sc(d)< -Main.opt.ERR) { inF2 = false; break; } // } // // boolean inLine = Main.opt.ERR < r.get(0,0) && r.get(0,0) < 1-Main.opt.ERR; // if (inLine) { // System.out.println("inline"); // } // if (inF2 && inLine) { // cut[cuti] = is; // System.out.println(is.x[0]+" "+is.x[1]+" "+is.x[2]+" "+line+" "+f2); // cuti++; // } // } // } // if (cuti==1) { // //dont know what to do yet // } // if (cuti>=2) {System.out.println(cuti);} // } public void draw3dFacet(DCell f3) { for (DCell f:f3.getFaces(1,false)) { if (f.isInternal()) { continue; } draw1dFacet(f); // drawLine(new PE3d1d(f)); } } public void renderCompound(Compound c) { // all visible facets of a compound (non-grid,non-transparent) // dont intersect each other // DCell[] facets4d = c.getTopLevelFacets(); for (int i=0;i<facets4d.length;i++) { DCell facet4d = facets4d[i]; for (int s=0;s<2;s++) for (int a=0;a<4;a++) { DCell face3d = facet4d.facets[s][i]; if (!face3d.isInternal()) { draw3dFacet(face3d); } } } } public void drawTrihedral(Point3d o,double s) { Point3d o1,o2,o3; o1 = new Point3d(s,0,0); o1.add(o); o2 = new Point3d(0,s,0); o2.add(o); o3 = new Point3d(0,0,s); o3.add(o); drawArrow(o,o1,"x"); drawArrow(o,o2,"y"); drawArrow(o,o3,"z"); } public void drawTrihedral(double s) { drawTrihedral(new Point3d(0,0,0),s); } public void drawTrihedral() { drawTrihedral(1); } public D2GraphicsIF getGraphics() { return g2; } public void setGraphics(D2GraphicsIF _g2) { g2 = _g2; } }