Link to home
Start Free TrialLog in
Avatar of Tagyourareit
Tagyourareit

asked on

Problems with loop for/while

Hello experts,

I have a problem with a function in my code (see below)

 class Program
    {

        public static XDocument doc = null;
        public static string Dokument = "doc.xml";

        static void Main(string[] args)
        {
            DisplayXmlParsedObjects();
            Console.ReadLine();
        }


        public static List<Point> XmlParse()
        {

            doc = XDocument.Load(Dokument);

            var result = from c in doc.Descendants("HotSpot")
                         select new Point()
                         {
                             Id = (int)(c.Attribute("id")),
                             x = (float)c.Attribute("x"),
                             y = (float)c.Attribute("y"),
                             z = (float)c.Attribute("z")
                         };
            
          
            List<Point> ListResults = new List<Point>();

            foreach (var item in result)
            {
                ListResults.Add(new Point() { x = item.x, y = item.y, z = item.z, Id = item.Id });
            }

            ListResults.Add(new Point() { x = 666, y = 666, z = 666, Id = 0 });

            List<Point> SortedList = ListResults.OrderBy(o => o.Id).ToList();


            return SortedList;
        }

        public static void DisplayXmlParsedObjects()
        {
            List<Point> HotSpots = XmlParse();


                for (int i = 0; i <= HotSpots.Count - 2; i++)
                {
                    Point a = HotSpots[i];			//this is starting point coordinate
                    Point b = HotSpots[i + 1];		//this will store mid point coordinates
                    Point c = HotSpots[i + 1];		//this one will store end point coordinate

                    while (a.x != c.x && a.y != c.y && a.z != c.z)
                    {

                        if (CalcMidPoint(a, b))
                        {

                            //set mid coordinate as starting point coordinate! 
                            a.x = b.x;
                            a.y = b.y;
                            a.z = b.z;

                            //set static end point to point b
                            b.x = c.x;
                            b.y = c.y;
                            b.z = c.z;
                        }
                    }
            }  
         }

        public static bool CalcMidPoint( Point a,  Point b)
        {

            float distance = (float)Math.Sqrt(Math.Pow(b.x - a.x, 2) + Math.Pow(b.y - a.y, 2) + Math.Pow(b.z - a.z, 2));

            if (distance < 100)
            {
               
                Console.WriteLine("Final distance : " + distance + " ... on coord: X:" + b.x + "  Y:" + b.y + "  Z:" + b.z + "\r");
                return true;
            }
            else
            {

                b.x = (a.x + b.x) / 2;
                b.y = (a.y + b.y) / 2;
                b.z = (a.z + b.z) / 2;

           
                return CalcMidPoint( a,  b);
            }
        }
    }

    public class Point
    {
        public float x { get; set; }
        public float y { get; set; }
        public float z { get; set; }
        public int Id { get; set; }
    }

Open in new window


What i try to do is calculate distance between two points in 3D. If distance calculated in CalcMidPoint function is greater than 100 we need to add midpoint.

I am reading stored data from XML file  (see below)

<?xml version="1.0" encoding="utf-8"?>
<start>
	 <HotSpot id="1" x="10" y="10" z="10"/>
	 <HotSpot id="2" x="66326.78" y="-74404.68" z="-3172.191"/>
	 <HotSpot id="3" x="66220.13" y="-73542.97" z="-3286.478"/>
</start>

Open in new window


Now problem is in funtion DisplayXmlParsedObjects. For some reason it keeps breaking out of while loop after 1st itteration.
It should loop and call CalcMidPoint till it reaches point stored in List and then continue from that point to another.

And a bit explanatio on class Point.
In class point i am  storing coordinates and node Id.  Usually i am dealing with 3 points at once,
point a is starting point, point be is a variable like point where we store current mid point and point c is our "static" end point
 which shouldnt change till we reach next node in our Xml parser.
 
Any questions please let me know!

Thank you!
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

>>For some reason it keeps breaking out of while loop after 1st itteration.

What are the values in 'a' and 'c' after one iteration?
Avatar of Tagyourareit
Tagyourareit

ASKER

The values are as they suposed to be thats the main problem. If i do this for example:

public static void DisplayXmlParsedObjects()
        {
           
               
            Point a = new Point() { x = 666, y = 666, z = 666 };  
            Point b = new Point() { x = 10, y = 5, z = 1 };             
            Point c = new Point() { x = 10, y = 5, z = 1 };            

                    while (a.x != c.x && a.y != c.y && a.z != c.z)
                    {

                        if (CalcMidPoint(a, b))
                        {

                            //set mid coordinate as starting point coordinate! 
                            a.x = b.x;
                            a.y = b.y;
                            a.z = b.z;

                            //set static end point to point b
                            b.x = c.x;
                            b.y = c.y;
                            b.z = c.z;
                        }
            }  
         }

Open in new window


Code works fine.
OK.  Maybe I am misunderstanding something.
Your loop finishes when your termination condition is met and you're asking why isn't it working because the loop is finishing when I want it to?

Maybe step into the start of the loop and see just what is different between the real code and what you hard code in your second example.
Somehow loop overrides my value stored in Pont c ...  no clue where and how.
Hi Tagyourareit;

What happened to your if statement in your last post compared to the original post? Can you tell us how this function should work?

While I was looking through your code I made some changes to this section although it is not the source of your current issue.

        public static List<Point> XmlParse()
        {

            doc = XDocument.Load(Dokument);

            List<Point> result = (from c in doc.Descendants("HotSpot")
                                  orderby c.Attribute("id").Value
                                  select new Point()
                                  {
                                      Id = (int)(c.Attribute("id")),
                                      x = (float)c.Attribute("x"),
                                      y = (float)c.Attribute("y"),
                                      z = (float)c.Attribute("z")
                                  }).ToList();

            // The code I removed from here could be handled in the query as shown
            // above. Adding the new Point with id 0 which will be at the beginning
            // of the list can be done by Insert'ing it at index 0 as shown below.
            result.Insert(0, new Point() { x = 666, y = 666, z = 666, Id = 0 });

            return result;
        }

Open in new window

line 58 is
if (CalcMidPoint(a, b))

I'd put a breakpoint on that line and in the watch (locals) window see what is happening to the contents of a, b and c as you single step through the code.
@Fernando Soto:

Hey,

What funtion should do is. Rea results from List  into 3 sets of points in Point class.

points a,b,c ach with its own set of coordinates.

It will then go like this  .... basically we will be calculating distance between points. Let say distance between 2 points in 3d is maximum 100.  We will take point A as a start in point and we are heading to point B (in my case i am storing estination point in Point c). Now if distance between point A and B is more than 100 we will create a mid-point and we store it temporary in Point b. So now we are calculating distance between this newly created point to final destination point which is still stored in Point c.

Now before we start with another calculation we will move Point b to Point a and Point c in point b and restart calculation. Distance between nevely created point stored in Point a to final destination point stored in Pointc.

After we reach last point in our first XML node we will move to the second node using last node point as starting point and next node point as final destination point...

I hope i didnt calculate this to much ( learing c# by using some mathematica problems).
PS as i said this works

public static void DisplayXmlParsedObjects()
        {
           
               
            Point a = new Point() { x = 666, y = 666, z = 666 };  
            Point b = new Point() { x = 10, y = 5, z = 1 };             
            Point c = new Point() { x = 10, y = 5, z = 1 };            

                    while (a.x != c.x && a.y != c.y && a.z != c.z)
                    {

                        if (CalcMidPoint(a, b))
                        {

                            //set mid coordinate as starting point coordinate! 
                            a.x = b.x;
                            a.y = b.y;
                            a.z = b.z;

                            //set static end point to point b
                            b.x = c.x;
                            b.y = c.y;
                            b.z = c.z;
                        }
            }  
         }

Open in new window

Did you try my last suggestion yet?
@Tagyourareit;

You state that these values work,

            Point a = new Point() { x = 666, y = 666, z = 666 };  
            Point b = new Point() { x = 10, y = 5, z = 1 };            
            Point c = new Point() { x = 10, y = 5, z = 1 };            

But in the XML file you have three Point objects defined plus the one you added manually that have all 666 in each value of x, y, and z giving a total of four Point objects. So what happens to the forth object when you need three to do the calculations?
No you miss understood. You will ttake point from first node and then u calculate against second then u take second an calculate against third and so on ...
To repeat myself again:
>>Somehow loop overrides my value stored in Pont c ...  no clue where and how.

Have you followed my suggestion to track down what is happening where (and then very likely why it is being overwritten)?
Hi Tagyourareit;

Try and see if this modification I made to the beginning of the function gives you the correct values.

public static void DisplayXmlParsedObjects()
{
    List<Point> HotSpots = XmlParse();


    for (int i = 0; i <= HotSpots.Count - 3; ++i)
    {
        Point a = HotSpots[i];			//this is starting point coordinate
        Point b = HotSpots[i + 1];		//this will store mid point coordinates
        Point c = HotSpots[i + 2];		//this one will store end point coordinate

        while (a.x != c.x && a.y != c.y && a.z != c.z)
        {

            if (CalcMidPoint(a, b))
            {

                //set mid coordinate as starting point coordinate! 
                a.x = b.x;
                a.y = b.y;
                a.z = b.z;

                //set static end point to point b
                b.x = c.x;
                b.y = c.y;
                b.z = c.z;
            }
        }
    }
}

Open in new window

To repeat myself again:
>>Somehow loop overrides my value stored in Pont c ...  no clue where and how.

Have you followed my suggestion to track down what is happening where (and then very likely why it is being overwritten)?

I am sorry i have to miss ur comment. Yes i diid the debugging and i am overwritting my stored Point C value with calculated Point b value.


  }
            else
            {

                b.x = (a.x + b.x) / 2;
                b.y = (a.y + b.y) / 2;
                b.z = (a.z + b.z) / 2;
               //here c value is already overwritten .... 
             
                return CalcMidPoint( a,  b);
            }

Open in new window

I have no idea why does that happen.
@Fernando Soto: sorry we  didnt understand each other. I ll try to post more acurate descriptio a bit later.
Did you try my last post?
No that wont work.

I will try to explain it again.

Think of a let say 2 points.

A(x,y,z) ----------------------- B(x,y,z)

Now distance between those two points is greater than 100.

So you will have to calculate a mid-point between start point A and finish B that has distance less than 100.

We run trought loop  a couple of times till we find it.

A(x.y.z) ------------ C(x.y.z)------------------B(x.y.z)

Now distance between A and C is ess than 100 so we have to calculate again between point C and B.

If distance is less than 100 then we are finished with current set of coordinates if not we start calculating again ....

C is now new start and B end.

And so on till we get MID point = Finish point then we move to another node in XML.
Additionla explanation on code:

Thats why i use Point A,Point B, and Point C.

Point A allways holds coordinates of point we are heading from and Point C is out end point that will remain the same
whitin same xml node. Point b is the one i uuse for mid points and it changing all the time.
ASKER CERTIFIED SOLUTION
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
AndyAinscow 5 stars to you :)

This sočved my probem ... and thats why that hard coded solution worked so flawlessly i have created new object for eeach point.

Thank you again!