// Copy constructor public IntersectionPoint(IntersectionPoint copyIntersectionPoint) { this.loc = (copyIntersectionPoint.loc == null) ? null : new Location(copyIntersectionPoint.loc); this.flatshape = copyIntersectionPoint.flatshape; /* this.flatshape = (copyIntersectionPoint.flatshape == null) ? null : new FlatShape2d(copyIntersectionPoint.flatshape); */ }
// Copy constructor public IntersectionPoint(IntersectionPoint copyIntersectionPoint) { this.loc = (copyIntersectionPoint.loc == null) ? null : new Location(copyIntersectionPoint.loc); this.flatshape = copyIntersectionPoint.flatshape; /* this.flatshape = * (copyIntersectionPoint.flatshape == null) ? * null : new FlatShape2d(copyIntersectionPoint.flatshape); */ }
public IntersectionPoint[] intersects11circleborder(Trace trace) { Scientrace.Line line = trace.traceline; double d1, d2, dx, dy, lx, ly; double ABCa, ABCb, ABCc, discr; Scientrace.Vector v1, v2; Scientrace.FlatShape2d plane1, plane2; Scientrace.IntersectionPoint[] ip; dx = line.direction.x; dy = line.direction.y; lx = line.startingpoint.x; ly = line.startingpoint.y; ABCa = Math.Pow(ly, 2) + Math.Pow(lx, 2); ABCb = 2 * ((ly * dy) + (lx * dx)); ABCc = Math.Pow(dy, 2) + Math.Pow(dx, 2) - 1; discr = Math.Pow(ABCb, 2) - (4 * ABCa * ABCc); if (discr < 0) { ip = new Scientrace.IntersectionPoint[0]; //ip[0] = null; //ip[1] = null; return(ip); } if (discr == 0) { ip = new Scientrace.IntersectionPoint[1]; d1 = ((-ABCb) + Math.Sqrt(Math.Pow(ABCb, 2) - (4 * ABCa * ABCc))) / (2 * ABCa); v1 = (line.direction.toVector() * d1) + line.startingpoint.toVector(); //plane1 is based on v1 rotated 90 degrees which makes: x' = -y, y' = x, z = z plane1 = new Scientrace.FlatShape2d(v1.toLocation(), new Scientrace.UnitVector(0, 0, 1), new Scientrace.UnitVector(-v1.y, v1.x, v1.z)); ip[0] = new IntersectionPoint(v1.toLocation(), plane1); return(ip); } d1 = ((-ABCb) + Math.Sqrt(Math.Pow(ABCb, 2) - (4 * ABCa * ABCc))) / (2 * ABCa); d2 = ((-ABCb) - Math.Sqrt(Math.Pow(ABCb, 2) - (4 * ABCa * ABCc))) / (2 * ABCa); v1 = (line.direction.toVector() * d1) + line.startingpoint.toVector(); v2 = (line.direction.toVector() * d2) + line.startingpoint.toVector(); ip = new Scientrace.IntersectionPoint[2]; plane1 = new Scientrace.FlatShape2d(v1.toLocation(), new Scientrace.UnitVector(0, 0, 1), new Scientrace.UnitVector(-v1.y, v1.x, v1.z)); ip[0] = new IntersectionPoint(v1.toLocation(), plane1); plane2 = new Scientrace.FlatShape2d(v2.toLocation(), new Scientrace.UnitVector(0, 0, 1), new Scientrace.UnitVector(-v2.y, v2.x, v2.z)); ip[1] = new IntersectionPoint(v2.toLocation(), plane2); return(ip); }
public IntersectionPoint[] intersects11circleborder(Trace trace) { Scientrace.Line line = trace.traceline; double d1, d2, dx, dy, lx, ly; double ABCa, ABCb, ABCc, discr; Scientrace.Vector v1, v2; Scientrace.FlatShape2d plane1, plane2; Scientrace.IntersectionPoint[] ip; dx = line.direction.x; dy = line.direction.y; lx = line.startingpoint.x; ly = line.startingpoint.y; ABCa = Math.Pow(ly,2)+Math.Pow(lx,2); ABCb = 2*((ly*dy) + (lx*dx)); ABCc = Math.Pow(dy,2)+Math.Pow(dx,2)-1; discr = Math.Pow(ABCb, 2)-(4*ABCa*ABCc); if (discr < 0) { ip = new Scientrace.IntersectionPoint[0]; //ip[0] = null; //ip[1] = null; return ip; } if (discr == 0) { ip = new Scientrace.IntersectionPoint[1]; d1 = ((-ABCb)+Math.Sqrt(Math.Pow(ABCb, 2)-(4*ABCa*ABCc)))/(2*ABCa); v1 = (line.direction.toVector()*d1)+line.startingpoint.toVector(); //plane1 is based on v1 rotated 90 degrees which makes: x' = -y, y' = x, z = z plane1 = new Scientrace.FlatShape2d(v1.toLocation(), new Scientrace.UnitVector(0,0,1), new Scientrace.UnitVector(-v1.y, v1.x, v1.z)); ip[0] = new IntersectionPoint(v1.toLocation(), plane1); return ip; } d1 = ((-ABCb)+Math.Sqrt(Math.Pow(ABCb, 2)-(4*ABCa*ABCc)))/(2*ABCa); d2 = ((-ABCb)-Math.Sqrt(Math.Pow(ABCb, 2)-(4*ABCa*ABCc)))/(2*ABCa); v1 = (line.direction.toVector()*d1)+line.startingpoint.toVector(); v2 = (line.direction.toVector()*d2)+line.startingpoint.toVector(); ip = new Scientrace.IntersectionPoint[2]; plane1 = new Scientrace.FlatShape2d(v1.toLocation(), new Scientrace.UnitVector(0,0,1), new Scientrace.UnitVector(-v1.y, v1.x, v1.z)); ip[0] = new IntersectionPoint(v1.toLocation(), plane1); plane2 = new Scientrace.FlatShape2d(v2.toLocation(), new Scientrace.UnitVector(0,0,1), new Scientrace.UnitVector(-v2.y, v2.x, v2.z)); ip[1] = new IntersectionPoint(v2.toLocation(), plane2); return ip; }
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 }
/// <summary> /// "line" has to be transformed so it encounters the 2nd order polynominal with /// its base at 0,0,0 and orientation in 0,0,1 (z-direction) /// </summary> /// <param name="line"> /// A <see cref="Scientrace.Line"/> /// </param> public IntersectionPoint[] baseintersections(Scientrace.Line line) { // location = line.loc * (d * line.dir); // keep formulae readable double d1, d2, dx, dy, dz, c, lx, ly, lz; double ABCa, ABCb, ABCc, discr; Scientrace.Vector v1, v2; Scientrace.IntersectionPoint[] ip; c = this.c; dx = line.direction.x; dy = line.direction.y; dz = line.direction.z; lx = line.startingpoint.x; ly = line.startingpoint.y; lz = line.startingpoint.z; ABCa = c * (Math.Pow(dy, 2) + Math.Pow(dx, 2)); ABCb = (2 * c * (dy * ly + dx * lx)) - dz; ABCc = (c * (Math.Pow(ly, 2) + Math.Pow(lx, 2))) - lz; /*if ((dx*dy) == 0) { * ip = new Scientrace.IntersectionPoint[1]; * v1 = new Vector(lx, ly, c*(Math.Pow(lx, 2)+Math.Pow(ly, 2))); * ip[0] = new IntersectionPoint(v1.toLocation(), this.intersectionPlane(v1.x, v1.y)); * //ip[1] = null; * return ip; * }*/ // if ((Math.Pow(ABCa,2)) < 1E-56) { // <-- used to be // if ((Math.Pow(ABCa,2)) < 1E-31) { // <-- used to be if ((Math.Pow(ABCa, 2)) < 1E-31) // <-- now, so no (/less) significance errors do occur any longer in results //Console.WriteLine("ABCa is SMALL"+ABCa.ToString()); { ip = new Scientrace.IntersectionPoint[1]; d1 = -ABCc / ABCb; v1 = (line.direction.toVector() * d1) + line.startingpoint.toVector(); ip[0] = new IntersectionPoint(v1.toLocation(), this.baseIntersectionShape(v1.x, v1.y)); return(ip); } //Console.WriteLine("ABCa is large enough "+ABCa.ToString()); //d1,2 => lambda 1,2 at http://amswiki.jbos.eu/wiki/index.php/Parabolic_Collision#Quadratic_formula //derived from the quadratic formula, note the +/- sign before the Sqrt. discr = Math.Pow(ABCb, 2) - (4 * ABCa * ABCc); if (discr < 0) { //Console.WriteLine("Negative discriminant : "+discr); ip = new Scientrace.IntersectionPoint[0]; //ip[0] = null; //ip[1] = null; return(ip); } if (discr == 0) { ip = new Scientrace.IntersectionPoint[1]; d1 = ((-ABCb) + Math.Sqrt(Math.Pow(ABCb, 2) - (4 * ABCa * ABCc))) / (2 * ABCa); v1 = (line.direction.toVector() * d1) + line.startingpoint.toVector(); ip[0] = new IntersectionPoint(v1.toLocation(), this.baseIntersectionShape(v1.x, v1.y)); return(ip); } //still here? two results! /*d1 = ((-ABCb)+Math.Sqrt(Math.Pow(ABCb, 2)-(4*ABCa*ABCc)))/(2*ABCa); * d2 = ((-ABCb)-Math.Sqrt(Math.Pow(ABCb, 2)-(4*ABCa*ABCc)))/(2*ABCa);*/ d1 = ((-ABCb) + Math.Sqrt(discr)) / (2.0 * ABCa); d2 = ((-ABCb) - Math.Sqrt(discr)) / (2.0 * ABCa); v1 = (line.direction.toVector() * d1) + line.startingpoint.toVector(); v2 = (line.direction.toVector() * d2) + line.startingpoint.toVector(); //Console.WriteLine("discr: "+discr+" ABCa: "+ABCa+" ABCb: "+ABCb+" ABCc: "+ABCc); //FOR BETTER PERFORMANCE REMOVE CHECKS BELOW /* //This was removed at 20160222 * if ((v1 != null) && (!line.throughLocation(v1.toLocation(), 0.00001))) { * throw new Exception("TRFd line 1 "+v1.trico()+" avoids "+line.ToString()); * } * if ((v2 != null) && (!line.throughLocation(v2.toLocation(), 0.00001))) { * v2 = v1; * // Console.WriteLine("discr: "+discr); * // throw new Exception("TRFd line 2 "+v1.trico()+" avoids "+line.ToString()+" contrairy to "+v1.trico()); * } */ ip = new Scientrace.IntersectionPoint[2]; ip[0] = (v1 == null ? null : new IntersectionPoint(v1.toLocation(), this.baseIntersectionShape(v1.x, v1.y)) ); ip[1] = (v2 == null ? null : new IntersectionPoint(v2.toLocation(), this.baseIntersectionShape(v2.x, v2.y)) ); return(ip); }