POV-Ray : Newsgroups : povray.off-topic : Bounding circle intersection : Re: Bounding circle intersection Server Time
4 Sep 2024 23:22:19 EDT (-0400)
  Re: Bounding circle intersection  
From: Warp
Date: 11 Dec 2009 13:23:06
Message: <4b228e0a@news.povray.org>
bart <bart@home> wrote:
> Have you tried this condition?

> ((distSq < (radius1Sq+radius2Sq))
> or (4*radius1Sq*radius2Sq > (distSq - (radius1Sq+radius2Sq))^2))

  I was curious to see how much of a difference sqrt() really makes compared
to avoiding it, so I made this C++ file:

//-------------------------------------------------------------
#include <cmath>
#include <algorithm>

bool circlesCollide1(double cx1, double cy1, double rs1,
                     double cx2, double cy2, double rs2)
{
    const double vx = cx2 - cx1, vy = cy2 - cy1;
    return std::sqrt(vx*vx + vy*vy) < std::sqrt(rs1) + std::sqrt(rs2);
}

bool circlesCollide2(double cx1, double cy1, double rs1,
                     double cx2, double cy2, double rs2)
{
    const double vx = cx2 - cx1, vy = cy2 - cy1;
    const double dist2 = vx*vx + vy*vy;
    const double tmp = dist2 - (rs1 + rs2);
    return dist2 < rs1 + rs2 || 4.0*rs1*rs1 > tmp*tmp;
}
//-------------------------------------------------------------

and then a main program to test the speed:

//-------------------------------------------------------------
#include <iostream>
#include <ctime>

bool circlesCollide1(double cx1, double cy1, double rs1,
                     double cx2, double cy2, double rx2);
bool circlesCollide2(double cx1, double cy1, double rs1,
                     double cx2, double cy2, double rx2);

int main()
{
    double cx1 = -10.0, cy1 = -5.0, rs1_1 = 2.0*2.0, rs1_2 = 16.0*16.0;
    double cx2 = 5.0, cy2 = 10.0, rs2_1 = 2.5*2.5, rs2_2 = 18.0*18.0;
    const int iterations = 200000000;

    std::clock_t iClock = std::clock();
    for(int i = 0; i < iterations; ++i)
    {
        circlesCollide1(cx1, cy1, rs1_1, cx2, cy2, rs2_1);
        circlesCollide1(cx1, cy1, rs1_2, cx2, cy2, rs2_2);
    }
    std::clock_t eClock = std::clock();
    std::cout << "circlesCollide1: " << iterations << " iterations took "
              << double(eClock-iClock) / CLOCKS_PER_SEC << " seconds."
              << std::endl;

    iClock = std::clock();
    for(int i = 0; i < iterations; ++i)
    {
        circlesCollide2(cx1, cy1, rs1_1, cx2, cy2, rs2_1);
        circlesCollide2(cx1, cy1, rs1_2, cx2, cy2, rs2_2);
    }
    eClock = std::clock();
    std::cout << "circlesCollide2: " << iterations << " iterations took "
              << double(eClock-iClock) / CLOCKS_PER_SEC << " seconds."
              << std::endl;
}
//-------------------------------------------------------------

  I compiled with "-O3 -march=native" and got this result:

circlesCollide1: 200000000 iterations took 16.23 seconds.
circlesCollide2: 200000000 iterations took 5.42 seconds.

  (I didn't test that the functions give the correct result, though.)

-- 
                                                          - Warp


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.