double ComputeVennCircleDistanceForOverlap(VennCircle CircleX, VennCircle CircleY, double OverlapRegionXY, double precision) { double distanceMax = CircleX.radius + CircleY.radius; double distanceMin = Math.Abs(CircleX.radius - CircleY.radius); double distanceMid = (distanceMax + distanceMin) / 2.0; while (true) { double overlap = CircleX.ComputeOverlap(CircleY, distanceMid); if (overlap > (OverlapRegionXY + precision)) { // overlap is too large. Move the centers farther apart distanceMin = distanceMid; distanceMid = (distanceMax + distanceMin) / 2.0; } else if (overlap < (OverlapRegionXY - precision)) { // overlap is too small. Move the centers closer together distanceMax = distanceMid; distanceMid = (distanceMax + distanceMin) / 2.0; } else { break; } } return(distanceMid); }
public VennCircle(VennCircle vc) { center.X = vc.center.X; center.Y = vc.center.Y; radius = vc.radius; m_area = vc.m_area; }
public VennCircle(VennCircle vc, double scaleFactor) { this.center.X = vc.center.X * scaleFactor; this.center.Y = vc.center.Y * scaleFactor; this.radius = vc.radius * scaleFactor; this.m_area = vc.m_area; }
public double ComputeDistanceBetweenCenters(VennCircle circle) { // cartesian distance d = Sqrt( ((x2-x1)^2) + ((y2-y1)^2) ) double distance = Math.Sqrt(Math.Pow((center.X - circle.center.X), 2.0) + Math.Pow((center.Y - circle.center.Y), 2.0)); return(distance); }
public Point ComputeIntersectionPoint(VennCircle circle, double distance) { // compute a point of intersection for the circles Point pt = new Point(); pt.X = (Math.Pow(radius, 2.0) - Math.Pow(circle.radius, 2.0) + Math.Pow(distance, 2.0)) / (2.0 * distance); pt.Y = Math.Sqrt(Math.Pow(radius, 2.0) - Math.Pow(pt.X, 2.0)); return(pt); }
public Point ComputeIntersectionPoint(VennCircle circle) { // compute a point of intersection for the circles then the area of the overlap Point pt = new Point(); double distance = ComputeDistanceBetweenCenters(circle); pt.X = (Math.Pow(radius, 2.0) - Math.Pow(circle.radius, 2.0) + Math.Pow(distance, 2.0)) / (2.0 * distance); pt.Y = Math.Sqrt(Math.Pow(radius, 2.0) - Math.Pow(pt.X, 2.0)); return(pt); }
public void ComputeVennDiagramData() { // Create the circles and size them CircleA = new VennCircle(RegionA + RegionAB + RegionAC + RegionABC); CircleB = new VennCircle(RegionB + RegionAB + RegionBC + RegionABC); // TODO: what is the right precision computation? // fixed? based on smallest region? largest region? average of region sizes? // for now, compute our precision to 0.1% of average region size but no less than 1 double myPrecision = ((RegionA + RegionB + +RegionC + RegionAB + RegionAC + RegionBC + RegionABC) / 7) * 0.001; if (myPrecision < 1.0) { myPrecision = 1.0; } DistanceAB = ComputeVennCircleDistanceForOverlap(CircleA, CircleB, RegionAB + RegionABC, myPrecision); #if false Console.WriteLine("AB Distance {0}", DistanceAB); #endif // Position CircleA and CircleB along the x axis // since the Y axis is increasing going down, assign a negative value for Y CircleA.center.X = 0.0; CircleB.center.X = DistanceAB; // if this is a three circle Venn Diagram, compute the other circle and placement if (vennType == VennTypes.ThreeCircle) { CircleC = new VennCircle(RegionC + RegionAC + RegionBC + RegionABC); DistanceAC = ComputeVennCircleDistanceForOverlap(CircleA, CircleC, RegionAC + RegionABC, myPrecision); DistanceBC = ComputeVennCircleDistanceForOverlap(CircleB, CircleC, RegionBC + RegionABC, myPrecision); #if false Console.WriteLine("AC Distance {0}", DistanceAC); Console.WriteLine("BC Distance {0}", DistanceBC); #endif if ((DistanceAB + DistanceAC < DistanceBC) || (DistanceAB + DistanceBC < DistanceAC) || (DistanceAC + DistanceBC < DistanceAB)) { throw new ArgumentOutOfRangeException(Properties.Resources.NoFeasibleSolution); } // CircleA and CircleB are along the x axis, position CircleC above // since the Y axis is increasing going down, assign a negative value for Y CircleC.center.X = (Math.Pow(DistanceAC, 2.0) - Math.Pow(DistanceBC, 2.0) + Math.Pow(DistanceAB, 2.0)) / (2 * DistanceAB); CircleC.center.Y = 0 - Math.Sqrt(Math.Pow(DistanceAC, 2) - Math.Pow(CircleC.center.X, 2.0)); } }
public double ComputeOverlap(VennCircle circle, double distance) { if (distance > radius + circle.radius) { throw new Exception("No overlap"); } if (distance <= Math.Abs(radius - circle.radius)) { throw new Exception("Completely Enclosed"); } Point pt = ComputeIntersectionPoint(circle, distance); double overlap = (Math.Pow(radius, 2.0) * Math.Atan2(pt.Y, pt.X)) + (Math.Pow(circle.radius, 2.0) * Math.Atan2(pt.Y, distance - pt.X)) - (distance * pt.Y); return(overlap); }
public VennDiagramData(VennDiagramData vdd) { vennType = vdd.vennType; RegionA = vdd.RegionA; RegionB = vdd.RegionB; RegionC = vdd.RegionC; RegionAB = vdd.RegionAB; RegionAC = vdd.RegionAC; RegionBC = vdd.RegionBC; RegionABC = vdd.RegionABC; DistanceAB = vdd.DistanceAB; DistanceAC = vdd.DistanceAC; DistanceBC = vdd.DistanceBC; CircleA = new VennCircle(vdd.CircleA); CircleB = new VennCircle(vdd.CircleB); if (vennType == VennTypes.ThreeCircle) { CircleC = new VennCircle(vdd.CircleC); } fScaled = vdd.fScaled; }
public double ComputeOverlap(VennCircle circle) { double distance = ComputeDistanceBetweenCenters(circle); return(ComputeOverlap(circle, distance)); }
public double ComputeOverlap(VennCircle circle, double distance) { if (distance > radius + circle.radius) throw new Exception("No overlap"); if (distance <= Math.Abs(radius - circle.radius)) throw new Exception("Completely Enclosed"); Point pt = ComputeIntersectionPoint(circle, distance); double overlap = (Math.Pow(radius, 2.0) * Math.Atan2(pt.Y, pt.X)) + (Math.Pow(circle.radius, 2.0) * Math.Atan2(pt.Y, distance - pt.X)) - (distance * pt.Y); return overlap; }
public void ComputeVennDiagramData() { // Create the circles and size them CircleA = new VennCircle(RegionA + RegionAB + RegionAC + RegionABC); CircleB = new VennCircle(RegionB + RegionAB + RegionBC + RegionABC); // TODO: what is the right precision computation? // fixed? based on smallest region? largest region? average of region sizes? // for now, compute our precision to 0.1% of average region size but no less than 1 double myPrecision = ((RegionA + RegionB + +RegionC + RegionAB + RegionAC + RegionBC + RegionABC) / 7) * 0.001; if (myPrecision < 1.0) { myPrecision = 1.0; } DistanceAB = ComputeVennCircleDistanceForOverlap(CircleA, CircleB, RegionAB + RegionABC, myPrecision); #if false Console.WriteLine("AB Distance {0}", DistanceAB); #endif // Position CircleA and CircleB along the x axis // since the Y axis is increasing going down, assign a negative value for Y CircleA.center.X = 0.0; CircleB.center.X = DistanceAB; // if this is a three circle Venn Diagram, compute the other circle and placement if (vennType == VennTypes.ThreeCircle) { CircleC = new VennCircle(RegionC + RegionAC + RegionBC + RegionABC); DistanceAC = ComputeVennCircleDistanceForOverlap(CircleA, CircleC, RegionAC + RegionABC, myPrecision); DistanceBC = ComputeVennCircleDistanceForOverlap(CircleB, CircleC, RegionBC + RegionABC, myPrecision); #if false Console.WriteLine("AC Distance {0}", DistanceAC); Console.WriteLine("BC Distance {0}", DistanceBC); #endif if ((DistanceAB + DistanceAC < DistanceBC) || (DistanceAB + DistanceBC < DistanceAC) || (DistanceAC + DistanceBC < DistanceAB)) throw new ArgumentOutOfRangeException(Properties.Resources.NoFeasibleSolution); // CircleA and CircleB are along the x axis, position CircleC above // since the Y axis is increasing going down, assign a negative value for Y CircleC.center.X = (Math.Pow(DistanceAC, 2.0) - Math.Pow(DistanceBC, 2.0) + Math.Pow(DistanceAB, 2.0)) / (2 * DistanceAB); CircleC.center.Y = 0 - Math.Sqrt(Math.Pow(DistanceAC, 2) - Math.Pow(CircleC.center.X, 2.0)); } }
double ComputeVennCircleDistanceForOverlap(VennCircle CircleX, VennCircle CircleY, double OverlapRegionXY, double precision) { double distanceMax = CircleX.radius + CircleY.radius; double distanceMin = Math.Abs(CircleX.radius - CircleY.radius); double distanceMid = (distanceMax + distanceMin) / 2.0; while (true) { double overlap = CircleX.ComputeOverlap(CircleY, distanceMid); if (overlap > (OverlapRegionXY + precision)) { // overlap is too large. Move the centers farther apart distanceMin = distanceMid; distanceMid = (distanceMax + distanceMin) / 2.0; } else if (overlap < (OverlapRegionXY - precision)) { // overlap is too small. Move the centers closer together distanceMax = distanceMid; distanceMid = (distanceMax + distanceMin) / 2.0; } else { break; } } return distanceMid; }
public Point ComputeIntersectionPoint(VennCircle circle, double distance) { // compute a point of intersection for the circles Point pt = new Point(); pt.X = (Math.Pow(radius, 2.0) - Math.Pow(circle.radius, 2.0) + Math.Pow(distance, 2.0)) / (2.0 * distance); pt.Y = Math.Sqrt(Math.Pow(radius, 2.0) - Math.Pow(pt.X, 2.0)); return pt; }
public double ComputeDistanceBetweenCenters(VennCircle circle) { // cartesian distance d = Sqrt( ((x2-x1)^2) + ((y2-y1)^2) ) double distance = Math.Sqrt(Math.Pow((center.X - circle.center.X), 2.0) + Math.Pow((center.Y - circle.center.Y), 2.0)); return distance; }
public double ComputeOverlap(VennCircle circle) { double distance = ComputeDistanceBetweenCenters(circle); return ComputeOverlap(circle, distance); }
AddVennVertex ( ListObject vertexTable, VennCircle vc, int idx, string columnName, string color ) { string[] sLabelPosition = { "Middle Left", "Middle Right", "Bottom Center" }; PolarCoordinate pc = new PolarCoordinate(vc.center); // Add vertex to table SetTableCellValue(vertexTable, idx, VertexColumnName, columnName); SetTableCellValue(vertexTable, idx, ColorColumnName, color); SetTableCellValue(vertexTable, idx, ShapeColumnName, "Disk"); SetTableCellValue(vertexTable, idx, OpacityColumnName, 30); SetTableCellValue(vertexTable, idx, VisibilityColumnName, "Show"); SetTableCellValue(vertexTable, idx, LabelColumnName, "Group " + columnName); SetTableCellValue(vertexTable, idx, LabelPositionColumnName, sLabelPosition[idx]); SetTableCellValue(vertexTable, idx, PolarRColumnName, pc.Rho); SetTableCellValue(vertexTable, idx, PolarAngleColumnName, (pc.Theta * (180.0 / Math.PI))); SetTableCellValue(vertexTable, idx, SizeColumnName, RadiusWpfToVertexSize(vc.radius)); }
public Point ComputeIntersectionPoint(VennCircle circle) { // compute a point of intersection for the circles then the area of the overlap Point pt = new Point(); double distance = ComputeDistanceBetweenCenters(circle); pt.X = (Math.Pow(radius, 2.0) - Math.Pow(circle.radius, 2.0) + Math.Pow(distance, 2.0)) / (2.0 * distance); pt.Y = Math.Sqrt(Math.Pow(radius, 2.0) - Math.Pow(pt.X, 2.0)); return pt; }