Results 1 to 8 of 8

Thread: Can anyone help to rewrite this C++ code to Delphi?

  1. #1

    Can anyone help to rewrite this C++ code to Delphi?

    Hello can you help to rewrite this C++ code to Delphi? It's Convex Hull. Yet I am working with old Delphi 7 so does this Delphi version even support vectors? Or how to go around vectors? I never used vectors in Delphi till now. I worked mostly with TStringLists or maybe some arrays. The C++ is very high level and yet this algo was taken from a tutorial, modified by another C++ expert (because I use C++98 on my old OS). Any help approciated.

    I am working on a free program to help free-time mappers to map some areas which are not present in OpenStreetMap data. This includes taking part of map been already rendered and then analyze selected area and to find polygon edges. After that the Convex Hull should be run to get rid of redundant coordinates.

    Code:
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <stdbool.h>
    
    #include <set>
    
    #include <float.h>      // DBL_MAX
    #include <vector>
    #include <algorithm>
    #include <typeinfo>
    
    #include <cstdlib> // rand()
    using namespace std;
    #include<ctime> // time()
    
    struct Point {
        double x, y;
    };
    bool compare(Point a, Point b)
    {
        return a.x < b.x || (a.x == b.x && a.y < b.y);
    }
    //Returns positive value if B lies to the left of OA, negative if B lies to the right of OA, 0 if collinear
    double cross(const Point& O, const Point& A, const Point& B)
    {
        return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x);
    }
    
    //Returns a list of points on the convex hull
    
    std::vector<Point> convex_hull(std::vector<Point> P)
    {
        int n = P.size(), k = 0;
        std::vector<Point> H(2 * n);
        std::sort(P.begin(), P.end(), compare);
        // Build lower hull
        for (int i = 0; i < n; ++i) {
            while (k >= 2 && cross(H[k - 2], H[k - 1], P[i]) <= 0) k--;
            H[k++] = P[i];
        }
    
        // Build upper hull
        //i starts from n-2 because n-1 is the point which both hulls will have in common
        //t=k+1 so that the upper hull has atleast two points to begin with
        for (int i = n - 2, t = k + 1; i >= 0; i--) {
            while (k >= t && cross(H[k - 2], H[k - 1], P[i]) <= 0) k--;
            H[k++] = P[i];
        }
        //the last point of upper hull is same with the fist point of the lower hull
        H.resize(k - 1);
        return H;
    }
    
    
    int main()
    {
    
        std::cout << "Hello World!\n";
    
        std::vector<Point> P_in;
        std::cout << "Input vector size: " << P_in.size();
    
        srand(time(0));
        std::cout << "Input vector points: ";
    	for(int a = 0; a < 35; a++)
    	{
            for(int b = 0; b < 20; b++)
            {
              int x = rand() % 100 +1;
              int y = rand() % 100 +1;
              std::cout << x << "  " << y;
              std::cout << '\n';
    		  P_in.push_back({x, y});
            }
    	}
    
    
        //std::vector<Point> P_in = { {0,0}, {10,10}, {0,10}, {10,0} };
    
        std::vector<Point> P_out = convex_hull(P_in);
    
        std::cout << "Output vector size: " << P_out.size();
        std::cout << '\n';
        for (int i = 0; i < P_out.size(); i++) {
            std::cout << P_out[i].x << "  " << P_out[i].y;
            std::cout << '\n';
        }// for
    
    }// main

  2. #2
    I thought by 'Vector', you meant, those types that indicate a certain direction and length.

    But reading that code, it's something else entirely!

    TIL about vectors and the prominent role they play in C++, when I found the Embarcadero blog post [url=https://blogs.embarcadero.com/vector-containers-for-delphi/Vector containers for Delphi[/url], which is about exactly that topic. The article links to a library that would be supported by Delphi as well as FreePascal, but unfortunately the repository is gone or hidden, so that renders the whole article pretty useless.

    Anyway, the C++ notation looks like generics, and the Delphi examples in that blog post depend on generic as well. Generics are not available until Delphi XE, I think, so you need a version that's at least a decade newer than then one you're using now.

    I'm not sure why you're still using Delphi 7, but it's 20 years old or so, and is way behind on features compared to recent builds. If it's a financial issue, with Delphi being pretty much unaffordable for hobbyists, you could have a look at the community editions of Delphi, or to FreePascal with the Lazarus IDE.
    The latter at least has some actual libaries for Vectors, it seems.

    But then again, if you want to stick to Delphi 7, I think you could easily get away with using (dynamic) arrays or a TList as well.
    Last edited by GolezTrol; 18-Nov-22 at 21:02.
    1+1=b

  3. #3
    My English is not so good so sometimes also I understand the message in completly different meaning, like "get away" like go away with ... I think vectors here in my code may be not necessary because the main thing in this algo is to work with coordinates. But later I will need to expand the program to make detection of borders of polygon and I think I will need to detect neighbours (neighbouring coordinates) which would be possible to do if I would do some mapping. So for this purpose I will need to have containers. So for example, lets have a image of size 1024x1024 px (LOD10), where some polygon with green color borders is located on black background. I will need to create some copies in lower LODs like 512x512 px (LOD9), 256x256px (LOD8), 128x128px (LOD7),64x64px (LOD6), 32x32 (LOD5), or maybe even 16x16 px (LOD4). Just to be able to improve the calculation of distance to a border/edge of the polygon. Then I thought, similar thing is needed to mapping, to create grayscale gradient images but for every LOD to change the way or direction the GRID is made. This would be great for sorting algo because I need to sort the point of the edges to find out how to connect the resulting points. Vector data (so called OSM data) will be the result. So this was my idea... A bit more complex So sorting point in the final stage would be made by comparing of the grayscale value saved in the mapper (container).

    So tomorrow I will read the article found here:
    https://docwiki.embarcadero.com/Code...TList_(Delphi)
    But are you sure, this TList is not specific only for RAD Studio?

  4. #4
    Get away as in, getting it done by 'simply' using this alternative.

    The generic TList is for later versions indeed. That's the TList<T> where you make list for any given type T.
    But an old fashioned TList (of pointers), or a TObjectList (of TObjects) is available in Delphi 7. You may need some casting, but you'll manage

    Or arrays. They are strong types.
    The trickyest part is the sorting, which is easier for the TList.
    There are some tips on Stack Overflow for sorting an array, some of which are actually using a TList to help.

    If you would make a TPointList class or something, you could embed that logic in it.

    All the other stuff you wrote, no idea what that means.
    Last edited by GolezTrol; 18-Nov-22 at 22:49.
    1+1=b

  5. #5
    If you are interested about logic of the Convex Hull algo, it is explained here:
    https://www.hackerearth.com/practice...ique/tutorial/
    In C++ the code originally used set instead vectors. But a very good programmer rewrite it to the shorted version as presented in my first post.

  6. #6
    Not particularly interested in the algo itself, but I'm interested in how you fare writing your own implementation of it in Delphi 7.
    1+1=b

  7. #7
    Quote Originally Posted by GolezTrol View Post
    Not particularly interested in the algo itself, but I'm interested in how you fare writing your own implementation of it in Delphi 7.
    I had a time to read some stuff about image proccessing. Now I need to start with Delphi (v. 7). I would also like to work with Graphics and especialy GDI+. My original idea was to write program for detection of polygon and return the edges. Then I have realized that this algo above is not exactly what I need. I think that it wrapps the points in such a menner that it will skip some important points. This needs to upload an image. So the green polygon - if you click in the middle and obtain coords, so the algo could detect the points to wrap the polygon with the red line as on the right. And that means that will skip some green lines inside it. It would be significantly reduced. The algo itself is good, but not for the purpose what I need to do now.

    And here is another question. Is it possible to work in Delphi 7 with GDI+ functions like Lockbits? I think I need some good performance function because I would like to test Sobel Edge detection algorythm. There is need to proccess image in both x-direction and in y-direction. And I think that functions like scanf, which is also included in Graphics units would be tremendously slow. But I dont know if is this possible to access the Windows GDI+. Maybe I can do all the stuff with GDI+ outside Graphics? It is complication for me the fact, the Graphics module does not have included this function. I thought I could use the functions from GDI+ directly like in gdip library for autohotkey (gdip.ahk). Because the scripting language has such library, where all the use of the function is listed. There is the function Gdip_LockBits(pBitmap, x, y, w, h, ByRef Stride, ByRef Scan0, ByRef BitmapData, LockMode = 3, PixelFormat = 0x26200a). So it seems to me like the Graphics unit is different. There is nothing like BitBlt (The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context.). Nothing like handle to destination device context HDC. Is it possible to make external calls for the GDI+ functions in Delphi 7? How to do it?
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	convex hull.PNG 
Views:	53 
Size:	6.4 KB 
ID:	8268  
    Last edited by chlopik; 23-Nov-22 at 00:36.

  8. #8
    Why are you looking at autohotkey scripts? They are so different from Delphi in how they call dlls.

    AFAIK, the GDI+ api is a 32 bit API that can be used in Delphi 7, although you'll find (again) that many examples and libraries won't support Delphi 7 anymore. I found a bunch, like this one, which only work for Delphi 2009 and up, and/or Lazarus.
    The graphics unit is indeed not a GDI+ library.

    I don't think I can help you further with this.
    1+1=b

Thread Information

Users Browsing this Thread

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

Tags for this Thread

Bookmarks

Posting Permissions

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