Помогите преобразовать приложение Python в C # - PullRequest
3 голосов
/ 20 сентября 2010

Все,

вот ссылка на небольшое приложение на Python:

http://en.wikipedia.org/wiki/File:Beta-skeleton.svg

Я думаю, что я правильно его преобразовал(Источник внизу поста)

Но Math.Acos всегда возвращает NaN.Есть ли разница между Python-версией acos и Math.Acos?

    private Random rnd = new Random();
    private double scale = 5;
    private double radius = 10;
    private double beta1 = 1.1;
    private double beta2 = 0.9;
    private double theta1;
    private double theta2;

    private Point[] points = new Point[10];

    public MainWindow()
    {
        InitializeComponent();
        for (int i = 0; i < 100; i++ )
        {
            points[i] = new Point((rnd.NextDouble() * scale), 
                (rnd.NextDouble() * scale));
        }

        theta1 = Math.Asin(1/beta1);
        theta2 = Math.PI - Math.Asin(beta2);
    }

    private double Dot(Point p, Point q, Point r)
    {
        var pr = new Point();
        var qr = new Point();

        //(p[0]-r[0])
        pr.X = p.X-r.X;

        //(p[1]-r[1])
        pr.Y = p.Y-r.Y;

        //(q[0]-r[0])
        qr.X = q.X-r.X;

        //(q[1]-r[1])
        qr.Y = q.Y-r.Y;

        return (pr.X*qr.X) + (pr.Y*qr.Y);
    }

private double Sharp(Point p,Point q)
{
    double theta = 0;

    foreach(var pnt in points)
    {
        if(pnt!=p && pnt!=q)
        {
            var dotpq = Dot(p, q, pnt);
            double t = Math.Acos(dotpq);
            double u = Math.Pow((dotpq * dotpq), 0.5);

            var tempVal = t/u;

            theta = Math.Max(theta, tempVal);
        }
    }
    return theta;

}

    private void DrawPoint(Point p)
    {
        var e = new Ellipse
                    {
                        Width = radius/2,
                        Height = radius/2,
                        Stroke = Brushes.Red,
                        Visibility = Visibility.Visible
                    };

        Canvas.SetTop(e, p.Y + radius);
        Canvas.SetLeft(e, p.X + radius);

        MyCanvas.Children.Add(e);
    }

    private void DrawEdge1(Point p,Point q)
    {
        var l = new Line
                    {
                        X1 = p.X,
                        Y1 = p.Y,
                        X2 = q.X,
                        Y2 = q.Y,
                        Stroke = Brushes.Black,
                        Width = 1,
                        Visibility = Visibility.Visible
                    };

        MyCanvas.Children.Add(l);
    }

    private void DrawEdge2(Point p,Point q)
    {
        var l = new Line
                    {
                        X1 = p.X,
                        Y1 = p.Y,
                        X2 = q.X,
                        Y2 = q.Y,
                        Stroke = Brushes.Blue,
                        Width = 1,
                        Visibility = Visibility.Visible
                    };

        MyCanvas.Children.Add(l);
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        foreach (var p in points)
        {
            foreach (var q in points)
            {
                var theta = Sharp(p, q);

                if(theta < theta1) DrawEdge1(p, q);
                else if(theta < theta2) DrawEdge2(p, q);

            }                
        }
    }       

Ответы [ 3 ]

3 голосов
/ 20 сентября 2010

То, что вам нужно сделать, чтобы получить угол от точечного произведения, это убрать длину перед тем, как вы начнете.

Что у питона:

prq = acos(dot(p,q,r) / (dot(p,p,r)*dot(q,q,r))**0.5)

Что вы делаетене делится в Acos, а делится после.

так:

int r = pnt;
int ppr = Dot(p,p,r);
int qqr = Dot(q,q,r);
int pqr = Dot(p,q,r);

double u = Math.Acos(pqr / Math.Sqrt(ppr * qqr));

Конечно, меняйте переменные, я просто пытался сохранить его похожим на питон, чтобы помочь вам понять:)

2 голосов
/ 20 сентября 2010

Я думаю, это связано с вашим переводом выражения Python (dot(p,q,r) / (dot(p,p,r) * dot(q,q,r)) **0.5). Экспонирование в Python имеет один из самых низких операторов по приоритету, поэтому квадратный корень берется из подтерма dot(p,q,r) / (dot(p,p,r) * dot(q,q,r)). В вашей версии C # при вычислении значения двойного 'u' вы берете только квадратный корень из произведения двух последних членов, то есть (dotpq * dotpq).

0 голосов
/ 20 сентября 2010

Вопрос в том, каково значение dotpq при вызове функции.Это должно быть двойное значение между -1 и 1, как указано в документах .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...