void UBGraphicsProtractor::paintAngleMarker(QPainter *painter)
{
    painter->save();
    painter->translate(rect().center());
    painter->rotate(-mStartAngle);
    painter->translate(-rect().center().x(), -rect().center().y());
    qreal co = cos(mCurrentAngle * PI/180);
    qreal si = sin(mCurrentAngle * PI/180);
    qreal rad = radius();

    painter->drawLine(QLineF(rect().center(), QPointF(rect().center().x()+ (rad+ 20)*co, rect().center().y() - (rad + 20)*si)));
    QPointF center = rect().center();
    painter->drawArc(QRectF(center.x() - rad/8, center.y() - rad/8, rad / 4, rad / 4), 0
                     , (mCurrentAngle - (int)(mCurrentAngle/360)*360)*16);
    painter->translate(rect().center());
    painter->rotate(-mCurrentAngle);
    painter->translate(-rect().center().x(), -rect().center().y());

    //Paint Angle text (horizontally)

    //restore transformations
    painter->translate(rect().center());
    painter->rotate(mCurrentAngle);
    painter->rotate(mStartAngle);
    painter->translate(-rect().center().x(), -rect().center().y());

    qreal angle = mCurrentAngle - (int)(mCurrentAngle/360)*360;

    if (angle != 0)
    {
        QString ang = QString("%1°").arg(angle,0, 'f', 1);
        QFont font2 = painter->font();
        font2.setBold(true);
        QFontMetricsF fm2(font2);
        painter->setFont(font2);
        if (angle < 50)
            angle = 90;
        else
            angle = angle / 2;

        co = cos((mStartAngle + angle) * PI/180);
        si = sin((mStartAngle + angle) * PI/180);
        painter->drawText(QRectF(rect().center().x() + (rad*2.5/10)*co  - fm2.width(ang)/2,
                                 rect().center().y() - (rad*2.5/10)*si - fm2.height()/2,
                                 fm2.width(ang), fm2.height()), Qt::AlignTop, ang);
    }

    painter->restore();
}
Ejemplo n.º 2
0
void LCVCircle::draw(LcPainter* painter, LcDrawOptions* options, const lc::geo::Area& rect) const {
    bool modified = false;

    if (this->selected()) {
        modified = true;
        painter->save();
        painter->source_rgba(
            options->selectedColor().red(),
            options->selectedColor().green(),
            options->selectedColor().blue(),
            options->selectedColor().alpha()
        );
    }


    if (radius() /** painter->scale() > 5 */) {
        painter->circle(center().x(), center().y(), radius());
        painter->stroke();
    }

    if (modified) {
        painter->restore();
    }
}
Ejemplo n.º 3
0
bool ice_ring_test(di::w_spot const& spot,di::SpotFilterAgent* agent){
  double r = radius(spot,agent);
  for(
   af::shared<Distl::icering>::const_iterator ice_ring =
     agent->icerings.begin();
   ice_ring != agent->icerings.end();
   ++ice_ring) {
     if (
      r > agent->pixel_size*(std::sqrt(ice_ring->lowerr2)) - 0.4 &&
      r < agent->pixel_size*(std::sqrt(ice_ring->upperr2)) + 0.4
     ) {return false;}
  }
  // add a 0.4mm annulus above & below ring to allow for inaccurate center
  return true;
}
Ejemplo n.º 4
0
Node* Internals::touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
{
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    IntSize radius(width / 2, height / 2);
    IntPoint point(x + radius.width(), y + radius.height());

    Node* targetNode;
    IntPoint adjustedPoint;
    document->frame()->eventHandler()->bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
    return targetNode;
}
uint8_t ADMVideoMaskedSoften::configure( AVDMGenericVideoStream *instream)
{
        _in=instream;
        /*uint32_t luma,chroma;
	uint32_t radius;
	*/
        
        diaElemUInteger luma(&(_param->luma),QT_TR_NOOP("_Luma threshold:"),0,255);
        diaElemUInteger chroma(&(_param->chroma),QT_TR_NOOP("C_hroma threshold:"),0,255);
        diaElemUInteger radius(&(_param->radius),QT_TR_NOOP("_Radius:"),1,60);
	  
    diaElem *elems[3]={&luma,&chroma,&radius};
  
    return diaFactoryRun(QT_TR_NOOP("Soften"),3,elems);
}
void Circle::draw(Window const& wndw, Color const& clr) 
{
    const float pi = std::acos(-1);
    float r=radius();
    wndw.draw_point(center().x,center().y,clr.r_,clr.g_,clr.b_); //Center+RGB
    
    
    for (int i=1; i<361; i++)
    {
        Vec2 start=((make_rotation_mat2(2*pi*i/360))*Vec2(r,0)+center());
        Vec2 end=((make_rotation_mat2(2*pi*(i+1)/360))*Vec2(r,0)+center());
        wndw.draw_line(start.x,start.y,end.x,end.y,clr.r_,clr.g_,clr.b_);
    }
          
}
Ejemplo n.º 7
0
QRect KisVisualEllipticalSelectorShape::getSpaceForTriangle(QRect geom)
{
    int sizeValue = qMin(width(),height());
    QRect b(geom.left(), geom.top(), sizeValue, sizeValue);
    QLineF radius(b.center(), QPointF(b.left()+m_barWidth, b.center().y()) );
    radius.setAngle(90);//point at yellowgreen :)
    QPointF t = radius.p2();
    radius.setAngle(330);//point to purple :)
    QPointF br = radius.p2();
    radius.setAngle(210);//point to cerulean :)
    QPointF bl = radius.p2();
    QPointF tl = QPoint(bl.x(),t.y());
    QRect r(tl.toPoint(), br.toPoint());
    return r;
}
void ReactiveRectangleElement::paint(juce::Graphics &g)
{
    g.saveState();
    
    if (clip)
    {
        g.reduceClipRegion(clipPath);
    }
    if(width() > 0 && height() > 0)
    {
        
        if (fill)
        {
            g.setColour(fillColour());
            g.fillRoundedRectangle(fx, fy, fw, fh, radius());
        }
        g.setColour(borderColour());
        g.drawRoundedRectangle(fx, fy, fw, fh, radius(), borderWidth());
        
    }
    GraphicsElement::paint(g);
    
    g.restoreState();
}
Ejemplo n.º 9
0
int JuliaFractal::calcAtPoint(const double x0, const double y0) const
{
	long double vectorLength = 0;
	auto x = x0;
	auto y = y0;
	int iteration;
	for (iteration = 0;(iteration < maxIterationCount())&(vectorLength < radius()); iteration++ ) {
		auto currentX = (x+y)*(x-y) + cPmin;
		auto currentY = x*y + x*y + cQmin;
		vectorLength = currentX*currentX + currentY*currentY;
		x = currentX;
		y = currentY;
	}
	return iteration;
}
Ejemplo n.º 10
0
void CResource::paint() {
    float x = center().x();
    float y = center().y();
	float z = center().z();
    float r = radius();

    switch(m_type){
        case CResource::RES_TYPE_FOOD: glColor3f(0.0, 1.0, 0.0); break;
        case CResource::RES_TYPE_WATER: glColor3f(0.0, 0.0, 1.0); break;
        default: break;
    }
	glTranslatef(x, y, z);
	glutSolidCube(r);
	glTranslatef(-x, -y, -z);
}
Ejemplo n.º 11
0
void setup_airspaces(Airspaces& airspaces, const GeoPoint& center, const unsigned n) {
    std::ofstream *fin = NULL;

    if (verbose) {
        Directory::Create(Path(_T("output/results")));
        fin = new std::ofstream("output/results/res-bb-in.txt");
    }

    for (unsigned i=0; i<n; i++) {
        AbstractAirspace* as;
        if (rand()%4!=0) {
            GeoPoint c;
            c.longitude = Angle::Degrees(fixed((rand()%1200-600)/1000.0))+center.longitude;
            c.latitude = Angle::Degrees(fixed((rand()%1200-600)/1000.0))+center.latitude;
            fixed radius(10000.0*(0.2+(rand()%12)/12.0));
            as = new AirspaceCircle(c,radius);
        } else {

            // just for testing, create a random polygon from a convex hull around
            // random points
            const unsigned num = rand()%10+5;
            GeoPoint c;
            c.longitude = Angle::Degrees(fixed((rand()%1200-600)/1000.0))+center.longitude;
            c.latitude = Angle::Degrees(fixed((rand()%1200-600)/1000.0))+center.latitude;

            std::vector<GeoPoint> pts;
            for (unsigned j=0; j<num; j++) {
                GeoPoint p=c;
                p.longitude += Angle::Degrees(fixed((rand()%200)/1000.0));
                p.latitude += Angle::Degrees(fixed((rand()%200)/1000.0));
                pts.push_back(p);
            }
            as = new AirspacePolygon(pts,true);
        }
        airspace_random_properties(*as);
        airspaces.Add(as);
        if (fin)
            *fin << *as;
    }

    delete fin;

    // try inserting nothing
    airspaces.Add(NULL);

    airspaces.Optimise();

}
Ejemplo n.º 12
0
std::vector<Cell> MxField::cells() const
{
    std::vector<Cell> result;
    for (uint32_t x = 0; x < m_sides.x; ++x) {
        for (uint32_t y = 0; y < m_sides.y; ++y) {
            for (uint32_t z = 0; z < m_sides.z; ++z) {
                if (m_field[x][y][z] != 0) {
                    result.push_back(Cell(//new FCube(side()),
                                          new FSphere(radius()),
                                          dCoord(x * side(), y * side(), z * side())));
                }
            }
        }
    }
    return result;
}
Ejemplo n.º 13
0
void Foam::toroidalCS::writeDict(Ostream& os, bool subDict) const
{
    if (subDict)
    {
        os  << indent << nl
            << indent << token::BEGIN_BLOCK << incrIndent << nl;
    }

    coordinateSystem::writeDict(os, false);
    os.writeKeyword("radius") << radius() << token::END_STATEMENT << nl;

    if (subDict)
    {
        os << decrIndent << indent << token::END_BLOCK << endl;
    }
}
Ejemplo n.º 14
0
af::shared<int>
di::SpotFilterAgent::resolution_sort(spot_list_t masterlist,
                                     af::shared<int> parentselection){
  //First update the w_spot array with calculated resolutions.
  for (spot_list_t::iterator spotptr = masterlist.begin();
       spotptr != masterlist.end(); ++spotptr) {
       double spotradius = radius(*spotptr,this);
       double theta = std::atan2(spotradius,distance)/2.0;
       spotptr->resolution = wavelength/(2.0 * std::sin(theta));
  }
  cmp mycmp(masterlist);
  //sort according to resolution
  af::shared<int> to_be_sorted = parentselection.deep_copy();
  std::sort<PtrTyp,cmp>(to_be_sorted.begin(),to_be_sorted.end(),mycmp);
  return to_be_sorted;
}
Ejemplo n.º 15
0
std::shared_ptr<CAbstractShape> CShapeFactory::CreateEllipse(std::istream & descr)
{
	
	Vec2 center(-1.0, -1.0);
	Vec2 radius(-1.0, -1.0);
	std::string color;
	descr >> color;
	descr >> center.x >> center.y >> radius.x >> radius.y;
	if (center.x < 0 || center.y < 0 || radius.x < 0 || radius.y < 0)
	{
		throw std::invalid_argument("Unclear data");
	}
	auto shape = std::make_shared<CEllipse>(center, radius);
	shape->SetColor(GetColor(color));
	return shape;
}
Ejemplo n.º 16
0
void blur_channels_node_t::get_expand_radius( int& hradius, int& vradius) const
{
    Imath::V2f r_radius = get_value<Imath::V2f>( param( "r_radius"));
    Imath::V2f g_radius = get_value<Imath::V2f>( param( "g_radius"));
    Imath::V2f b_radius = get_value<Imath::V2f>( param( "b_radius"));
    Imath::V2f a_radius = get_value<Imath::V2f>( param( "a_radius"));

	r_radius = adjust_blur_size( r_radius, 1);
	g_radius = adjust_blur_size( g_radius, 1);
	b_radius = adjust_blur_size( b_radius, 1);
	a_radius = adjust_blur_size( a_radius, 1);
    Imath::V2i radius( round_blur_size( Imath::V2f( std::max( r_radius.x, std::max( g_radius.x, std::max( b_radius.x, a_radius.x))),
							                        std::max( r_radius.y, std::max( g_radius.y, std::max( b_radius.y, a_radius.y))))));

    hradius = radius.x;
    vradius = radius.y;
}
Ejemplo n.º 17
0
bool color_picker::mouse_press( const point &p, int b )
{
	if ( b == 1 )
	{
		coord_type r = point::distance( p, center() ) / radius();
		if ( r > 0.70 && r < 0.95 )
		{
			_tracking = true;
			point d = p.delta( center() );
			coord_type h = std::atan2( d.y(), d.x() );
			_current.set_hsl( h, 1.0, 0.5 );
			return mouse_move( p );
		}
	}

	return widget::mouse_press( p, b );
}
Ejemplo n.º 18
0
void
AsdkSmiley::scaleRadius(const double r)       
{
    assertWriteEnabled();
    AcGePoint3d center( center() );
    double rad = radius(),
           factor = r / rad;
    setEyesApart( factor * meyesapart );
    setEyesHeight( factor * meyesheight );
    setEyeSize( factor * meyesize );
    AcGePoint3d left( mouthLeft() ),
                bottom( mouthBottom() ),
                right( mouthRight() );
    setMouth( left.scaleBy( factor, center ), bottom.scaleBy( factor, center ), right.scaleBy( factor, center ) );
    setRadius( r );
    recordGraphicsModified();
} // smiley radius
/***********************************************************************//**
 * @brief Return MC sky direction
 *
 * @param[in] energy Photon energy.
 * @param[in] time Photon arrival time.
 * @param[in,out] ran Random number generator.
 * @return Sky direction.
 *
 * Draws an arbitrary sky direction from the 2D disk distribution as function
 * of the photon @p energy and arrival @p time.
 ***************************************************************************/
GSkyDir GModelSpatialRadialDisk::mc(const GEnergy& energy,
                                    const GTime&   time,
                                    GRan&          ran) const
{
    // Simulate offset from photon arrival direction
    double cosrad = std::cos(radius() * gammalib::deg2rad);
    double theta  = std::acos(1.0 - ran.uniform() * (1.0 - cosrad)) *
                    gammalib::rad2deg;
    double phi    = 360.0 * ran.uniform();

    // Rotate sky direction by offset
    GSkyDir sky_dir = dir();
    sky_dir.rotate_deg(phi, theta);

    // Return sky direction
    return sky_dir;
}
Ejemplo n.º 20
0
PassRefPtr<ClientRect> Internals::bestZoomableAreaForTouchPoint(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
{
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    IntSize radius(width / 2, height / 2);
    IntPoint point(x + radius.width(), y + radius.height());

    Node* targetNode;
    IntRect zoomableArea;
    document->frame()->eventHandler()->bestZoomableAreaForTouchPoint(point, radius, zoomableArea, targetNode);
    if (targetNode)
        zoomableArea = targetNode->document()->view()->contentsToWindow(zoomableArea);

    return ClientRect::create(zoomableArea);
}
Ejemplo n.º 21
0
PassRefPtr<WebKitPoint> Internals::touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
{
    if (!document || !document->frame()) {
        ec = INVALID_ACCESS_ERR;
        return 0;
    }

    IntSize radius(width / 2, height / 2);
    IntPoint point(x + radius.width(), y + radius.height());

    Node* targetNode;
    IntPoint adjustedPoint;
    document->frame()->eventHandler()->bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
    if (targetNode)
        adjustedPoint = targetNode->document()->view()->contentsToWindow(adjustedPoint);

    return WebKitPoint::create(adjustedPoint.x(), adjustedPoint.y());
}
Ejemplo n.º 22
0
vector<Point> findPoly(int vertices, vector<Point> points) {
  double angle = (2 * M_PI) / ((double)vertices); 
  double dist  = radius(points);
  Point center = polyCenter(points);
  Point offset = center + Point(0, 2 * dist);
  vector<Point> result;
  vector<Point> polygon;

  Point first = rotateAround(center, offset, - (0.5 * angle));
  polygon.push_back(first);

  for (int i = 0; i < vertices - 1; i++) {
    Point p = rotateAround(center, first, angle * (i+1));
    polygon.push_back(p);
  }

  return correlate(polygon, points);
}
Ejemplo n.º 23
0
const Options Writer::getDefaultOptions() const
{
    Options options;

    Option grid_x("grid_dist_x", 6.0, "X grid distance");
    Option grid_y("grid_dist_y", 6.0, "Y grid distance");

    double default_radius = (double) sqrt(2.0) * grid_x.getValue<double>();
    Option radius("radius", default_radius);

    Option fill_window_size("fill_window_size", 3);

    options.add(grid_x);
    options.add(grid_y);
    options.add(radius);
    options.add(fill_window_size);
    return options;
}
Ejemplo n.º 24
0
double FillingRate(Mat src, int size) {
    Mat src_gray;
    cvtColor(src, src_gray, CV_BGR2GRAY);
    blur(src_gray, src_gray, Size(3, 3));

    Mat threshold_output;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    /// Detect edges using Threshold
    threshold(src_gray, threshold_output, 253, 255, THRESH_BINARY);
    //imshow("", threshold_output); waitKey(0);
    /// Find contours
    findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    /// Approximate contours to polygons + get bounding rects and circles
    vector<vector<Point> > contours_poly(contours.size());
    vector<Rect> boundRect(contours.size());
    vector<Point2f>center(contours.size());
    vector<float>radius(contours.size());

    for (int i = 0; i < contours.size(); i++)
    {
        approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);
        minEnclosingCircle((Mat)contours_poly[i], center[i], radius[i]);
    }

    /// Draw polygonal contour + bonding rects + circles
    Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);
    for (int i = 0; i< contours.size(); i++)
    {
        //cout << arcLength(contours[i], true) << endl;
        Scalar color = Scalar(255, 255, 255);
        drawContours(drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point());
        circle(drawing, center[i], (int)radius[i], color, 2, 8, 0);
    }
    size = windowSize*windowSize - countNonZero(threshold_output);
    /// Show in a window
    //namedWindow("Contours", CV_WINDOW_AUTOSIZE); imshow("Contours", drawing); waitKey(0);
    cout << double(size) / (double(pow(radius[1], 2))*3.14);
    return double(size) / (double(pow(radius[1], 2))*3.14);


}
Ejemplo n.º 25
0
void read_input()
{
    FILE *fin = fopen("Kepler-90.in", "r");
    fscanf (fin, "%d", &n_planets);
    // fprintf (stderr, "%d\n", n_planets);
    for (int i = 0; i < n_planets; i++)
    {
        char s[100];
        fscanf (fin, "%s %d", s, &use[i]);
        P90[i] = atof (s);
        IO90[i].a      = radius (M90, P90[i]);
        // fprintf (stderr, "%d %f\n", i + 1, IO90[i].a);
        IO90[i].r_star = R90 * SR_TO_AU;
        IO90[i].r      = 0;
        IO90[i].e      = 0;
        IO90[i].omega  = 0;
    }
    fclose (fin);
}
Ejemplo n.º 26
0
WebTouchEvent WebEventFactory::createWebTouchEvent(const QTouchEvent* event, const QTransform& fromItemTransform)
{
    WebEvent::Type type  = webEventTypeForEvent(event);
    WebPlatformTouchPoint::TouchPointState state = static_cast<WebPlatformTouchPoint::TouchPointState>(0);
    unsigned int id;
    WebEvent::Modifiers modifiers   = modifiersForEvent(event->modifiers());
    double timestamp                = currentTimeForEvent(event);

    const QList<QTouchEvent::TouchPoint>& points = event->touchPoints();
    
    Vector<WebPlatformTouchPoint, 6> m_touchPoints;
    for (int i = 0; i < points.count(); ++i) {
        const QTouchEvent::TouchPoint& touchPoint = points.at(i);
        id = static_cast<unsigned>(touchPoint.id());
        switch (touchPoint.state()) {
        case Qt::TouchPointReleased: 
            state = WebPlatformTouchPoint::TouchReleased; 
            break;
        case Qt::TouchPointMoved: 
            state = WebPlatformTouchPoint::TouchMoved; 
            break;
        case Qt::TouchPointPressed: 
            state = WebPlatformTouchPoint::TouchPressed; 
            break;
        case Qt::TouchPointStationary: 
            state = WebPlatformTouchPoint::TouchStationary; 
            break;
        default:
            ASSERT_NOT_REACHED();
            break;
        }

        // Qt does not have a Qt::TouchPointCancelled point state, so if we receive a touch cancel event,
        // simply cancel all touch points here.
        if (type == WebEvent::TouchCancel)
            state = WebPlatformTouchPoint::TouchCancelled;

        IntSize radius(touchPoint.rect().width()/ 2, touchPoint.rect().height() / 2);
        m_touchPoints.append(WebPlatformTouchPoint(id, state, touchPoint.screenPos().toPoint(), fromItemTransform.map(touchPoint.pos()).toPoint(), radius, 0.0, touchPoint.pressure()));
    }

    return WebTouchEvent(type, m_touchPoints, modifiers, timestamp);
}
Ejemplo n.º 27
0
void Lake::ripple(const Drop &drop, unsigned int step, float timeunit) {
  auto point_map
    = affected_points(drop, radius(drop, step*timeunit), step*timeunit);

  for (const auto &association : point_map) {
    const auto &height = association.first;
    const auto &points = association.second;
    #pragma omp parallel for schedule(static)
    for (unsigned int k = 0; k < points->size(); k++) {
      int i = (*points)[k].first + drop.position().first;
      int j = (*points)[k].second + drop.position().second;
      if (i >= 0 && j >= 0
      &&  i < static_cast<int>(width_) && j < static_cast<int>(length_)) {
        updateSum(i, j, height, step);
        updateVariance(i, j, height, step);
      }
    }
  }
}
Ejemplo n.º 28
0
Options P2gWriter::getDefaultOptions()
{
    Options options;

    Option grid_x("grid_dist_x", 6.0, "X grid distance");
    Option grid_y("grid_dist_y", 6.0, "Y grid distance");

    double default_radius = (double) sqrt(2.0) * grid_x.getValue<double>();
    Option radius("radius", default_radius);

    Option fill_window_size("fill_window_size", 3);
    Option dim_z("Z", "Z", "Name of Z dimension to interpolate");
    options.add(dim_z);
    options.add(grid_x);
    options.add(grid_y);
    options.add(radius);
    options.add(fill_window_size);
    return options;
}
Ejemplo n.º 29
0
	void WegstueckSchlange::zeichne( sZeichenflaeche::Zeiger zeichenflaeche )
	{
		for (int i = 0; i < anzahl(); i++)
		{
			UnaerePlanareFunktionsvisualisierung::Zeiger visualisierung = new UnaerePlanareFunktionsvisualisierung(wegstueck(i));
			visualisierung->referenzEntfernen();
			double schrittweite;
			if (kreis(i))
			{
				schrittweite = radius(i)*winkel(i) /  40.0;
			} else 
				schrittweite = laenge(i);

			visualisierung->setzeSchrittweite(schrittweite);
			visualisierung->setzeBeginn(0.0);
			visualisierung->setzeEnde  (laenge(i));
			visualisierung->zeichne(zeichenflaeche);
		}
	}
Ejemplo n.º 30
0
template<UnsignedInt dimensions> Collision<dimensions> InvertedSphere<dimensions>::operator/(const Sphere<dimensions>& other) const {
    const Float maxDistance = radius() - other.radius();
    /** @todo How to handle inseparable shapes or shapes which can't be separated by movement only (i.e. two half-spaces)? */
    CORRADE_INTERNAL_ASSERT(maxDistance > 0.0f);
    const VectorTypeFor<dimensions, Float> separating = other.position() - position();
    const Float dot = separating.dot();

    /* No collision occured */
    if(dot < Math::pow<2>(maxDistance)) return {};

    /* Actual distance */
    const Float distance = Math::sqrt(dot);

    /* Separating normal */
    const VectorTypeFor<dimensions, Float> separatingNormal = separating/distance;

    /* Contact position is on the surface of `other`, distance > maxDistance */
    return Collision<dimensions>(other.position() + separatingNormal*other.radius(), separatingNormal, distance - maxDistance);
}