예제 #1
0
 public TreeViaShape(double _x, double _y, double _thickness, double _height, double depth, double angle = 0, bool polygon = false, bool leaves = false)
 {
     if (leaves)
     {
         Line leaf = new Line();
         leaf.Stroke             = Brushes.Black;
         leaf.StrokeStartLineCap = PenLineCap.Round;
         leaf.StrokeEndLineCap   = PenLineCap.Triangle;
         leaf.StrokeThickness    = 2;
         leaf.X1 = _x; // + _thickness / 2 * Math.Cos(angle);
         leaf.Y1 = _y; // + _thickness / 2 * Math.Sin(angle);
         leaf.X2 = leaf.X1 + 5 * Math.Sin(angle);
         leaf.Y2 = leaf.Y1 - 5 * Math.Cos(angle);
         brunch  = leaf;
         return;
     }
     if (polygon)
     {
         Polygon pol = new Polygon();
         pol.Stroke   = Brushes.Black;
         pol.Fill     = Brushes.Black;
         pol.FillRule = FillRule.Nonzero;
         pol.Points.Add(new Point(_x, _y));
         pol.Points.Add(new Point(_x + (1 - thick_coef) * _thickness / 2, _y - _height));
         pol.Points.Add(new Point(_x + (1 + thick_coef) * _thickness / 2, _y - _height));
         pol.Points.Add(new Point(_x + _thickness, _y));
         if (angle > 0)
         {
             pol.RenderTransform = new RotateTransform(angle / rad2deg,
                                                       _thickness, 0);
         }
         else
         {
             pol.RenderTransform = new RotateTransform(angle / rad2deg,
                                                       0, 0);
         }
     }
     else
     {
         brunch        = new Rectangle();
         brunch.Height = _height;
         brunch.Width  = _thickness;
         brunch.Stroke = Brushes.Black;
         brunch.Fill   = Brushes.Black;
         Canvas.SetLeft(brunch, _x);
         Canvas.SetTop(brunch, _y);
         //if (angle > 0)
         //brunch.RenderTransform = new RotateTransform(angle / rad2deg,
         //                                       _thickness,
         //                                      _height);
         //else
         brunch.RenderTransform = new RotateTransform(angle / rad2deg,
                                                      0, _height);
     }
     _thickness = _thickness * thick_coef;
     //_y -= _height;
     if (_height > 5 && depth < 350)
     {
         _x += _height * Math.Sin(angle) + ((brunch.Width - _thickness) / 2) * Math.Cos(angle);
         _y += _height * (1 - Math.Cos(angle)) - ((brunch.Width - _thickness) / 2) * Math.Sin(-angle);
         if (StaticRandom.NextDouble() < 0.9 || _thickness > 4)
         {
             center = new TreeViaShape(_x, _y - _height * height_coef,
                                       _thickness,
                                       _height * height_coef,
                                       depth + _height,
                                       angle,
                                       polygon);
         }
         if (StaticRandom.NextDouble() < 0.7 && (angle > -110 * rad2deg || _height < 15))
         {
             double new_height = _height * StaticRandom.NextGaussian(0.8, 0.2, 0.3, 0.9);
             //double new_height = _height * StaticRandom.NextDouble(0.7, 0.9);
             left = new TreeViaShape(_x, _y - new_height,
                                     StaticRandom.NextDouble(_thickness * 0.6, _thickness * 0.9),
                                     new_height,
                                     depth + _height,
                                     angle - StaticRandom.NextDouble(10, 46) * rad2deg,
                                     polygon);
         }
         if (StaticRandom.NextDouble() < 0.7 && (angle < 110 * rad2deg || _height < 15))
         {
             double new_height = _height * StaticRandom.NextGaussian(0.8, 0.2, 0.3, 0.9);
             //double new_height = _height * StaticRandom.NextDouble(0.7, 0.9);
             right = new TreeViaShape(_x, _y - new_height,
                                      StaticRandom.NextDouble(_thickness * 0.6, _thickness * 0.9),
                                      new_height,
                                      depth + _height,
                                      angle + StaticRandom.NextDouble(10, 46) * rad2deg,
                                      polygon);
         }
     }
     else
     {
         _x    += _height * Math.Sin(angle) + (brunch.Width / 2) * Math.Cos(angle);
         _y    += _height * (1 - Math.Cos(angle)) + (brunch.Width / 2) * Math.Sin(Math.Abs(angle));
         center = new TreeViaShape(_x, _y, _thickness, _height, 0, angle, polygon, true);
         left   = new TreeViaShape(_x - StaticRandom.NextDouble(_height / 5, _height / 2) * Math.Sin(angle),
                                   _y + StaticRandom.NextDouble(_height / 5, _height / 2) * Math.Cos(angle),
                                   _thickness, _height, 0,
                                   angle - StaticRandom.NextDouble(60, 90) * rad2deg, polygon, true);
         right = new TreeViaShape(_x - StaticRandom.NextDouble(_height / 5, _height / 2) * Math.Sin(angle),
                                  _y + StaticRandom.NextDouble(_height / 5, _height / 2) * Math.Cos(angle),
                                  _thickness, _height, 0,
                                  angle + StaticRandom.NextDouble(60, 90) * rad2deg, polygon, true);
     }
 }
예제 #2
0
        public void GenerateProteins()
        {
            var angleInverseDistributions = LoadInverseAngleDistributions();
            var pdbId                  = "1a2b";
            var aminoAcidSequence      = ReadAminoAcidSequenceFromPositionFile($@"G:\Projects\HumanGenome\Protein-PDBs\HumanProteins\AminoAcidPositions\pdb{pdbId}_model000.csv");
            var distanceMapsDirectory  = @"G:\Projects\HumanGenome\generatedProteins\DistanceMaps";
            var positionFilesDirectory = @"G:\Projects\HumanGenome\generatedProteins\PositionFiles";
            var distanceMean           = 380;
            var distanceSigma          = 4;

            var iterations = 1000;

            for (int iteration = 0; iteration < iterations; iteration++)
            {
                var aminoAcidPositions = new List <Point3D> {
                    new Point3D(0, 0, 0)
                };
                var lastAminoAcidLetter = aminoAcidSequence[0];
                for (var aminoAcidIdx = 1; aminoAcidIdx < aminoAcidSequence.Count; aminoAcidIdx++)
                {
                    var aminoAcidLetter = aminoAcidSequence[aminoAcidIdx];
                    var distance        = StaticRandom.NextGaussian(distanceMean, distanceSigma);
                    if (aminoAcidPositions.Count < 2)
                    {
                        aminoAcidPositions.Add(new Point3D(distance, 0, 0));
                        lastAminoAcidLetter = aminoAcidLetter;
                        continue;
                    }

                    var angleInverseDistribution = angleInverseDistributions[lastAminoAcidLetter];
                    var angleInRadians           = angleInverseDistribution.ValueAtX(StaticRandom.Rng.NextDouble());
                    var lastPosition             = aminoAcidPositions.Last().To(SIPrefix.Pico, Unit.Meter);
                    var vector1 = aminoAcidPositions[aminoAcidIdx - 2].VectorTo(aminoAcidPositions[aminoAcidIdx - 1]);
                    var vector2 = aminoAcidIdx >= 3
                        ? aminoAcidPositions[aminoAcidIdx - 3].VectorTo(aminoAcidPositions[aminoAcidIdx - 2])
                        : new Vector3D(0, 1, 0);
                    var bestPositionedPoint = ApproximateAminoAcidPositioner.CalculateAtomPosition(
                        lastPosition,
                        vector1,
                        vector2,
                        distance.To(SIPrefix.Pico, Unit.Meter),
                        angleInRadians.To(Unit.Radians),
                        (2 * Math.PI * (StaticRandom.Rng.NextDouble() - 0.5)).To(Unit.Radians));
                    var       isColliding           = CollidesWithExistingPositions(bestPositionedPoint, aminoAcidPositions, out var distanceToClosest);
                    var       bestDistanceToClosest = distanceToClosest;
                    const int MaxPositionIterations = 3;
                    var       positionIteration     = 0;
                    while (isColliding && positionIteration < MaxPositionIterations)
                    {
                        positionIteration++;
                        var pointCandidate = ApproximateAminoAcidPositioner.CalculateAtomPosition(
                            lastPosition,
                            vector1,
                            vector2,
                            distance.To(SIPrefix.Pico, Unit.Meter),
                            angleInRadians.To(Unit.Radians),
                            (2 * Math.PI * (StaticRandom.Rng.NextDouble() - 0.5)).To(Unit.Radians));
                        isColliding = CollidesWithExistingPositions(bestPositionedPoint, aminoAcidPositions, out distanceToClosest);
                        if (!isColliding)
                        {
                            bestPositionedPoint = pointCandidate;
                            break;
                        }
                        if (distanceToClosest > bestDistanceToClosest)
                        {
                            bestPositionedPoint   = pointCandidate;
                            bestDistanceToClosest = distanceToClosest;
                        }
                    }
                    aminoAcidPositions.Add(bestPositionedPoint.In(SIPrefix.Pico, Unit.Meter));

                    lastAminoAcidLetter = aminoAcidLetter;
                }

                var filenameBase = $"pdb{pdbId}_gen{iteration}";
                var distanceMap  = DistanceMapGenerator.Generate(aminoAcidPositions);
                distanceMap.Save(Path.Combine(distanceMapsDirectory, filenameBase + ".png"));
                File.WriteAllLines(
                    Path.Combine(positionFilesDirectory, filenameBase + ".csv"),
                    Enumerable.Range(0, aminoAcidSequence.Count)
                    .Select(idx => $"{aminoAcidSequence[idx]};{aminoAcidPositions[idx].ToString()}"));
            }
        }
예제 #3
0
 public void MakeATree(double _x, double _y, double _thickness, double _height, double depth, double angle = 0, bool polygon = false, bool leaves = false)
 {
     if (leaves)
     {
         EllipseGeometry leaf = new EllipseGeometry(new Point(_x, _y), leafHOR, leafVER);
         leaf.Transform = new RotateTransform(angle / rad2deg, _x, _y);
         tree.Children.Add(leaf);
         double new_x = _x - StaticRandom.NextDouble(_height / 5, _height / 2) * Math.Sin(angle);
         double new_y = _y + StaticRandom.NextDouble(_height / 5, _height / 2) * Math.Cos(angle);
         leaf           = new EllipseGeometry(new Point(new_x, new_y), leafHOR, leafVER);
         leaf.Transform = new RotateTransform(angle / rad2deg + 90, new_x, new_y);
         tree.Children.Add(leaf);
         new_x          = _x - StaticRandom.NextDouble(_height / 5, _height / 2) * Math.Sin(angle);
         new_y          = _y + StaticRandom.NextDouble(_height / 5, _height / 2) * Math.Cos(angle);
         leaf           = new EllipseGeometry(new Point(new_x, new_y), leafHOR, leafVER);
         leaf.Transform = new RotateTransform(angle / rad2deg - 90, new_x, new_y);
         tree.Children.Add(leaf);
         return;
     }
     if (polygon)
     {
         StreamGeometry a = new StreamGeometry();
         using (var b = a.Open())
         {
             b.BeginFigure(new Point(_x, _y + _height), true, true);
             b.LineTo(new Point(_x + (1 - thick_coef) * _thickness / 2, _y), true, true);
             b.LineTo(new Point(_x + (1 + thick_coef) * _thickness / 2, _y), true, true);
             b.LineTo(new Point(_x + _thickness, _y + _height), true, true);
             b.Close();
         }
         a.Transform = new RotateTransform(angle / rad2deg, _x, _y + _height);
         tree.Children.Add(a);
     }
     else
     {
         Rect rectangle           = new Rect(new Point(_x, _y), new Size(_thickness, _height));
         RectangleGeometry brunch = new RectangleGeometry(rectangle);
         if (angle > 0)
         {
             brunch.Transform = new RotateTransform(angle / rad2deg,
                                                    _x + _thickness,
                                                    _y + _height);
         }
         else
         {
             brunch.Transform = new RotateTransform(angle / rad2deg,
                                                    _x,
                                                    _y + _height);
         }
         tree.Children.Add(brunch);
     }
     //_y -= _height;
     if (_height > 5 && depth < 350)
     {
         _x        += _height * Math.Sin(angle) + (1 - thick_coef) * _thickness / 2 * Math.Cos(angle);
         _y        += _height * (1 - Math.Cos(angle)) - (1 - thick_coef) * _thickness / 2 * Math.Sin(-angle);
         _thickness = _thickness * thick_coef;
         if (StaticRandom.NextDouble() < 0.9 || _thickness > 4)
         {
             double new_height = _height * StaticRandom.NextGaussian(0.85, 0.1, 0.7, 1);
             MakeATree(_x, _y - new_height,
                       _thickness,
                       new_height,
                       depth + _height,
                       angle, polygon);
         }
         if (StaticRandom.NextDouble() < 0.7 && (angle > -110 * rad2deg || _height < 15))
         {
             double new_height = _height * StaticRandom.NextGaussian(0.8, 0.2, 0.3, 0.9);
             //double new_height = _height * StaticRandom.NextDouble(0.7, 0.9);
             MakeATree(_x, _y - new_height,
                       StaticRandom.NextDouble(_thickness * 0.6, _thickness * 0.9),
                       new_height,
                       depth + _height,
                       angle - StaticRandom.NextDouble(10, 46) * rad2deg, polygon);
         }
         if (StaticRandom.NextDouble() < 0.7 && (angle < 110 * rad2deg || _height < 15))
         {
             double new_height = _height * StaticRandom.NextGaussian(0.8, 0.2, 0.3, 0.9);
             //double new_height = _height * StaticRandom.NextDouble(0.7, 0.9);
             MakeATree(_x, _y - new_height,
                       StaticRandom.NextDouble(_thickness * 0.6, _thickness * 0.9),
                       new_height,
                       depth + _height,
                       angle + StaticRandom.NextDouble(10, 46) * rad2deg, polygon);
         }
     }
     else
     {
         _x += _height * Math.Sin(angle) + thick_coef * _thickness / 2 * Math.Cos(angle);
         _y += _height * (1 - Math.Cos(angle)) + thick_coef * _thickness / 2 * Math.Sin(Math.Abs(angle));
         MakeATree(_x, _y, _thickness, _height, 0, angle, polygon, true);
     }
     return;
 }