There is an algorithm, it reads a point in a circle, on the outer / inner border or on the figure inside the circle. But faced with such a problem, it does not correctly display information about falling on the inner border of a figure that is inside a circle. For example, if you specify a coordinate (-14; 0) it will output a "точка на внутренней границе" and if for example you specify a coordinate (0; 3) , which also falls on the border, it will simply output a "точка входит область" . I can not understand where I made a mistake, please tell me how to fix it? The picture of the circle (in red it shows the coordinates (height and width of this small figure)):

enter image description here

 if (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]>=0) or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]<=-14)or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]<=0) and (y[i]<=round(-b/2)) or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]<=0) and (y[i]>=round(b/2)) then t:=t+1; if (x[i]*x[i]+y[i]*y[i]>r*r) then begin TextOut(65, f, ' - точка за границей области'); f:=f+16; end else if (x[i]*x[i]+y[i]*y[i]=r*r) then begin TextOut(65, f, ' - точка на внешеней границе'); f:=f+16; end else if (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]>=0) or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]<-14) or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]<=0) and (y[i]<round(-b/2)) or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]<=0) and (y[i]>round(b/2)) then begin TextOut(65, f, '- точка входит область'); f:=f+16; end else if ((x[i]=0) and (y[i]<15) and (y[i]=15)) or ((x[i]=-14) and (y[i]<15) and (y[i]>-15)) or ((y[i]=15) and (x[i]<0) and (x[i]>-14)) or ((y[i]=-15) and (x[i]<0) and (x[i]>-14)) then begin TextOut(65, f, ' - точка на внутренней границе'); f:=f+16; end else begin TextOut(65, f, ' - точка во внутренней фигуре'); f:=f+16; end end; 
  • one
    y[i]=15 instead of y[i]>-15 - is this a typo in the question or in the code? .. this problem does not apply, but you should not compare floating-point numbers (if here they are) for equality ... - Fat-Zer
  • @ Fat-Zer, I checked a typo, there y[i]>-15 . But this did not affect the situation, all the same, when a point hits the OU axis, it does not show that it is a boundary. Initially, this block should be like this (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]>=0) or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]=-14) or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]<=0) and (y[i]=round(-b/2)) or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]<=0) and (y[i]=round(b/2)) - Mr.Flatman

2 answers 2

So, I formulate the condition of the problem. On a coordinate axis with a center at the point (0, 0) circle of radius R specified. Inside the circle is a rectangle with the coordinates of the diagonal Rect = ((Left, Top), (Right, Bottom)) . It is required for the point (x, y) determine the belonging of one of the following zones

  • Outside the circle
  • On the circle
  • Inside the circle
  • On the border of the rectangle
  • Inside rectangle

Decision:

 type TZone = (zOut, zCircle, zCircleIn, zRect, zRectInt); TZoneSegment = (zsOut, zsBorder, zsIn); // Проверка принадлежности точки отрезку function TestSegment(const APoint, AFrom, ATo: Double): TZoneSegment; begin if SameValue(APoint, AFrom) or SameValue(APoint, ATo) then Result := zsBorder else if (APoint > AFrom) and (APoint < ATo) then Result := zsIn else Result := zsOut; end; function TestZone(const APoint: TPoint; const ARadius: Double; const ARect: TRect): TZone; var LRadiusVector: Double; LXSegment, LYSegment: TZoneSegment; begin LRadiusVector := Sqrt(Sqr(APoint.X) + Sqr(APoint.Y)); if SameValue(LRadiusVector, ARadius) then Result := zCircle else if LRadiusVector > ARadius then Result := zOut else begin LXSegment := TestSegment(APoint.X, ARect.Left, ARect.Right); LYSegment := TestSegment(APoint.Y, ARect.Top, ARect.Bottom); // Если точка лежит внутри каждого отрезка сторон if (LXSegment = zsIn) and (LYSegment = zsIn) then Result := zRectIn // то она лежит внутри прямоугольника // Если точка лежит снаружи хотя бы одного отрезка сторон else if (LXSegment = zsOut) or (LYSegment = zsOut) then Result := zCircleIn // то она лежит внутри прямоугольника else Result := zRect; // Точка лежит внутри одной стороны и на границе другой end; end; 

    The condition (x[i]=0) and (y[i]<15) and (y[i]=15) is incorrect, it never holds. Apparently, a typo

    • I checked, so I wrote. Initially, this block should be like this (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]>=0) or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]=-14) or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]<=0) and (y[i]=round(-b/2)) or (x[i]*x[i]+y[i]*y[i]<=r*r) and (x[i]<=0) and (y[i]=round(b/2)) - Mr.Flatman