Page 1 of 1

How to know which hatch/CurvePolygon an entity belong to?

Posted: 11 Jul 2016, 14:24
by sen
Hi Mikhail,

How to know which hatch/CurvePolygon an entity belong to (Covering to)?

I try loop using entity.box.center and CurvePolygon.boundaries properties but it's seem they each have difffrent coordinate measurement. Although in the PictureBox the entity is inside the Hatch/CurvePolygon but the coordinate is different

Code: Select all

//eAREA_List = all CurvePolygon entities in cadImage
//cUnit = entity text need to test inside/outside the CurvePolygon 

            foreach (var item in eAREA_List)
            {
                    bool lInside = false;
                    if (item.ThisHatch_CP.Boundaries.Count > 0)
                    {
                        for (int i = 0; i < item.ThisHatch_CP.Boundaries.Count; i++)
                        {
                            PointF[] b1 = new PointF[item.ThisHatch_CP.Boundaries[i].Count + 1];
                            for (int j = 0; j < item.ThisHatch_CP.Boundaries[i].Count; j++)
                            {
                                DPoint rp = GetRealPointNode(new DPoint(item.ThisHatch_CP.Boundaries[i][j].X, item.ThisHatch_CP.Boundaries[i][j].Y, 0));

                                float X = float.Parse(rp.X.ToString());
                                float Y = float.Parse(rp.Y.ToString());
                                b1[j] = new PointF(X, Y);

                            }
                            //add close circle
                            DPoint rp0 = GetRealPointNode(new DPoint(item.ThisHatch_CP.Boundaries[i][0].X, item.ThisHatch_CP.Boundaries[i][0].Y, 0));
                            float XX = float.Parse(rp0.X.ToString());
                            float YY = float.Parse(rp0.Y.ToString());

                            b1[item.ThisHatch_CP.Boundaries[i].Count] = new PointF(XX, YY);
                            if (PointInPolygon(b1, float.Parse(item.CenterPointX.ToString()), float.Parse(item.CenterPointY.ToString())))
                            {
                                lInside = true;
                                break;
                            }
                    }
I download the PointInPolygon from another source in the web, it's should be right.

Code: Select all


        // Return True if the point is in the polygon.
        #region IS INSIDE POLYGON
        public bool PointInPolygon(PointF[] Points, float X, float Y)
        {
            // Get the angle between the point and the
            // first and last vertices.
            int max_point = Points.Length - 1;
            float total_angle = GetAngle(
                Points[max_point].X, Points[max_point].Y,
                X, Y,
                Points[0].X, Points[0].Y);

            // Add the angles from the point
            // to each other pair of vertices.
            for (int i = 0; i < max_point; i++)
            {
                total_angle += GetAngle(
                    Points[i].X, Points[i].Y,
                    X, Y,
                    Points[i + 1].X, Points[i + 1].Y);
            }

            // The total angle should be 2 * PI or -2 * PI if
            // the point is in the polygon and close to zero
            // if the point is outside the polygon.
            return (Math.Abs(total_angle) > 0.000001);
        }


        public static float GetAngle(float Ax, float Ay,
    float Bx, float By, float Cx, float Cy)
        {
            // Get the dot product.
            float dot_product = DotProduct(Ax, Ay, Bx, By, Cx, Cy);

            // Get the cross product.
            float cross_product = CrossProductLength(Ax, Ay, Bx, By, Cx, Cy);

            // Calculate the angle.
            return (float)Math.Atan2(cross_product, dot_product);
        }


        private static float DotProduct(float Ax, float Ay,
    float Bx, float By, float Cx, float Cy)
        {
            // Get the vectors' coordinates.
            float BAx = Ax - Bx;
            float BAy = Ay - By;
            float BCx = Cx - Bx;
            float BCy = Cy - By;

            // Calculate the dot product.
            return (BAx * BCx + BAy * BCy);
        }


        public static float CrossProductLength(float Ax, float Ay,
    float Bx, float By, float Cx, float Cy)
        {
            // Get the vectors' coordinates.
            float BAx = Ax - Bx;
            float BAy = Ay - By;
            float BCx = Cx - Bx;
            float BCy = Cy - By;

            // Calculate the Z coordinate of the cross product.
            return (BAx * BCy - BAy * BCx);
        }


some help please


Thank in advance
Sen

Re: How to know which hatch/CurvePolygon an entity belong to

Posted: 11 Jul 2016, 18:21
by support
Hello Sen,

Your code snippet is not quite clear, please try to make it compilable like the PointInPolygon() routine. In particular, it is not clear what the following properties/methods do:

Code: Select all

item.ThisHatch_CP

Code: Select all

item.CenterPointX
item.CenterPointY

Code: Select all

GetRealPointNode()
Mikhail

Re: How to know which hatch/CurvePolygon an entity belong to

Posted: 12 Jul 2016, 07:34
by sen
Hi Mikhail,

For item.ThisHatch_CP its from CurvePolygon entity from iterate loop, I modify the ImportDemo examples adding ImportCurvePolygonXML.

Code: Select all

        private void ImportCurvePolygonXML(CADCurvePolygon CurvePolygon)
        {
            if (CurvePolygon.Layer.Color ==CurvePolygon.Color )
            {
                na.Color_ByLayer = true;
                na.Color_Layer_Name = CurvePolygon.Layer.Name;
                na.Color_LayerArea_Color = CurvePolygon.Layer.Color;
            }
            else
            {
                na.Color_ByLayer = false;
                na.Color_Layer_Name = "N/A";
                na.Color_LayerArea_Color = CurvePolygon.Color;
            }
            na.ThisHatch_CP = CurvePolygon;
            DPoint rp = GetRealPointNode(CurvePolygon.Box.Center);            
            na.CenterPointX = rp.X;
            na.CenterPointY = rp.Y;
            eAREA_List.Add(na);
        }

For item.CenterPointX and item.CenterPointY, it comes from Box.Center.X dan Box.Center.Y after I pass it to GetRealPointNode(), I modify from ImportDemo too.

Code: Select all

        private void ImportTextXML(CADText text)
        {
            DPoint rp = GetRealPointNode(text.StartPoint);
            nt.StartPointX = rp.X;
            nt.StartPointY = rp.Y;
            nt.StartPointZ = rp.Z;

            DPoint cp = GetRealPointNode(text.Box.Center);
            nt.CenterPointX = cp.X;
            nt.CenterPointY= cp.Y;

            nt.Text = text.Text;
            nt.pointf = new PointF(float.Parse(rp.X.ToString()), float.Parse(rp.Y.ToString()));
            eTEXT_List.Add(nt);
        }
the GetRealPointNode from ImportDemo too , this one I do not made any modification.

Code: Select all

        private DPoint GetRealPointNode(DPoint val)
        {
            return cadParams.matrix.PtXMat(val);
        }

So, first all entity from iterate

Code: Select all

          image.Converter.Iterate(new CADEntityProc(ReadCADEntitiesParamsToXML), null, cadParams);
Modifiy ReadCADEntitiesParamsToXML method,

Code: Select all

 
        private bool ReadCADEntitiesParamsToXML(CADEntity entity)
        {
            string sClassName;
            string sEntityName;
            string sColor;
            string sLayer;
           
            string str = CADImport.FaceModule.CADImportFace.SetName(entity);
            Color cl;
            double val;
            nodeEntity = doc.CreateElement("Entity");
            attr = doc.CreateAttribute("ClassName");
            attr.Value = string.Format("CADImport.CAD{0}", str);
            nodeEntity.Attributes.Append(attr);
            sClassName = attr.Value;

            attr = doc.CreateAttribute("EntityName");
            attr.Value = str;
            nodeEntity.Attributes.Append(attr);
            sEntityName = attr.Value;

            cl = CADConst.EntColor(entity, cadParams.insert);
            attr = doc.CreateAttribute("Color");
            attr.Value = ApplicationConstants.GetColor(cl);
            nodeEntity.Attributes.Append(attr);
            sColor = attr.Value;

            attr = doc.CreateAttribute("LineWeight");
            val = CADConst.EntLineWeight(entity, cadParams.insert);
            if (val == 0)
                val = image.NullWidth;
            attr.Value = val.ToString();
            nodeEntity.Attributes.Append(attr);
            CADConst.DoScale2D(ref cadParams);		// calculates 2d scale and rotation
            CADLayer layer = CADConst.EntLayer(entity, cadParams.insert);
            
            nodeParam = doc.CreateElement("Layer");
            str = "0";
            cl = CADConst.clNone;
            if (layer != null)
            {
                str = layer.Name;
                cl = layer.Color;
            }
            attr = doc.CreateAttribute("Name");
            attr.Value = str;
            nodeParam.Attributes.Append(attr);
            sLayer = attr.Value;

            attr = doc.CreateAttribute("Color");
            attr.Value = ApplicationConstants.GetColor(cl);
            nodeParam.Attributes.Append(attr);
            nodeEntity.AppendChild(nodeParam);


            

            switch (entity.EntType)
            {
                case EntityType.Text:
                        ID_TEXT += 1;
                        nt = new ViewerDemo.eTEXT();
                        nt.ID = ID_TEXT;
                        nt.ClassName = sClassName;
                        nt.EntityName = sEntityName;
                        nt.Color = sColor;
                        nt.Layer = sLayer;
                        ImportTextXML(entity as CADText);
                    break;
                case EntityType.Hatch:
                        ID_HATCH += 1;
                        nhatch = new ViewerDemo.eHATCH();
                        nhatch.ID = ID_HATCH;
                        nhatch.ClassName = sClassName;
                        nhatch.EntityName = sEntityName;
                        nhatch.Color = sColor;
                        nhatch.Layer = sLayer;
                    ImportHatchXML(entity as CADHatch);
                    break;
                case EntityType.Layer:
                    ID_LAYER += 1;
                    nlayer = new ViewerDemo.eLAYER();
                    nlayer.ID = ID_LAYER;
                    nlayer.ClassName = sClassName;
                    nlayer.EntityName = sEntityName;
                    nlayer.Color = sColor;
                    nlayer.Layer = sLayer;
                    ImportLayerXML(entity as CADLayer);
                    break;
                case EntityType.CurvePolygon:
                    ID_AREA += 1;
                    na = new ViewerDemo.eAREA();
                    na.ID = ID_AREA;
                    na.ClassName = sClassName;
                    na.EntityName = sEntityName;
                    na.Color = sColor;
                    na.Layer = sLayer;
                    ImportCurvePolygonXML(entity as CADCurvePolygon);
                    break;
            }
            return true;
        }
and loop each entity found previously against area (CurvePolygon)

Code: Select all

            List<ViewerDemo.eTEXT> list_Unit = new List<eTEXT>();
            var lu1 = eTEXT_List.FindAll(x => x.Text.ToUpper().TrimStart().StartsWith("GF"));
            list_Unit.AddRange(lu1);

Code: Select all

       foreach (var item in list_Unit)
            {
                ViewerDemo.List_UNIT_AREA mUA = new ViewerDemo.List_UNIT_AREA();
                mUA.ID_UNIT = item.ID;
                mUA.eUNIT_LAYER = item.Layer;
                mUA.eUNIT_TEXT = item.Text;
                mUA.StartPointX = item.StartPointX;
                mUA.StartPointY = item.StartPointY;
                mUA.CenterPointX = item.CenterPointX;
                mUA.CenterPointY = item.CenterPointY;
                                
                eAREA eAreaID = GetNearest_AreaID(item);

                mUA.ID_AREA = eAreaID.ID;
                mUA.eAREA_LAYER = eAreaID.Layer;
                List_Unit_Area.Add(mUA);
            }

First I try using nearest Center.X and Center.Y but did not success, so I try to check whether the entity (ie:text) is inside the CurvePolygon boundaries.

Code: Select all

        public eAREA GetNearest_AreaID(eTEXT cUnit)
        {
            eAREA ccp_area;
            double last_pos_from_unit_label = 0;
            int last_ID = 0;
            bool first = true;                     
            foreach (var item in eAREA_List)
            {
                    double posx = cUnit.CenterPointX - item.CenterPointX;
                    double posy = cUnit.CenterPointY - item.CenterPointY;

                    if (CalLayer.Contains(item.Layer))
	                {		
                        bool lInside = false;
                        if (item.ThisHatch_CP.Boundaries.Count>0)
	                    {
		                    for (int i = 0; i < item.ThisHatch_CP.Boundaries.Count; i++)
			                {
                                PointF[] b1 = new PointF[item.ThisHatch_CP.Boundaries[i].Count+1] ;     
		                        for (int j = 0; j < item.ThisHatch_CP.Boundaries[i].Count; j++)
			                    {
                                    DPoint rp = GetRealPointNode(new DPoint(item.ThisHatch_CP.Boundaries[i][j].X, item.ThisHatch_CP.Boundaries[i][j].Y,0));

                                    float X = float.Parse(rp.X.ToString());
                                    float Y = float.Parse(rp.Y.ToString());
                                    b1[j] = new PointF(X,Y);

  			                    }	
                                //add close circle
                                DPoint rp0 = GetRealPointNode(new DPoint(item.ThisHatch_CP.Boundaries[i][0].X, item.ThisHatch_CP.Boundaries[i][0].Y, 0));
                                float XX = float.Parse(rp0.X.ToString());
                                float YY = float.Parse(rp0.Y.ToString());

                                b1[item.ThisHatch_CP.Boundaries[i].Count] = new PointF(XX, YY);

                                if (PointInPolygon(b1, float.Parse(cUnit.CenterPointX.ToString()), float.Parse(cUnit.CenterPointY.ToString())))
                                {
                                    lInside = true;
                                    break;
                                }			                		 
			                }
	                    }

                        if (lInside)
                        {
                            last_ID = item.ID;
                            break;
                        }
                        else
                        {
                            if ((last_pos_from_unit_label > Math.Sqrt(Math.Pow(posx, 2) + Math.Pow(posy, 2)) || first)
                               )
                            {
                                last_pos_from_unit_label = Math.Sqrt(Math.Pow(posx, 2) + Math.Pow(posy, 2));
                                last_ID = item.ID;
                                first = false;
                            } 
                        }

                    }
            }
            ccp_area = eAREA_List.Where(x => x.ID == last_ID).First();
            return ccp_area;
        }

Thank in advance
Sen

Re: How to know which hatch/CurvePolygon an entity belong to

Posted: 12 Jul 2016, 13:12
by sen
Its seem the culprit is in

Code: Select all

        private DPoint GetRealPointNode(DPoint val)
        {            
            return cadParams.matrix.PtXMat(val);
        }
While entity from text, I pass the Box.Center.X and Box.Center.Y to the GetRealPointNode function the result DPoint value is different from the original.

But when I pass each CurvePolygon.Boundaries[j].X and CurvePolygon.Boundaries[j].Y the result DPoint values is the same like the original values.

IF I do not pass both the text entity and CurvePolygon.Boundaries to the GetRealPointNode function still the coordinate position between these two is diffrent.

I dont really understand how the scale/measurement between each entity works. How to get global coordinate for each/every entites ?

Thank in advance
Sen

Re: How to know which hatch/CurvePolygon an entity belong to

Posted: 13 Jul 2016, 20:50
by support
Hello Sen,

You should pay attention to cadParams.matrix value which defines a coordinate transformation matrix. You might notice that the matrix data is changed on each iteration, this fact explains the difference in values returned by a CADMatrix.PtXMat method for different entities, because this method multiplies a DPoint value by the matrix.

In case the DPoint coordinates are not transformed after invoking the CADMatrix.PtXMat method, it means that multiplying by the identity matrix took place. As you may know, multiplying by the identity matrix doesn't change anything, just like multiplying a number by 1 doesn't change anything.

As for the difference between coordinates of CADCurvePolygon boundary points and CADText.Box.Center, the boundary points (CAD2DPoint) have the absolute (global) coordinates, while the coordinates of the box center point are relative to the base point of this CADText. To get the global coordinates of CADText.Box.Center, you should pass it to the GetRealPointNode function:

Code: Select all

if (item.EntType == EntityType.Text)
{
    CADText text = item as CADText;
    DPoint rp = GetRealPointNode(text.Box.Center);
}
Mikhail

Re: How to know which hatch/CurvePolygon an entity belong to

Posted: 14 Jul 2016, 06:28
by sen
Hi Mikhail,

The coordinate text.box.center is converted using GetRealPointNote meanwhile the CurvePolygon not necessary since its already global.

I believed I have follow all your instruction but still got wrong coordinate

text.box.center (after convert using GetRealPointNote )
  • 3783860.25 -2003823.75
and the CurvePolygon.Boundaries
  • -137532.6 187591.9
    -106111.4 192762.5
    -106111.4 192762.5
    -72832.56 192762.5
    -72832.56 192762.5
    -72832.55 178412.5
    -72832.55 178412.5
    -63361.02 178412.5
    -63361.02 178412.5
    -63361.02 168412.5
    -63361.02 168412.5
    -71182.55 168412.5
    -71182.55 168412.5
    -71182.55 160062.5
    -71182.55 160062.5
    -70832.55 160062.5
    -70832.55 160062.5
    -70832.55 112412.5
    -70832.55 112412.5
    -137532.6 112397.6
    -137532.6 112397.6
    -137532.6 187591.9
    -137532.6 187591.9
I'd send the modified Import Examples and the DWG v2010 files to support, Would you please check where is the issue, do I made mistake or miss some step or something else.


Thank in advance
Sen

Re: How to know which hatch/CurvePolygon an entity belong to

Posted: 19 Jul 2016, 21:38
by support
Hello Sen,

The boundary points have absolute coordinates until a corresponding CADCurvePolygon object is inside a block, in this case the coordinates will be relative to this block. I'm currently searching a way to transform the relative coordinates inside blocks to the absolute coordinates. Don't worry, I will keep you posted about my investigation.


Mikhail

Re: How to know which hatch/CurvePolygon an entity belong to

Posted: 20 Jul 2016, 04:59
by sen
Thank you waiting for your investigation.


TIA
Sen

Re: How to know which hatch/CurvePolygon an entity belong to

Posted: 21 Jul 2016, 15:01
by support
Hello Sen,

To obtain the absolute coordinates for entities inside in a block, you should add the block insertion point coordinates and coordinates relative to the given block. When using CADConverter.Iterate method to iterate through the entities, cadParams.insert.Point returns the insertion point for a block which contains the currently iterated entity. If the iterated entity is not in a block, cadParams.insert will be null. Given the above said and your code snippets, a code for calculating the absolute coordinates of the hatch boundaries inside a block will be the following:

Code: Select all

float X, Y;
...

if (cadParams.insert != null)
{
    X = (float)(cadParams.insert.Point.X + item.ThisHatch_CP.Boundaries[i][j].X);
    Y = (float)(cadParams.insert.Point.Y + item.ThisHatch_CP.Boundaries[i][j].Y);
}
else
{
    X = (float)(item.ThisHatch_CP.Boundaries[i][j].X);
    Y = (float)(item.ThisHatch_CP.Boundaries[i][j].Y);
}
Mikhail

Re: How to know which hatch/CurvePolygon an entity belong to

Posted: 22 Jul 2016, 06:54
by sen
Ok thank a lot , I will implemented it in our test project and inform you the result

Thank again
Sen

Re: How to know which hatch/CurvePolygon an entity belong to

Posted: 22 Jul 2016, 08:04
by sen
Hi Mikhail,

it works perfectly

Thank
Sen