private Color GetPixelHelper( int x, int y, int step = 0 ) { // if we're at the dest center, return the source center Point2D destPt = new Point2D(x, y) - m_dstCenter; if( destPt.R < DMS.EPSILON ) return m_Source.GetPixel((int)m_srcCenter.X, (int)m_srcCenter.Y); //calculate source location Point2D sourcePt; double timesAround = Math.Log(destPt.R, m_Tightness) - destPt.Theta / (2.0 * Math.PI); sourcePt = Point2D.FromPolar(m_innerRadius + (m_outerRadius - m_innerRadius) * delog(fractional(timesAround) + step, m_Tightness), (destPt.Theta + (2.0 * Math.PI * (Math.Floor(timesAround) - step))) * m_TwistFactor); sourcePt += m_srcCenter; //calculate our color Color result = Color.FromArgb(0, m_Blank); if (sourcePt.X >= 0 && sourcePt.Y >= 0 && sourcePt.X < m_Source.Width && sourcePt.Y < m_Source.Height) result = m_Source.GetPixel((int)sourcePt.X, (int)sourcePt.Y); //a solid color means we can return! if( result.A == 0xFF ) return result; //if it's transparent, return the next step down. Color next = GetPixelHelper(x, y, step - 1); if (result.A == 0x00) return next; //if it's only a little transparent, blend the next step down in. int R = (int)( (double)((result.R * result.A) + (next.R * (255-result.A))) / 255.0 ); int G = (int)( (double)((result.G * result.A) + (next.G * (255-result.A))) / 255.0 ); int B = (int)( (double)((result.B * result.A) + (next.B * (255-result.A))) / 255.0 ); return Color.FromArgb(R, G, B); }
//point on plane public RelativePosition( Point2D p, Segment seg ) { m_Segment = seg; Point2D BtoPos = p - m_Segment.B; Point2D AtoPos = p - m_Segment.A; if( Point2D.Dot( BtoPos, m_Segment.AtoBDir ) > 0.0 ) { m_fTheta = DMS.FixAngle(BtoPos.Theta - m_Segment.AtoBDir.Theta); m_fDistance = BtoPos.R; m_fClosestPt = m_Segment.Length; } /* if */ else if( Point2D.Dot( AtoPos, m_Segment.AtoBDir ) < 0.0 ) { m_fTheta = DMS.FixAngle(AtoPos.Theta - m_Segment.AtoBDir.Theta); m_fDistance = AtoPos.R; m_fClosestPt = 0.0; } /* else if */ else { double fAnglePosAB = DMS.FixAngle(AtoPos.Theta - m_Segment.AtoBDir.Theta); m_fDistance = Math.Sin( fAnglePosAB ) * AtoPos.R; m_fClosestPt = Math.Cos( fAnglePosAB ) * AtoPos.R; m_fTheta = m_fDistance > 0.0 ? DMS.QUARTERTAU : -DMS.QUARTERTAU; m_fDistance = Math.Abs( m_fDistance ); } /* else */ }
//constructors; public Equirect2Ortho(Renderer renderer, int size) : base(new Size(size, size)) { m_renderer = renderer; m_radius = size / 2; m_center = new Point2D(m_radius, m_radius ); }
public Globedrawer( int size, DMSImage source, Color Background, Skeleton skeleton, bool bOrthographic = true ) : base(new Size(bOrthographic?size:2*size, size), source, Background) { m_bOrthographic = bOrthographic; m_Skeleton = skeleton; m_radius = size/2; m_center = new Point2D(m_radius, m_radius); }
/// <summary> /// Draws a circle /// </summary> /// <param name="center">center of the circle</param> /// <param name="radius">it's radius</param> /// <param name="fillStr">fill color</param> /// <param name="outlineStr">outline color</param> public void DrawCircle(Point2D center, double radius, String fillStr, String outlineStr) { StartDrawingObject(); m_sw.WriteLine( "" + center.X + " " + center.Y + " " + radius + " 0 360 arc" ); EndDrawingObject(fillStr, outlineStr); }
//coords of p range from 0.0 to 1.0; Point3D OrthoTo3D(Point2D p) { double u = p.X * 2.0 - 1.0; double v = p.Y * 2.0 - 1.0; double w = Math.Sqrt(Math.Max(1.0 - u * u - v * v, 0.0)); return Equirect2Ortho.NICE_TILT.Rotate(new Point3D(u, v, w)); }
public Path(Point2D pt1, params Point2D[] pts) : this() { AddControlPt(pt1); foreach (Point2D pt in pts) { AddControlPt(pt); } }
public override Color GetPixel(int x, int y) { Point3D pointOnSphere = Point3D.FromSphericalCoords(1.0, (double)y / Size.Height * Math.PI, (double)x / Size.Width * Math.PI * 2.0); Point2D pointOnStereographic = pointOnSphere.StereographicToPlane(); Point2D imageLocation = pointOnStereographic / 6.0; imageLocation += new Point2D(0.5, 0.5); return m_Source.GetPixel(imageLocation); }
public Droste(DMSImage Source, Point2D SrcCenter, double SrcInnerRad, double SrcOuterRad, Size DstSize, Point2D DstCenter, double DstTwistFactor, Color Blank) : base(DstSize, Source, Blank) { m_srcCenter = SrcCenter; m_dstCenter = DstCenter; m_outerRadius = Math.Max(SrcOuterRad, SrcInnerRad); m_innerRadius = Math.Min(SrcOuterRad, SrcInnerRad); m_Tightness = m_outerRadius / m_innerRadius; m_TwistFactor = DstTwistFactor; }
private Point2D ConformallyStretchRadius(Point2D pt, double ConstantRadius, double factor) { //calculate new radius double radius = pt.R; radius /= ConstantRadius; radius = Math.Pow(radius, m_Symmetry / 6.0); radius *= ConstantRadius; //calculate new theta double theta = pt.Theta; theta *= m_Symmetry / 6.0; //put it back into point2d for our polar2cartesian conversion return Point2D.FromPolar(radius, theta); }
public override Color GetPixel(int x, int y) { double ConstantRadius = Math.Min((double)m_Source.Width / 2.0, (double)m_Source.Height / 2.0); //prepare coordinate (centered at origin) Point2D coordinate = new Point2D(x, y); Point2D offset = new Point2D((double)m_Source.Width / 2.0, (double)m_Source.Height / 2.0); coordinate -= offset; coordinate.Theta += Math.PI / 2.0; //deal with the blend weighting double sweep = coordinate.Theta / Math.PI * 8.0 - 7.0; double weight = 0.0; //1.0 means use the colour from: coordinate, 0.0 means use coordinateB; if (sweep > -DMS.EPSILON && sweep <= 1.0) { weight = DMS.smooth(sweep); } //apply the stretch, also calculate the other side to blend to coordinate = ConformallyStretchRadius(coordinate, ConstantRadius, m_Symmetry / 6.0); Point2D coordinateB = Point2D.FromPolar(coordinate.R, DMS.FixAnglePositive(coordinate.Theta) - 2.0 * Math.PI * m_Symmetry / 6.0); //now back to native coordinates coordinate.Theta += Math.PI / 6.0; coordinateB.Theta += Math.PI / 6.0; coordinate += offset; coordinateB += offset; if (coordinate.X < 0 || coordinate.X >= m_Source.Width || coordinate.Y < 0 || coordinate.Y >= m_Source.Height || coordinateB.X < 0 || coordinateB.X >= m_Source.Width || coordinateB.Y < 0 || coordinateB.Y >= m_Source.Height) return m_Blank; //apply the weighting. Color A = m_Source.GetPixel((int)coordinate.X, (int)coordinate.Y), B = m_Source.GetPixel((int)coordinateB.X, (int)coordinateB.Y); if (A.ToArgb() == m_Blank.ToArgb() || B.ToArgb() == m_Blank.ToArgb()) return m_Blank; return Color.FromArgb( (int)((1.0 - weight) * A.R + weight * B.R), (int)((1.0 - weight) * A.G + weight * B.G), (int)((1.0 - weight) * A.B + weight * B.B)); }
public override void AlignPt(ref Point2D input) { double distance = double.MaxValue; if( m_AlignerList.Count == 0 ) return; Aligner alignertouse = m_AlignerList[0]; foreach (Aligner a in m_AlignerList) { if (a.DistanceOut(input) < distance) { distance = a.DistanceOut(input); alignertouse = a; } } alignertouse.AlignPt(ref input); }
public override Color GetPixel(int x, int y) { double theta = (double)x / m_Size.Width * DMS.TAU; //longitude double phi = (double)y / m_Size.Height * DMS.HALFTAU; //angle down from north pole (latitude-ish) Point2D pt = new Point2D(theta, phi); //"unroll" by adding TAU * number of turns to theta, (and then back it off one) while( DMS.TAU * pt.Y > m_x * pt.X ) { pt.X += DMS.TAU; } pt.X -= DMS.TAU; //undo our spiral by rotating it clockwise pt.Theta -= m_alpha; //scale it so that we're referencing the stretched textStrip in it's native resolution pt.Scale(m_stretchedSize.Width / (m_n * m_y)); //unstretch it double horiz = pt.X * 2.0 / m_stretchedSize.Width; // 0 ... 2 horiz -= 1.0; // -1 ... 1 horiz *= m_maxStretched; // -m_maxStretched ... m_maxStretched horiz = unstretch(horiz); // -m_maxUnstretched ... m_maxUnstretched horiz /= m_maxUnstretched; // -1 ... 1 horiz += 1.0; // 0 ... 2 horiz *= 0.5 * m_textStripeSize.Width; // 0 ... textwidth pt.X = horiz; //wind our strip back up so we can reference the right pixel in the source while (pt.X >= m_Source.Width) { pt.X -= m_Source.Width; pt.Y += m_textStripeSize.Height; } if (pt.Y >= m_Source.Height || pt.Y < 0.0 || pt.X < 0.0 ) return m_Blank; return m_Source.GetPixel((int)pt.X, (int)pt.Y); }
public override Color GetPixel(int x, int y) { Point2D f_Z; //we have to calculate this. Point2D Z = new Point2D(x, y); //this is given Z -= new Point2D( m_Size.Width/2, m_Size.Height/2 ); Z *= 8.0 / Math.Max(m_Size.Height, m_Size.Width); #if true //rotate by 60 degres (e^(i*5/6*pi)) = (sqrt3)/2 + (1/2)i Z = Z * new Point2D(-Math.Sqrt(3.0)/4, 1.0/4); //we have z, we want f(z) = z+1/z f_Z = Z; f_Z = f_Z + Point2D.Invert(Z); #else f_Z = Z.Pow(2.0); #endif //great but we want to grab this from a visible sphere Point3D Source3D = f_Z.InvStereographicToSphere(); return m_Source.GetSpherePixel(Source3D); }
private void Square2Parallelogram() { Point2D posA = new Point2D(0, 0); Point2D posB = new Point2D(1, 0); Point2D posC = new Point2D(1, 1); Point2D posD = new Point2D(2, 1); int full = m_net.Size - 1; AlignToSeg AB = new AlignToSeg(posA, posB); AlignToSeg BD = new AlignToSeg(posB, posD); AlignToSeg CD = new AlignToSeg(posC, posD); AlignToSeg AC = new AlignToSeg(posA, posC); //edges m_net.AlignEdge(m_net[0, 0], m_net[0, full], AC); m_net.AlignEdge(m_net[0, full], m_net[full, full], CD); m_net.AlignEdge(m_net[full, full], m_net[full, 0], BD); m_net.AlignEdge(m_net[full, 0], m_net[0, 0], AB); //vertices m_net[0, 0].Alignment = new AlignFixed(posA); m_net[0, full].Alignment = new AlignFixed(posC); m_net[full, full].Alignment = new AlignFixed(posD); m_net[full, 0].Alignment = new AlignFixed(posB); //precondition the points: if( m_bFirstPass) for (int i = 0; i < m_net.Size; i++) for (int j = 0; j < m_net.Size; j++) { m_net[i, j].Position = m_net[i, j].Position * 2.0 / (double)m_net.Size - posD/2.0; } }
// good to go private void Square2Oval() { Indicatrix TL = m_net[0, m_net.Size - 1], BL = m_net[0, 0], TR = m_net[m_net.Size - 1, m_net.Size - 1], BR = m_net[m_net.Size - 1, 0]; Point2D posTL = new Point2D(-1, 1), posTR = new Point2D(1, 1), posBL = new Point2D(-1, -1), posBR = new Point2D(1, -1), center; double radius = Math.Sqrt(2); //adjust position if first time if( m_bFirstPass) for (int i = 0; i < m_net.Size; i++) for (int j = 0; j < m_net.Size; j++) m_net[i, j].Position = m_net[i, j].Position - new Point2D(m_net.Size/2, m_net.Size/2); AlignCombo perimeter = new AlignCombo(); center = new Point2D(0, 1); //typically Point2D.Origin; radius = (center - posTL).R; perimeter.AddAligner(new AlignToArc(center, radius, posTR, posTL)); center = new Point2D(0, -1); //typically Point2D.Origin; radius = (center - posBL).R; perimeter.AddAligner(new AlignToArc(center, radius, posBL, posBR)); perimeter.AddAligner(new AlignToSeg(posTL, posBL)); perimeter.AddAligner(new AlignToSeg(posTR, posBR)); m_net.AlignEdge(TL, TR, perimeter); m_net.AlignEdge(BL, BR, perimeter); m_net.AlignEdge(TL, BL, perimeter); m_net.AlignEdge(TR, BR, perimeter); }
//will do in a pinch private void Square2Heart() { Point2D A = new Point2D(-2.0, 0), B = new Point2D(-1.0, 0), C = new Point2D(0, 0), D = new Point2D(1.0, 0), E = new Point2D(2.0, 0), F = new Point2D(-Math.Sqrt(2.0), -Math.Sqrt(2.0)), G = new Point2D(Math.Sqrt(2.0), -Math.Sqrt(2.0)), H = new Point2D(0, -2.0 * Math.Sqrt(2)); Aligner HtoF = new AlignToSeg(H, F); Aligner HtoG = new AlignToSeg(H, G); Aligner FtoA = new AlignToArc(C, 2.0, A, F); Aligner EtoG = new AlignToArc(C, 2.0, G, E); Aligner AtoC = new AlignToArc(B, 1.0, C, A); Aligner CtoE = new AlignToArc(D, 1.0, E, C); AlignCombo Left = new AlignCombo(); Left.AddAligner(HtoF); Left.AddAligner(FtoA); Left.AddAligner(AtoC); AlignCombo Right = new AlignCombo(); Right.AddAligner(HtoG); Right.AddAligner(EtoG); Right.AddAligner(CtoE); m_net.AlignEdge(m_net[0, 0], m_net[m_net.Size - 1, m_net.Size - 1], new AlignToSeg(H, C)); m_net.AlignEdge(m_net[0, 0], m_net[0, m_net.Size - 1], Left); m_net.AlignEdge(m_net[0, 0], m_net[m_net.Size - 1, 0], Right); int quarter = m_net.Size / 4; m_net.AlignEdge(m_net[0, m_net.Size - 1], m_net[quarter, m_net.Size - 1], Left); m_net.AlignEdge(m_net[m_net.Size - 1, 0], m_net[m_net.Size - 1, quarter], Right); for (int i = quarter; i < m_net.Size; i++) { double fraction = (double)(i - quarter) / (double)(m_net.Size - 1 - quarter); fraction *= Math.PI; #if false //fix top arc m_net[i, m_net.Size - 1].Alignment = new AlignFixed(new Point2D(-1.0 - Math.Cos(fraction), Math.Sin(fraction))); m_net[m_net.Size - 1, i].Alignment = new AlignFixed(new Point2D(1.0 + Math.Cos(fraction), Math.Sin(fraction))); #else //initialize position if (m_bFirstPass) { m_net[i, m_net.Size - 1].Position = new Point2D(-1.0 - Math.Cos(fraction), Math.Sin(fraction)); m_net[m_net.Size - 1, i].Position = new Point2D(1.0 + Math.Cos(fraction), Math.Sin(fraction)); } #endif } //fix points m_net[0, 0].Alignment = new AlignFixed(H); m_net[m_net.Size - 1, m_net.Size - 1].Alignment = new AlignFixed(C); }
//good to go private void Square2Circle() { //center the square on the origin int full = m_net.Size - 1; int half = m_net.Size/2; //constrain verticle and horizontal lines Point2D N = new Point2D(0, 1); Point2D S = new Point2D(0, -1); Point2D E = new Point2D(1, 0); Point2D W = new Point2D(-1, 0); m_net.AlignEdge(m_net[half, full], m_net[half, 0], new AlignToSeg(N, S)); m_net.AlignEdge(m_net[full, half], m_net[0, half], new AlignToSeg(E, W)); //constrain diagonals Point2D NE = new Point2D(Math.Sqrt(0.5), Math.Sqrt(0.5)); Point2D NW = new Point2D(Math.Sqrt(0.5), -Math.Sqrt(0.5)); Point2D SE = new Point2D(-Math.Sqrt(0.5), Math.Sqrt(0.5)); Point2D SW = new Point2D(-Math.Sqrt(0.5), -Math.Sqrt(0.5)); m_net.AlignEdge(m_net[full, full], m_net[0, 0], new AlignToSeg(NE, SW)); m_net.AlignEdge(m_net[full, 0], m_net[0, full], new AlignToSeg(NW, SE)); //constrain specific points m_net[0, 0].Alignment = new AlignFixed(SW); m_net[full, full].Alignment = new AlignFixed(NE); m_net[full, 0].Alignment = new AlignFixed(NW); m_net[0, full].Alignment = new AlignFixed(SE); m_net[0, half].Alignment = new AlignFixed(W); m_net[half, 0].Alignment = new AlignFixed(S); m_net[full, half].Alignment = new AlignFixed(E); m_net[half, full].Alignment = new AlignFixed(N); m_net[half, half].Alignment = new AlignFixed(Point2D.Origin); //constrain to circle AlignToArc circle = new AlignToArc(Point2D.Origin, 1.0); m_net.AlignEdge(m_net[0, 0], m_net[full, 0], circle); m_net.AlignEdge(m_net[full, 0], m_net[full, full], circle); m_net.AlignEdge(m_net[full, full], m_net[0, full], circle); m_net.AlignEdge(m_net[0, full], m_net[0, 0], circle); //setup initial position if first time if (m_bFirstPass) { for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if (m_net[i, j] != null) { m_net[i, j].Position *= 2.0 / (double)full; m_net[i, j].Position -= new Point2D(1.0, 1.0); } } } } }
private void Parallelogram2Square() { int full = m_net.Size - 1; int half = m_net.Size / 2; //remove points outside parallelogram for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if (j > half) m_net[i, j] = null; else if (i + j < half) m_net[i, j] = null; else if (i + j > full) m_net[i, j] = null; } } Point2D posA = new Point2D(-1, -1); Point2D posB = new Point2D(1, -1); Point2D posC = new Point2D(-1, 1); Point2D posD = new Point2D(1, 1); Indicatrix indA = m_net[half,0]; Indicatrix indB = m_net[full,0]; Indicatrix indC = m_net[0,half]; Indicatrix indD = m_net[half,half]; #if true //free floating AlignToSeg AB = new AlignToSeg(posA, posB); AlignToSeg BD = new AlignToSeg(posB, posD); AlignToSeg CD = new AlignToSeg(posC, posD); AlignToSeg AC = new AlignToSeg(posA, posC); AlignCombo BAC = new AlignCombo(); BAC.AddAligner(AB); BAC.AddAligner(AC); AlignCombo BDC = new AlignCombo(); BDC.AddAligner(BD); BDC.AddAligner(CD); AlignCombo ABCD = new AlignCombo(); ABCD.AddAligner(AB); ABCD.AddAligner(BD); ABCD.AddAligner(CD); ABCD.AddAligner(AC); //edges m_net.AlignEdge(indA, indC, ABCD); //AC m_net.AlignEdge(indC, indD, ABCD); //CD m_net.AlignEdge(indD, indB, ABCD); //DB m_net.AlignEdge(indB, indA, ABCD); //BA //vertices indA.Alignment = new AlignFixed(posA); //indB.Alignment = new AlignFixed(posB); //indC.Alignment = new AlignFixed(posC); indD.Alignment = new AlignFixed(posD); //precondition the points: if (m_bFirstPass) { for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { double x = (double)i / half - 1.0; double y = (double)j / half; x += y; x *= 2.0; x -= 1.0; y *= 2.0; y -= 1.0; if (m_net[i, j] != null) m_net[i, j].Position = new Point2D(x, y); } } } #else //fixed double perimeter = (double)half * 2.0 * (1.0 + Math.Sqrt(2.0)); for (int i = 0; i <= half; i++) { for( int j=0; j<4; j++) { double dist = 0.0; Indicatrix element = null; switch( j ) { case 0: //A-B, m_net[half,0] .. m_net[full,0] dist = (double)i; element = m_net[half+i,0]; break; case 1: //B-D, m_net[full,0] ..m_net[half,half] dist = (double)half + Math.Sqrt(2.0) * (double)i; element = m_net[full-i,i]; break; case 2: //D-C, m_net[half, half] .. m_net[0, half] dist = (double)half * (1.0 + Math.Sqrt(2.0)) + (double)i; element = m_net[half-i, half]; break; case 3: //C-A, m_net[0, half] .. m_net[half, 0] dist = (double)half * (2.0 + Math.Sqrt(2.0)) + Math.Sqrt(2.0) * (double)i; element = m_net[i, half-i]; break; } //dist should be 0..half*(2+2sqrt2) dist /= (double)half; //dist should be 0..2+2sqrt2 dist -= 1.0; //dist should be -1..1+2sqrt2 if (dist < 0.0) dist += (2.0 + 2.0 * Math.Sqrt(2.0)); //dist should be 0..2+2sqrt2 dist /= (2.0 + 2.0 * Math.Sqrt(2.0)); //dist should be 0..1 dist *= 4.0; //dist should be 0..4 int integerpart = (int)dist; double fractionalpart = dist - integerpart; switch (integerpart) { case 0: element.Alignment = new AlignFixed( posA + (posB-posA) * fractionalpart); break; case 1: element.Alignment = new AlignFixed( posB + (posD-posB) * fractionalpart); break; case 2: element.Alignment = new AlignFixed( posD + (posC-posD) * fractionalpart); break; case 3: element.Alignment = new AlignFixed( posC + (posA-posC) * fractionalpart); break; default: element.Alignment = new AlignFixed(posA); break; } } } #endif }
//good to go private void HalfCross2Circle2() { int eighth = m_net.Size / 8; int quarter = m_net.Size / 4; int full = m_net.Size - 1; int half = m_net.Size / 2; int threequarters = 3 * quarter; int threeeighths = 3 * eighth; //null out pts for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if ((i > threequarters || i < quarter) && (j > threequarters || j < quarter)) { m_net[i, j] = null; } } } //Set src pos. Indicatrix A = m_net[quarter, full], B = m_net[threequarters, full], C = m_net[threequarters, threequarters], D = m_net[full, threequarters], E = m_net[full, quarter], F = m_net[threequarters, quarter], G = m_net[threequarters, 0], H = m_net[quarter, 0], I = m_net[quarter, quarter], J = m_net[0, quarter], K = m_net[0, threequarters], L = m_net[quarter, threequarters]; double sqrt2 = Math.Sqrt(2.0); double sqrt3m1 = Math.Sqrt(3.0) - 1.0; double twosqrt2 = 2.0 * Math.Sqrt(2.0); Point2D pos1 = new Point2D(-sqrt2, sqrt2), pos2 = new Point2D(sqrt2, sqrt2), pos3 = new Point2D(sqrt2, -sqrt2), pos4 = new Point2D(-sqrt2, -sqrt2), pos5 = new Point2D(-sqrt3m1, sqrt3m1), pos6 = new Point2D(sqrt3m1, sqrt3m1), pos7 = new Point2D(sqrt3m1, -sqrt3m1), pos8 = new Point2D(-sqrt3m1, -sqrt3m1); m_net.AlignEdge(m_net[0, half], m_net[full, half], new AlignToSeg(new Point2D(2, 0), new Point2D(-2, 0))); m_net.AlignEdge(m_net[half, 0], m_net[half, full], new AlignToSeg(new Point2D(0, 2), new Point2D(0, -2))); m_net.AlignEdge(C, I, new AlignToSeg(new Point2D(2, 2), new Point2D(-2, -2))); m_net.AlignEdge(F, L, new AlignToSeg(new Point2D(-2, 2), new Point2D(2, -2))); m_net.AlignEdge(A, B, new AlignToArc(Point2D.Origin, 2.0, pos2, pos1)); m_net.AlignEdge(D, E, new AlignToArc(Point2D.Origin, 2.0, pos3, pos2)); m_net.AlignEdge(G, H, new AlignToArc(Point2D.Origin, 2.0, pos4, pos3)); m_net.AlignEdge(J, K, new AlignToArc(Point2D.Origin, 2.0, pos1, pos4)); m_net.AlignEdge(L, A, new AlignToSeg(pos1, pos5)); m_net.AlignEdge(B, C, new AlignToSeg(pos2, pos6)); m_net.AlignEdge(C, D, new AlignToSeg(pos2, pos6)); m_net.AlignEdge(E, F, new AlignToSeg(pos3, pos7)); m_net.AlignEdge(F, G, new AlignToSeg(pos3, pos7)); m_net.AlignEdge(H, I, new AlignToSeg(pos4, pos8)); m_net.AlignEdge(I, J, new AlignToSeg(pos4, pos8)); m_net.AlignEdge(K, L, new AlignToSeg(pos1, pos5)); A.Alignment = K.Alignment = new AlignFixed(pos1); L.Alignment = new AlignFixed(pos5); B.Alignment = D.Alignment = new AlignFixed(pos2); C.Alignment = new AlignFixed(pos6); E.Alignment = G.Alignment = new AlignFixed(pos3); F.Alignment = new AlignFixed(pos7); H.Alignment = J.Alignment = new AlignFixed(pos4); I.Alignment = new AlignFixed(pos8); }
// good to go private void HalfCross2Circle1() { int eighth = m_net.Size / 8; int quarter = m_net.Size / 4; int full = m_net.Size - 1; int half = m_net.Size / 2; int threequarters = 3 * quarter; int threeeighths = 3 * eighth; //null out pts for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if (j >= half && j <= threequarters) { if (i > threeeighths) m_net[i, j] = null; } else if (i > eighth) { m_net[i, j] = null; } } } //Set src pos. Indicatrix A = m_net[eighth, full], B = m_net[eighth, threequarters], C = m_net[threeeighths, threequarters], D = m_net[threeeighths, half], E = m_net[eighth, half], F = m_net[eighth, quarter], G = m_net[eighth, 0], H = m_net[0, 0], I = m_net[0, quarter], J = m_net[0, half], K = m_net[0, threequarters], L = m_net[0, full]; double sqrt2 = Math.Sqrt(2.0); double sqrt3m1 = Math.Sqrt(3.0) - 1.0; double twosqrt2 = 2.0 * Math.Sqrt(2.0); Point2D pos1 = new Point2D(-sqrt2, sqrt2), pos2 = new Point2D(sqrt2, sqrt2), pos3 = new Point2D(sqrt2, -sqrt2), pos4 = new Point2D(-sqrt2, -sqrt2), pos5 = new Point2D(-sqrt3m1, sqrt3m1), pos6 = new Point2D(sqrt3m1, sqrt3m1), pos7 = new Point2D(sqrt3m1, -sqrt3m1), pos8 = new Point2D(-sqrt3m1, -sqrt3m1); m_net.AlignEdge(A, B, new AlignToArc(new Point2D(2.0, 0.0), twosqrt2, pos5, pos8)); m_net.AlignEdge(B, C, new AlignToArc(new Point2D(2.0, 0.0), twosqrt2, pos5, pos8)); m_net.AlignEdge(C, D, new AlignToArc(new Point2D(0.0, -2.0), twosqrt2, pos6, pos5)); m_net.AlignEdge(D, E, new AlignToArc(new Point2D(-2.0, 0.0), twosqrt2, pos7, pos6)); m_net.AlignEdge(E, F, new AlignToArc(new Point2D(-2.0, 0.0), twosqrt2, pos7, pos6)); m_net.AlignEdge(F, G, new AlignToArc(new Point2D(0.0, -2.0), twosqrt2, pos6, pos5)); m_net.AlignEdge(G, H, new AlignToSeg(pos1, pos5)); m_net.AlignEdge(H, I, new AlignToArc(Point2D.Origin, 2.0, pos2, pos1)); m_net.AlignEdge(I, J, new AlignToArc(Point2D.Origin, 2.0, pos3, pos2)); m_net.AlignEdge(J, K, new AlignToArc(Point2D.Origin, 2.0, pos4, pos3)); m_net.AlignEdge(K, L, new AlignToArc(Point2D.Origin, 2.0, pos1, pos4)); m_net.AlignEdge(L, A, new AlignToSeg(pos1, pos5)); A.Alignment = C.Alignment = G.Alignment = new AlignFixed(pos5); B.Alignment = new AlignFixed(pos8); D.Alignment = F.Alignment = new AlignFixed(pos6); E.Alignment = new AlignFixed(pos7); H.Alignment = L.Alignment = new AlignFixed(pos1); I.Alignment = new AlignFixed(pos2); J.Alignment = new AlignFixed(pos3); K.Alignment = new AlignFixed(pos4); }
// good to go private void Square2Rectangle() { Point2D BL = new Point2D(0.0, 0.0); Point2D BR = new Point2D(1.0, 0.0); Point2D TR = new Point2D(1.0, m_Ratio); Point2D TL = new Point2D(0.0, m_Ratio); int full = m_net.Size - 1; //create aligner AlignCombo rectangle = new AlignCombo(); rectangle.AddAligner(new AlignToSeg(TL, TR)); rectangle.AddAligner(new AlignToSeg(BL, BR)); rectangle.AddAligner(new AlignToSeg(TL, BL)); rectangle.AddAligner(new AlignToSeg(BR, TR)); //constrain the sides for (int i = 0; i < m_net.Size; i++) { m_net[i, full].Alignment = rectangle; //top m_net[i, 0].Alignment = rectangle; //bottom m_net[full, i].Alignment = rectangle; //right m_net[0, i].Alignment = rectangle; //left } //setup initial position if first time if (m_bFirstPass) { for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { m_net[i, j].Position /= (double)full; m_net[i, j].Position.Y *= m_Ratio; } } } }
private void ScaleNet( ) { //first lets determine the extents of the net Point2D MinExtent = new Point2D(double.MaxValue, double.MaxValue); Point2D MaxExtent = new Point2D(double.MinValue, double.MinValue); for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if (m_net[i, j] == null) continue; if (m_net[i, j].Position.X < MinExtent.X) MinExtent.X = m_net[i, j].Position.X; if (m_net[i, j].Position.Y < MinExtent.Y) MinExtent.Y = m_net[i, j].Position.Y; if (m_net[i, j].Position.X > MaxExtent.X) MaxExtent.X = m_net[i, j].Position.X; if (m_net[i, j].Position.Y > MaxExtent.Y) MaxExtent.Y = m_net[i, j].Position.Y; } } double Scale = Math.Max(MaxExtent.X - MinExtent.X, MaxExtent.Y - MinExtent.Y); //now adjust positions for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if (m_net[i, j] == null) continue; m_net[i, j].Position = (m_net[i, j].Position - MinExtent) / Scale * 2.0 - new Point2D(1.0, 1.0); } } }
//good to go private void Triangle() { Point2D BL = new Point2D(0.0, 0.0); Point2D BR = new Point2D(1.0, 0.0); Point2D TR = new Point2D(1.0, m_Ratio); int full = m_net.Size - 1; // erase points not in triangle for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if (j > i) m_net[i, j] = null; } } //constrain the sides for (int i = 0; i < m_net.Size; i++) { m_net[i, i].Alignment = new AlignToSeg(BL, TR); m_net[i, 0].Alignment = new AlignToSeg(BL, BR); m_net[full, i].Alignment = new AlignToSeg(BR, TR); } //fix the corners m_net[0, 0].Alignment = new AlignFixed(BL); m_net[full, 0].Alignment = new AlignFixed(BR); m_net[full, full].Alignment = new AlignFixed(TR); //setup initial position if first time if (m_bFirstPass) { for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if (m_net[i, j] != null) { m_net[i, j].Position /= (double)full; m_net[i, j].Position.Y *= m_Ratio; } } } } }
private void Square2Triangle() { Point2D posA = new Point2D(-1.0, 0); Point2D posB = new Point2D(1.0, 0); Point2D posC = new Point2D(0, Math.Sqrt(3)); int half = m_net.Size / 2; int full = m_net.Size - 1; AlignToSeg AC = new AlignToSeg(posA, posC); AlignToSeg OB = new AlignToSeg(Point2D.Origin, posB); AlignToSeg AO = new AlignToSeg(posA, Point2D.Origin); AlignToSeg BC = new AlignToSeg(posB, posC); AlignToSeg CO = new AlignToSeg(posC, Point2D.Origin); AlignCombo Left = new AlignCombo(); Left.AddAligner(AC); Left.AddAligner(AO); AlignCombo Right = new AlignCombo(); Right.AddAligner(BC); Right.AddAligner(OB); //edges m_net.AlignEdge(m_net[0, 0], m_net[0, full], Left); m_net.AlignEdge(m_net[0, full], m_net[half, full], Left); m_net.AlignEdge(m_net[half, 0], m_net[0, 0], Left); m_net.AlignEdge(m_net[half, full], m_net[full, full], Right); m_net.AlignEdge(m_net[full, full], m_net[full, 0], Right); m_net.AlignEdge(m_net[half, 0], m_net[full, 0], Right); //centerline m_net.AlignEdge(m_net[half, 0], m_net[half, full], CO); m_net[half, 0].Alignment = new AlignFixed(Point2D.Origin); m_net[half, full].Alignment = new AlignFixed(posC); m_net[0, 0].Alignment = new AlignFixed(posA); m_net[full, 0].Alignment = new AlignFixed(posB); //precondition the points: if( m_bFirstPass) for (int i = 0; i < m_net.Size; i++) for (int j = 0; j < m_net.Size; j++) { m_net[i, j].Position = m_net[i, j].Position * 2.0 / (double)m_net.Size + new Point2D(-1.0, 0); } }
//good to go private void Diamond2Lens() { double Sqrt3 = Math.Sqrt(3.0); int full = (m_net.Size-1); int half = m_net.Size / 2; int left = (int)((double)m_net.Size * (Sqrt3 - 1.0) / (2.0 * Sqrt3)) + 1; int right = (int)((double)m_net.Size * (Sqrt3 + 1.0) / (2.0 * Sqrt3)) - 1; //zero out what we don't need for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if (m_net[i, j] != null) { if ((double)i + (double)j / Sqrt3 < (double)full * 0.5 - DMS.EPSILON || (double)i + (double)j / Sqrt3 > (double)full * (0.5 + 1.0/Sqrt3) + DMS.EPSILON || (double)i - (double)j /Sqrt3 > (double)full * 0.5 + DMS.EPSILON || (double)i - (double)j / Sqrt3 < (double)full * (0.5 - 1.0/Sqrt3) - DMS.EPSILON) { m_net[i, j] = null; } } } } Point2D A = -Point2D.XAxis; Point2D B = new Point2D(0, 1.0 / Sqrt3); Point2D C = Point2D.XAxis; Point2D D = new Point2D(0, -1.0 / Sqrt3); Point2D E = Point2D.Origin; AlignToArc AlignTop = new AlignToArc(D, 2.0 / Sqrt3, C, A); AlignToArc AlignBottom = new AlignToArc(B, 2.0 / Sqrt3, A, C); m_net.SetNeighbors(); //align arcs for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if (m_net[i, j] != null) { if (m_net[i, j].North == null) m_net[i, j].Alignment = AlignTop; else if (m_net[i, j].South == null) m_net[i, j].Alignment = AlignBottom; else m_net[i, j].Alignment = new Aligner(); //generic non-aligner } } } //align horizontal, align vertical axes m_net.AlignEdge(m_net[half, 0], m_net[half, full], new AlignToSeg(B, D)); m_net.AlignEdge(m_net[left, half], m_net[right, half], new AlignToSeg(A, C)); //align points m_net[half, 0].Alignment = new AlignFixed(D); m_net[half, full].Alignment = new AlignFixed(B); m_net[left, half].Alignment = new AlignFixed(A); m_net[right, half].Alignment = new AlignFixed(C); }
private Point Original(int i, int j) { Point2D result = new Point2D(i, j); result /= (double)(m_net.Size); result *= (double)(height - 2 * buffer); result += new Point2D(buffer, buffer); return new Point((int)result.X, (int)result.Y); }
//good to go private void Bitmap2Circle() { Aligner circle = new AlignToArc(Point2D.Origin, 1.0); double full = m_net.Size - 1; for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { Point2D pt = new Point2D(i, j) / full; if (m_mask.GetPixel(pt).ToArgb() == Color.Black.ToArgb()) m_net[i, j] = null; } } m_net.SetNeighbors(); //calculate center, and determine which points are edges. Point2D center = new Point2D(); bool[,] isedge = new bool[m_net.Size, m_net.Size]; for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { isedge[i, j] = false; if (m_net[i, j] == null) continue; if (m_net[i, j].East == null || m_net[i, j].West == null || m_net[i, j].South == null || m_net[i, j].North == null) { isedge[i, j] = true; } center += m_net[i, j].Position; } } center /= m_net.Count; //fix edge points to circle for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if (m_net[i, j] == null) continue; if (isedge[i, j]) m_net[i, j].Alignment = circle; if (m_bFirstPass) { m_net[i, j].Position -= center; m_net[i, j].Position = m_net[i,j].Position / full; } } } }
private Point Destination(Indicatrix A) { Point2D result = A.Position; result += new Point2D(1.0, 1.0); result /= 2.0; result *= (height - 2 * buffer); result += new Point2D(width/2 + buffer, buffer); return new Point((int)result.X, (int)result.Y); }
//good to go private void Bitmap2Rectangle() { Bitmap2Circle(); //create new aligner Point2D TL = new Point2D(-m_Ratio, 1), TR = new Point2D(m_Ratio, 1), BL = new Point2D(-m_Ratio, -1), BR = new Point2D(m_Ratio, -1); AlignCombo ToRectangle = new AlignCombo(); ToRectangle.AddAligner(new AlignToSeg(TR, TL)); ToRectangle.AddAligner(new AlignToSeg(BL, TL)); ToRectangle.AddAligner(new AlignToSeg(BL, BR)); ToRectangle.AddAligner(new AlignToSeg(TR, BR)); //set alignment for (int i = 0; i < m_net.Size; i++) { for (int j = 0; j < m_net.Size; j++) { if (m_net[i, j] == null) continue; if (m_net[i, j].Alignment is AlignToArc) { m_net[i, j].Alignment = ToRectangle; } } } }