2010-01-09 10 views
5

मैं एक सी #, में अनियमित बहुभुज के क्षेत्रफल की गणना करने के लिए कैसे 'नौसिखियों के लिए' लिखने के लिए प्रबंधित किया है लेकिन मैं इसे verticies की किसी भी राशि के लिए गतिशील होना चाहिए।सी # में अनियमित बहुभुज का क्षेत्रफल की गणना कर रहा

क्या कोई मदद कर सकता है?

कक्षा:

public class Vertex 
{ 
    private int _vertexIdx; 
    private double _coordX; 
    private double _coordY; 
    private double _coordZ; 

    public Vertex() 
    { } 

    public Vertex(int vertexIdx, double coordX, double coordY, double coordZ) 
    { 
     _vertexIdx = vertexIdx; 
     _coordX = coordX; 
     _coordY = coordY; 
     _coordZ = coordZ; 
    } 

    public int VertexIdx 
    { 
     get { return _vertexIdx; } 
     set { _vertexIdx = value; } 
    } 

    public double X 
    { 
     get { return _coordX; } 
     set { _coordX = value; } 
    } 

    public double Y 
    { 
     get { return _coordY; } 
     set { _coordY = value; } 
    } 

    public double Z 
    { 
     get { return _coordZ; } 
     set { _coordZ = value; } 
    } 
} 

Form_Load: (4 अंक बहुभुज के लिए हार्ड-कोडेड - किसी भी राशि के लिए किया जाना चाहिए: जब बटन दबाने की गणना करने के

List<Vertex> verticies = new List<Vertex>(); 

verticies.Add(new Vertex(1, 930.9729, 802.8789, 0)); 
verticies.Add(new Vertex(2, 941.5341, 805.662, 0)); 
verticies.Add(new Vertex(3, 946.5828, 799.271, 0)); 
verticies.Add(new Vertex(4, 932.6215, 797.0548, 0)); 

dataGridView1.DataSource = verticies;

कोड। ..)

 // X-coords 
     double x1; 
     double x2; 
     double x3; 
     double x4; 
     double x5; 

     // Y-coords 
     double y1; 
     double y2; 
     double y3; 
     double y4; 
     double y5; 

     // Xn * Yn++ 
     double x1y2; 
     double x2y3; 
     double x3y4; 
     double x4y5; 

     // Yn * Xn++ 
     double y1x2; 
     double y2x3; 
     double y3x4; 
     double y4x5; 

     // XnYn++ - YnXn++ 
     double x1y2my1x2; 
     double x2y3my2x3; 
     double x3y4my3x4; 
     double x4y5my4x5; 

     double result; 
     double area; 

     x1 = Convert.ToDouble(dataGridView1.Rows[0].Cells[1].Value.ToString()); 
     y1 = Convert.ToDouble(dataGridView1.Rows[0].Cells[2].Value.ToString()); 
     txtLog.Text += String.Format("X1 = {0}\tY1 = {1}\r\n", x1, y1); 

     x2 = Convert.ToDouble(dataGridView1.Rows[1].Cells[1].Value.ToString()); 
     y2 = Convert.ToDouble(dataGridView1.Rows[1].Cells[2].Value.ToString()); 
     txtLog.Text += String.Format("X2 = {0}\tY2 = {1}\r\n", x2, y2); 

     x3 = Convert.ToDouble(dataGridView1.Rows[2].Cells[1].Value.ToString()); 
     y3 = Convert.ToDouble(dataGridView1.Rows[2].Cells[2].Value.ToString()); 
     txtLog.Text += String.Format("X3 = {0}\tY3 = {1}\r\n", x3, y3); 

     x4 = Convert.ToDouble(dataGridView1.Rows[3].Cells[1].Value.ToString()); 
     y4 = Convert.ToDouble(dataGridView1.Rows[3].Cells[2].Value.ToString()); 
     txtLog.Text += String.Format("X4 = {0}\tY4 = {1}\r\n", x4, y4); 

     // add the start point again 
     x5 = Convert.ToDouble(dataGridView1.Rows[0].Cells[1].Value.ToString()); 
     y5 = Convert.ToDouble(dataGridView1.Rows[0].Cells[2].Value.ToString()); 
     txtLog.Text += String.Format("X5 = {0}\tY5 = {1}\r\n", x5, y5); 
     txtLog.Text += "\r\n"; 

     // Multiply 
     x1y2 = x1 * y2; 
     x2y3 = x2 * y3; 
     x3y4 = x3 * y4; 
     x4y5 = x4 * y5; 

     y1x2 = y1 * x2; 
     y2x3 = y2 * x3; 
     y3x4 = y3 * x4; 
     y4x5 = y4 * x5; 

     // Subtract from each other 
     x1y2my1x2 = x1y2 - y1x2; 
     x2y3my2x3 = x2y3 - y2x3; 
     x3y4my3x4 = x3y4 - y3x4; 
     x4y5my4x5 = x4y5 - y4x5; 

     // Sum all results 
     result = x1y2my1x2 + x2y3my2x3 + x3y4my3x4 + x4y5my4x5; 
     area = Math.Abs(result/2); 

     txtLog.Text += String.Format("Area = {0}\r\n", area); 

उदाहरण आउटपुट:

X1 = 930.9729 Y1 = 802,8789

X2 = 941.5341 Y2 = 805,662

X3 = 946.5828 Y3 = 799,271

X4 = 932.6215 Y4 = 797.0548

X5 = 930.9729 Y5 = 802.8789

012,

क्षेत्र = 83,2566504099523

+0

माइक्रोस्टेशन गणना का स्क्रीनशॉट = http://img15.imageshack.us/img15/6523/areaofpolygon.png – riaandelange

+0

बहुविकल्पीय में बहुभुज को विभाजित करने के लिए मैंने पहले देखा है कि एक सामान्य विधि है, तो आप बस क्षेत्र को जोड़ सकते हैं सभी त्रिकोणों का। हालांकि यह nontrivial है, क्योंकि यह बहुभुज (पार करने किनारों, छेद, उत्तल/अवतल, आदि) –

+0

की जटिलता आप http://mathoverflow.net/ पर इस सवाल पूछ रहे हैं, एक ढेर Overflow- पर विचार हो सकता के आधार पर अलग एल्गोरिदम की जरूरत है साइट की तरह, केवल गणित प्रश्नों के लिए, बस सुनिश्चित करें कि आप प्रश्न को गैर प्रोग्रामिंग के रूप में पेश करते हैं और इसके बजाय एल्गोरिदमिक दृष्टिकोण मांगते हैं। –

उत्तर

10

लैम्ब्डा अभिव्यक्तियों का उपयोग करके इस तुच्छ हो जाता है!

var points = GetSomePoints(); 

points.Add(points[0]); 
var area = Math.Abs(points.Take(points.Count - 1) 
    .Select((p, i) => (points[i + 1].X - p.X) * (points[i + 1].Y + p.Y)) 
    .Sum()/2); 

एल्गोरिथ्म here समझाया गया है।

+0

लिंक "स्पष्टीकरण" * एल्गोरिदम * समझा नहीं है। यह सिर्फ कोड को अलग-अलग प्रस्तुत करता है। –

3

कुछ है कि एक plain polygon के लिए की तरह (नोटपैड द्वारा संकलित):

static double GetDeterminant(double x1, double y1, double x2, double y2) 
{ 
    return x1 * y2 - x2 * y1; 
} 

static double GetArea(IList<Vertex> vertices) 
{ 
    if(vertices.Count < 3) 
    { 
     return 0; 
    } 
    double area = GetDeterminant(vertices[vertices.Count - 1].X, vertices[vertices.Count - 1].Y, vertices[0].X, vertices[0].Y); 
    for (int i = 1; i < vertices.Count; i++) 
    { 
     area += GetDeterminant(vertices[i - 1].X, vertices[i - 1].Y, vertices[i].X, vertices[i].Y); 
    } 
    return area/2; 
} 

हालांकि अपने दृष्टिकोण Z- अक्ष पर ध्यान देना नहीं है। इसलिए मैं कुछ परिवर्तन यह से छुटकारा पाने के लागू करने के लिए सलाह चाहते हैं: आप इस क्षेत्र प्राप्त करने में सक्षम नहीं हो सकता है अगर बहुभुज, विमान नहीं है जबकि अगर यह विमान है कि आप तीसरे आयाम से छुटकारा पाने में सक्षम हैं।

+0

हां, तो वहाँ क्षेत्र 2 डी और 3 डी में गणना के बीच एक diffrence है एक विदेशी भाषा की तरह लग रहा? – riaandelange

+0

हां, बस थोड़ा सा। क्षेत्र केवल सादा वस्तुओं के लिए गणना की जा सकती है। इसलिए आपका बहुभुज सादा होना चाहिए - इसके सभी शिखर एक ही मैदान में झूठ बोलना चाहिए, अन्यथा क्षेत्र की गणना नहीं की जा सकती है। समस्या यह है कि यह विमान आपके उदाहरण में हमेशा Z = 0 विमान नहीं होगा। क्षेत्र को गणना करने से पहले आपको इसे ध्यान में रखना चाहिए और अंक को उचित तरीके से संसाधित करना चाहिए। – Li0liQ

0
 double resultant = 0; 
     double area = 0; 
     int tel1 = 0; 
     int tel2 = 0; 

     x1y2lst.Clear(); 
     y1x2lst.Clear(); 
     x1y2lstMinusy1x2lst.Clear(); 

     // *******************************************************************************************// 
     // Calculate and populate X1 * Y2 in a list 

     for (int i = 0; i < dataGridView1.Rows.Count - 1; i++) 
     { 
      tel1++; 
      double x1x = Convert.ToDouble(dataGridView1.Rows[i].Cells[1].Value.ToString()); 
      double y2y = Convert.ToDouble(dataGridView1.Rows[i+1].Cells[2].Value.ToString()); 
      x1y2lst.Add(x1x * y2y); 
     } 
     // Calculate the last with the first value 
     double xLastx = Convert.ToDouble(dataGridView1.Rows[tel1].Cells[1].Value.ToString()); 
     double yFirsty = Convert.ToDouble(dataGridView1.Rows[0].Cells[2].Value.ToString()); 
     x1y2lst.Add(xLastx * yFirsty); 

     // *******************************************************************************************// 
     // Calculate and populate Y1 * X2 in a list 
     for (int i = 0; i < dataGridView1.Rows.Count - 1; i++) 
     { 
      tel2++; 
      double y1y = Convert.ToDouble(dataGridView1.Rows[i].Cells[2].Value.ToString()); 
      double x2x = Convert.ToDouble(dataGridView1.Rows[i + 1].Cells[1].Value.ToString()); 
      y1x2lst.Add(y1y * x2x); 
     } 
     // Calculate the last with the first value 
     double yLasty = Convert.ToDouble(dataGridView1.Rows[tel2].Cells[2].Value.ToString()); 
     double xFirstx = Convert.ToDouble(dataGridView1.Rows[0].Cells[1].Value.ToString()); 
     y1x2lst.Add(yLasty * xFirstx); 

     // Subract List1 values from List2 values 
     for (int k = 0; k < x1y2lst.Count; k++) 
     { 
      x1y2lstMinusy1x2lst.Add(x1y2lst[k] - y1x2lst[k]); 
     } 

     // Add all answers from previous to a result 
     for (int l = 0; l < x1y2lstMinusy1x2lst.Count; l++) 
     { 
      resultant += x1y2lstMinusy1x2lst[l]; 
     } 
     // Area = Result from steps above devided by 2 
     area = Math.Abs(resultant/2); 
     txtArea.Text = Math.Round(area, 4).ToString(); 
4
public float Area(List<PointF> vertices) 
{ 
    vertices.Add(vertices[0]); 
    return Math.Abs(vertices.Take(vertices.Count - 1).Select((p, i) => (p.X * vertices[i + 1].Y) - (p.Y * vertices[i + 1].X)).Sum()/2); 
} 
+1

कृपया अपने उत्तर को आसान बनाने के लिए कुछ स्पष्टीकरण प्रदान करें। – Carsten

संबंधित मुद्दे