//copy constructor public Intersection(Intersection copyIntersection) { this.intersects = copyIntersection.intersects; this.object3d = copyIntersection.object3d; this.leaving = copyIntersection.leaving; if (copyIntersection.enter != null) this.enter = new Scientrace.IntersectionPoint(copyIntersection.enter); if (copyIntersection.exit != null) this.exit = new Scientrace.IntersectionPoint(copyIntersection.exit); }
// Add IntersectionPoints for entering and leaving to the SortedList when they exist and the distance from the startingpoint is not yet set public void conditionalIPList(SortedList<double,IntersectionPoint> ips, Intersection anIntersection, Location startingPoint) { if (anIntersection.enter != null) { if (!ips.Keys.Contains(anIntersection.enter.loc.distanceTo(startingPoint))) ips.Add(anIntersection.enter.loc.distanceTo(startingPoint), anIntersection.enter); /*else Console.WriteLine("WARNING: location "+anIntersection.enter.ToString()+" is entered (at least) twice at "+this.tag);*/ } if (anIntersection.exit != null) { if (!ips.Keys.Contains(anIntersection.exit.loc.distanceTo(startingPoint))) ips.Add(anIntersection.exit.loc.distanceTo(startingPoint), anIntersection.exit); /*else Console.WriteLine("WARNING: location "+anIntersection.enter.ToString()+" is entered (at least) twice at "+this.tag);*/ } }
public virtual Intersection intersectsBefore(Trace trace, Intersection intrs) { if (!this.hasDummyBorder()) { // no dummyborder? Do "normal" procedure return this.intersects(trace); } if (this.dummyBefore(trace, intrs)) { //is dummy intersected before intrs? return this.intersects(trace); //parse this object } else { return new Intersection(false,this); //do not parse this object } }
public bool dummyBefore(Trace trace, Intersection previousintersection) { Intersection dummyintersect = this.dummyborder.intersects(trace); if (!dummyintersect.intersects) { //dummyborder is NOT intersected. //Console.WriteLine("dummy NOT @ "+this.tag+" trace:"+trace.traceid+"@"+trace.traceline.ToString()); return false; } //dummyborder *is* intersected. Is it before the previous intersection? if (!previousintersection.intersects) { //the previous intersection does not exist, so dummy is always first. //Console.WriteLine("dummy IS @ "+this.tag+" trace:"+trace.traceid+"@"+trace.traceline.ToString()); return true; } if (trace.traceline.startingpoint.distanceTo(previousintersection.enter.loc) < trace.traceline.startingpoint.distanceTo(dummyintersect.enter.loc)) { //Console.WriteLine("dummy AFTER @ "+this.tag+" trace:"+trace.traceid+"@"+trace.traceline.ToString()); return false; } else { //Console.WriteLine("dummy BEFORE @ "+this.tag+" trace:"+trace.traceid+"@"+trace.traceline.ToString()); return true; } }
public override Intersection intersects(Trace trace) { Intersection retIS = new Intersection(trace, this.intersectionPoints(trace), this); retIS.leaving = this.contains(trace.traceline.startingpoint); return retIS; }
public Intersection mergeToNewIntersectionWithinBorder(Intersection anotherIntersection, IBorder3d aBorder, Trace aTrace, Object3d intersectedObject3d) { //List<IntersectionPoint> allips = new List<IntersectionPoint>(new IntersectionPoint[]{this.enter, this.exit, anotherIntersection.enter, anotherIntersection.exit} ); List<IntersectionPoint> allips = new List<IntersectionPoint>(); allips.Add(this.enter); allips.Add(this.exit); allips.Add(anotherIntersection.enter); allips.Add(anotherIntersection.exit); List<IntersectionPoint> validips = new List<IntersectionPoint>(); foreach (IntersectionPoint ip in allips) if ((ip != null) && (aBorder.contains(ip.loc))) validips.Add(ip); return new Intersection(aTrace, validips.ToArray(), intersectedObject3d); }
public override Intersection intersects(Trace aTrace) { /* OK, this is how we are going to do this: * First (1), we find all intersectionpoints for all sub-borders and order them * as a function of the distance from the startingpoint of the trace. Then (2), we * take the average location in between two consecutive intersectionpoints. Let's * ask all SubVolumes if anybody has this average value in it's body (3). We will * repeat this procedure until we find an average value that is *NOT* included (4). The * very first intersectionpoint, and the last intersectionpoint before that latest * assessed average will be the two intersectionpoints construction the Intersection (5) * value to return. * A final remark must be made: when a trace is leaving from the current object and the * average location between the start of the trace and the first intersection is also * within the object, the first intersectionpoint is actually virtual and should be * removed. (6) */ // (1) // create an orderedlist with as keys the distances from the last intersection to this ip SortedList<double,IntersectionPoint> all_ips = new SortedList<double,IntersectionPoint>(); Scientrace.Location subTraceStart = aTrace.traceline.startingpoint; foreach (PlaneBorderEnclosedVolume aSubVolume in subVolumes) { Intersection tIntersection = aSubVolume.intersects(aTrace); if (tIntersection.intersects) { this.conditionalIPList(all_ips, tIntersection, subTraceStart); } } IntersectionPoint previous_ip = null; IntersectionPoint first_ip = null; IntersectionPoint last_ip = null; for (int iKey = 0; iKey < all_ips.Keys.Count; iKey++) { double currentKey = all_ips.Keys[iKey]; IntersectionPoint currentIP = all_ips[currentKey]; if (previous_ip == null) { // is this the last IP in the list? if (iKey != all_ips.Count-1) { // If both the area between the start of the trace and that between this and the next trace is contained, skip to the next (by continue) IntersectionPoint nextIP = all_ips[all_ips.Keys[iKey+1]]; if (this.contains(subTraceStart.avgWith(currentIP.loc)) && this.contains(currentIP.loc.avgWith(nextIP.loc))) { continue; } } // (6) if (this.contains(subTraceStart.avgWith(currentIP.loc)) && (iKey+1!=all_ips.Keys.Count)) { first_ip = currentIP; break; } else { // the first ip in the list, no average to take with previous value first_ip = currentIP; } } else { // (2) Scientrace.Location average_loc = currentIP.loc.avgWith(previous_ip.loc); // (3) if (!this.contains(average_loc)) { //Console.WriteLine("BREAKOUT!!!!"); last_ip = previous_ip; // (4) Break out of foreach loop, we've found the last point in this intersection (the previous one in the list) break; } } // last statement in foreach loop, defining the current IP als the previous for the next cycle. previous_ip = currentIP; } // there has to be at least ONE intersection to succeed... if (first_ip == null) { return Intersection.notIntersect(this); } /* below must be the most obscure line in this routine, sry about that. * it does this: if last_ip is still unassigned, assign previous_ip as long as it differs from first_ip... */ // last_ip = last_ip ?? (previous_ip != first_ip ? previous_ip : null); if (last_ip == null) last_ip = (previous_ip != first_ip ? previous_ip : null); // (5) Scientrace.IntersectionPoint[] real_ips = new Scientrace.IntersectionPoint[2]; real_ips[0] = first_ip; real_ips[1] = last_ip; Intersection retIntersect = new Intersection(aTrace, real_ips, this); return retIntersect; //end func. intersect }
public override string exportX3D(Scientrace.Object3dEnvironment env) { int steps = this.exportX3Dgridsteps; Scientrace.AbstractGridBorder cborder = this.cborder; // Scientrace.VectorTransform cbordertrf = cborder.getTransform(); //Generate a rotating grid! Scientrace.VectorTransform cbordertrf = cborder.getGridTransform(this.zaxis); //Console.WriteLine("CBTRFcp: "+cbordertrf.ToCompactString()); /* * stloc: starting location actually representing the center of the border, * from there in the orthonormal direction of this border the collision points with * the parabolic mirror will be found (from -radius to +radius in both transform-directions */ Scientrace.Location stloc = cborder.getOrthoStartCenterLoc();// - cborder.getOthoDirection(); Scientrace.IntersectionPoint[] iparr, iparre, iparrs; Scientrace.Intersection cintr, eintr, sintr; /* * eloc is the location "east" of the current node, sloc "south" for drawing a grid * of course are terms east and south symbolic */ Scientrace.Location eloc, sloc; Scientrace.Line cline, eline, sline; //double r = cborder.getRadius(); double r1 = cborder.getURadius(); double r2 = cborder.getVRadius(); Scientrace.Vector v1 = cbordertrf.u.tryToUnitVector().toVector(); Scientrace.Vector v2 = cbordertrf.v.tryToUnitVector().toVector();; string retstr = ""; Scientrace.X3DGridPoint concentrationpoint = new Scientrace.X3DGridPoint(env, this.getConcentrationPoint(), null, null); retstr = concentrationpoint.x3DSphere(env.radius / 1000, "1 0 1", 0.5); retstr += concentrationpoint.x3DLineTo(this.loc, "1 0 1 1"); for (double ix = 0.5; ix < steps; ix++) { for (double iy = 0.5; iy <= steps; iy++) { /* Drawing a grid of lines in direction "border.orthodirection" to ParabolicMirror, * at every intersection a gridpoint is located. "cline" are those ortho-dir lines */ cline = new Scientrace.Line(((stloc - (v1 * r1) - (v2 * r2)) + (v1 * (r1 * 2 * (ix / steps))) + (v2 * (r2 * 2 * (iy / steps)))).toLocation(), cborder.getOrthoDirection()); // cborder.directionlength.toUnitVector()); /* USE THE "checkborder = false" function below to always * show the grid-points, also outside borders * iparr is the IntersectionPoint at the Parabolic Mirror for the current ix/iy iteration */ iparr = this.realIntersections(cline, true); /* DEBUG INFO foreach (IntersectionPoint ip in iparr) { * if (ip!=null) { * Console.WriteLine("IP AT: "+ip.ToString()); * } else { * Console.WriteLine("NO IP FROM: "+((stloc-(v1*r)-(v2*r))+(v1*(r*2*(ix/steps)))+(v2*(r*2*(iy/steps)))) +" AND "+cborder.getOrthoDirection()); * } * }*/ eline = new Scientrace.Line(((stloc - (v1 * r1) - (v2 * r2)) + (v1 * (r1 * 2 * ((ix + 1) / steps))) + (v2 * (r2 * 2 * (iy / steps)))).toLocation(), cborder.getOrthoDirection()); // cborder.directionlength.toUnitVector()); iparre = this.realIntersections(eline, true); //defining "east" neighbour eintr = new Intersection(eline, iparre, this); if (eintr.intersects) { eloc = eintr.enter.loc; } else { eloc = null; } sline = new Scientrace.Line(((stloc - (v1 * r1) - (v2 * r2)) + (v1 * (r1 * 2 * ((ix) / steps))) + (v2 * (r2 * 2 * ((iy + 1) / steps)))).toLocation(), cborder.getOrthoDirection()); // cborder.directionlength.toUnitVector()); iparrs = this.realIntersections(sline, true); //defining "south" neighbour sintr = new Intersection(sline, iparrs, this); if (sintr.intersects) { sloc = sintr.enter.loc; } else { sloc = null; } /* "central" point * where does line "cline" with intersections "iparr" intersect this object? */ cintr = new Intersection(cline, iparr, this, true); if (cintr.intersects) //add existing gridpoints { if (this.x3dgridspheres) { retstr = retstr + new X3DGridPoint(env, cintr.enter.loc, eloc, sloc).exportX3D(); } else { retstr = retstr + new X3DGridPoint(env, cintr.enter.loc, eloc, sloc).exportX3DnosphereRGBA("0 0 1 1"); } } } } //Console.WriteLine("!!!"+retstr); return(retstr + cborder.exportX3D(env)); }