Results 1 to 8 of 8

Thread: >>> FindColorSector and other functions.... <<<

  1. #1
    Join Date
    Apr 2007
    Location
    Perth, Australia
    Posts
    3,926
    Mentioned
    3 Post(s)
    Quoted
    2 Post(s)

    Default >>> FindColorSector and other functions.... <<<

    Ok this I decide to make this function due to several reasons.

    First of all it was because when I was making my Rune Mysteries Runner I was looking for a function similar to FindColorCircle except it would only search a sector of the minimap between to angles and a radius (similar to RadialWalk).

    Second was because I was bored studying for my exams in the next two weeks and decided to make SCAR draw random shapes using polar equations.
    So I decided to combinded the two together and make a new function that would also prepare me for my exams.

    So I give you FindColorSectorEx. It gives you many parameters from which ou can make other FindColorSector functions. (ie. FindColorSectorTol, FindColorSectorPolar, FindColorSectorMinimap, etc.)

    SCAR Code:
    function FindColourSectorEx(var Sx, Sy, R, Theta: Integer; Colour, CentreX,
      CentreY, StartAngle, EndAngle, Radius, RStep, Tol: Integer; Outwards: Boolean): Boolean;
    var
      j, k, l, m, n, BMP, Handle: Integer;
      PP: Array of PPoint;
      TP: TPointArray;
      Temp: TColor;
    begin
      Sx := -1; Sy := -1; R := -1; Theta := -1;
      if (StartAngle = EndAngle) then
      begin
        Writeln('StartAngle and EndAngle cannot be the same.');
        Exit;
      end;
      l := 1;
      k := 1;
      if (Outwards) then l := 0
      else k := Radius;
      {Handle := GetClientWindowHandle;
      BMP := BitmapFromString(2 * Radius, 2 * Radius, '');
      CopyClientToBitmap(BMP, CentreX - Radius, CentreY - Radius, CentreX + Radius,
        CentreY + Radius);
      SetTargetBitmap(BMP);}

      repeat
        if (Outwards) then PP := CreatePPArray(l, StartAngle, EndAngle, 1)
        else PP := CreatePPArray(k, StartAngle, EndAngle, 1);
        TP := PolarToCart(PP, CentreX, CentreY);
        for j := 0 to Length(TP) - 1 do
        begin
          //MoveMouse(Tp[j].x, Tp[j].y);
          Temp := GetColor(TP[j].x, TP[j].y);
          //Temp := FastGetPixel(BMP, TP[j].x, TP[j].y);
          if (SimilarColors(Colour, Temp, Tol)) then
          begin
            Sx := TP[j].x;
            Sy := TP[j].y;
            if (CentreX < Sx) then
            begin
              m := 90;
              if (CentreY < Sy) then
                n := 1
              else n := -1;
            end else
            begin
              m := 270;
              if (CentreY < Sy) then
                n := -1
              else n := 1;
            end;
            Theta := m + n * Round(FixD(Degrees(ArcTan(Abs((CentreY - Sy) / (CentreX - Sx))))));
            R := Distance(Sx, Sy, CentreX, CentreY);
            {SetClientWindowHandle(Handle);
            FreeBitmap(BMP);}

            Result := True;
            Exit;
          end;
        end;
        if (Outwards) then l := l + RStep
        else k := k - RStep;
      until (l >= Radius) or (k <= 0);
      {SetClientWindowHandle(Handle);
      FreeBitmap(BMP);}

    end;

    To use it you need two other functions that create a PPoint array and then convert Polar coordinates to Cartesian:

    SCAR Code:
    function CreatePPArray(Rad, StartAng, EndAng, AngleStep: Integer): Array of PPoint;
    var
      j, l: Integer;
    begin
      if (StartAng > EndAng) then l := -1 else l := 1;
      for j := 0 to Round(Abs((EndAng - StartAng) / AngleStep)) do
      begin
        SetLength(Result, j + 1);
        Result[j].r := Rad;
        Result[j].t := StartAng + j * l * AngleStep;
      end;
    end;
    SCAR Code:
    function PolarToCart(PPointArray: Array of PPoint; CentX, CentY: Integer): TPointArray;
    var
      k: Integer;
    begin
      for k := 0 to Length(PPointArray) - 1 do
      begin
        SetLength(Result, k + 1);
        Result[k].x := Round(PPointArray[k].r * Cos(Radians(PPointArray[k].t - 90))) + CentX;
        Result[k].y := Round(PPointArray[k].r * Sin(Radians(PPointArray[k].t - 90))) + CentY;
      end;
    end;

    So for an explanation of the parameters for FindColorSectorEx:

    • Sx, Sy - X and Y coordinates of the point found first.
    • R, Theta - R is the radius and Theta is the angle from the positive Y axis of the point found.
    • Colour - The colour to be found.
    • CentreX, CentreY - The centre of the circle in which the function searches in.
    • StartAngle, EndAngle - Pretty self-explanatory (similar to RadialWalk).
    • Radius - Also pretty self-explanatory. (also similar to RadialWalk).
    • RStep - The number of pixels from the centre it adds or subtracts everytime it finishes searching the arc. The smaller the number (1,2) the more accurate but also the slower. The larger the number, the faster. (RadialWalk uses 4).
    • Tol - The tolerance of the colour being searched for.
    • Outwards - True if you want the function to search inside out. False for outside in (RadialWalk is outside in).


    As I was saying from this multi-purpose function you could create other functions ie:

    SCAR Code:
    function FindColorSectorMiniMap(var x, y: Integer; Colour, StartAngle, EndAngle,
      Radius, Tol: Integer): Boolean;
    var
      R, T: Integer;
    begin
      Result := FindColorSectorEx(x, y, R, T, Colour, 643, 84, StartAngle, EndAngle, Radius,
        3, Tol, True);
    end;

    or:

    SCAR Code:
    function FindColorSectorMMPolar(var R, T: Integer; Colour, StartAngle, EndAngle,
      Radius, Tol: Integer): Boolean;
    var
      x, y: Integer;
    begin
      Result := FindColorSectorEx(x, y, R, T, Colour, 643, 84, StartAngle, EndAngle,
        Radius, 3, Tol, True);
    end;

    I know this function is pretty slow. I'm trying to speed it up by using bitmaps and stuff (as you can see from my commented out stuff ) but I haven't succeeded. Maybe someone could advise me on how to get it to work.

    EDIT: Heres the modified function:

    SCAR Code:
    function FindColorSectorEx2(var Sx, Sy, R, Theta: Integer; Colour, CentreX,
      CentreY, StartAngle, EndAngle, Radius, Tol: Integer; Outwards: Boolean): Boolean;
    var
      TempTP: TPointArray;
      TempPP, TempPts: Array of PPoint;
      cx1, cy1, cx2, cy2, i, j, a, Max, MaxNum, m, n: Integer;
    begin
      if (StartAngle > EndAngle) then
      begin
        a := StartAngle;
        StartAngle := EndAngle;
        EndAngle := a;
      end;
      Sx := -1; Sy := -1; R := -1; Theta := -1; j := 0;
      cx1 := CentreX - Radius; cy1 := CentreY - Radius;
      cx2 := CentreX + Radius; cy2 := CentreY + Radius;
      if (cx1 < 0) then cx1 := 0; if (cy1 < 0) then cy1 := 0;
      FindColorsTolerance(TempTP, Colour, cx1, cy1, cx2, cy2, Tol);
      if (Length(TempTP) = 0) then Exit;
      for i := 0 to Length(TempTp) - 1 do
      begin
        SetLength(TempPP, i + 1);
        if(CentreX < TempTP[i].x) then
        begin
          m := 90;
          if (CentreY < TempTP[i].y) then
            n := 1
          else n := -1;
        end else
        begin
          m := 270;
          if (CentreY < TempTP[i].y) then
            n := -1
          else n := 1;
        end;
        TempPP[i].r := Distance(TempTP[i].x, TempTP[i].y, CentreX, CentreY);
        TempPP[i].t := m + n * Round(FixD(Degrees(ArcTan(Abs((CentreY - Sy) / (CentreX - Sx))))));
      end;
      for i := 0 to Length(TempPP) - 1 do
      begin
        if (TempPP[i].r <= Radius) then
          if (TempPP[i].t >= StartAngle) then
            if (TempPP[i].t <= EndAngle) then
            begin
              SetLength(TempPts, j + 1);
              TempPts[j].r := TempPP[i].r;
              TempPts[j].t := TempPP[i].t;
              j := j + 1;
            end;
      end;
      if (Length(TempPts) = 0) then Exit;
      if (Outwards) then Max := Radius
      else Max := 0;
      for i := 0 to Length(TempPts) - 1 do
      begin
        if (Outwards) then
        begin;
          if (Round(TempPts[i].r) <= Max) then
          begin
            Max := Round(TempPts[i].r);
            MaxNum := i;
          end;
        end else
        begin
          if (Round(TempPts[i].r) >= Max) then
          begin
            Max := Round(TempPts[i].r);
            MaxNum := i;
          end;
        end;
      end;
      Sx := Round(TempPts[MaxNum].r * Cos(Radians(TempPts[MaxNum].t - 90))) + CentreX;
      Sy := Round(TempPts[MaxNum].r * Sin(Radians(TempPts[MaxNum].t - 90))) + CentreY;
      R := Round(TempPts[MaxNum].r);
      Theta := Round(TempPts[MaxNum].t);
      Result := True;
    end;

    Its parameters are the same except I've removed RStep.

  2. #2
    Join Date
    Feb 2006
    Location
    Amsterdam
    Posts
    13,692
    Mentioned
    146 Post(s)
    Quoted
    130 Post(s)

    Default

    You can speed it up by first using a FindColorsTolerance, then take out points in that TPA that are not in the degrees and distance. Then sort it by distance.



    The best way to contact me is by email, which you can find on my website: http://wizzup.org
    I also get email notifications of private messages, though.

    Simba (on Twitter | Group on Villavu | Website | Stable/Unstable releases
    Documentation | Source | Simba Bug Tracker on Github and Villavu )


    My (Blog | Website)

  3. #3
    Join Date
    Dec 2006
    Location
    Copy pastin to my C#
    Posts
    3,788
    Mentioned
    8 Post(s)
    Quoted
    29 Post(s)

    Default

    That looks pretty nice!

    Rofl, Wizzy is viewing, prepare for shortened version, or a thousand lines long uberturboleet code lol...

    Btw, if you want ever to do it in a less leet way, just do a FindColors and then a for loop, and have a function that checks if a coord is in a sector (Yes wizzup I remember InDegreeEx) and then sort the ones that were in a new TPA

    EDIT: -.- Wizzy....

    EDIT EDIT:

    Then sort it by distance.
    Okay, I escape the situation by mentioning wizzy's SortTPAFrom

  4. #4
    Join Date
    Dec 2006
    Location
    Banville
    Posts
    3,914
    Mentioned
    12 Post(s)
    Quoted
    98 Post(s)

    Default

    Fuck! I got my ass kicked!


    Ok. I'm of to learn Trig now.
    The jealous temper of mankind, ever more disposed to censure than
    to praise the work of others, has constantly made the pursuit of new
    methods and systems no less perilous than the search after unknown
    lands and seas.

  5. #5
    Join Date
    May 2006
    Location
    Qld, Australia
    Posts
    223
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    RadialWalkEx?

    Also;
    Why Theta if you have an end angle?
    Haven't scripted in a while, Willing to proofread, test and provide feedback.

  6. #6
    Join Date
    Apr 2007
    Location
    Perth, Australia
    Posts
    3,926
    Mentioned
    3 Post(s)
    Quoted
    2 Post(s)

    Default

    Quote Originally Posted by Wizzup? View Post
    You can speed it up by first using a FindColorsTolerance, then take out points in that TPA that are not in the degrees and distance. Then sort it by distance.
    I suppose that would be better. Thanks for the advise.

    Quote Originally Posted by Kevin Wolf View Post
    RadialWalkEx?

    Also;
    Why Theta if you have an end angle?
    Theta is the variable in which it saves the angle of the point its found. EndAngle is just the end of the search area.

    EDIT: Modified the function using Wizzup?'s idea. It now works a bit faster.

  7. #7
    Join Date
    May 2006
    Location
    Qld, Australia
    Posts
    223
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Ah, Very nice;
    I can't deny I haven't wish for more hmm "Indepth"? procedure,
    Ones which return more stuff xP
    Haven't scripted in a while, Willing to proofread, test and provide feedback.

  8. #8
    Join Date
    Apr 2007
    Location
    Perth, Australia
    Posts
    3,926
    Mentioned
    3 Post(s)
    Quoted
    2 Post(s)

    Default

    Quote Originally Posted by Kevin Wolf View Post
    Ah, Very nice;
    I can't deny I haven't wish for more hmm "Indepth"? procedure,
    Ones which return more stuff xP
    Yes that was one of the reasons why I made this function. BTW Wizzup?, since your method works so much better, maybe you could alter RadialWalk or make a FastRadialWalk or something.

    @R0b0t, Good luck... G & T (Geometry and Trigonometry) is the most advance maths course available for my year at school.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Some functions...
    By Negaal in forum Research & Development Lounge
    Replies: 11
    Last Post: 02-16-2008, 12:29 PM
  2. Functions
    By lordsaturn in forum OSR Help
    Replies: 1
    Last Post: 08-13-2007, 10:12 PM
  3. Help with some functions
    By Pinqvin in forum OSR Help
    Replies: 6
    Last Post: 03-06-2007, 01:34 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •