# Module: RGeo::Cartesian::Analysis

Defined in:
lib/rgeo/cartesian/analysis.rb

## Overview

This provides includes some spatial analysis algorithms supporting Cartesian data.

## Class Method Summary collapse

• Given a LineString, which must be a ring, determine whether the ring proceeds clockwise or counterclockwise.

## Class Method Details

### .ring_direction(ring_) ⇒ Object

Given a LineString, which must be a ring, determine whether the ring proceeds clockwise or counterclockwise. Returns 1 for counterclockwise, or -1 for clockwise.

Returns 0 if the ring is empty. The return value is undefined if the object is not a ring, or is not in a Cartesian coordinate system.

 ``` 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110``` ```# File 'lib/rgeo/cartesian/analysis.rb', line 58 def ring_direction(ring_) size_ = ring_.num_points - 1 return 0 if size_ == 0 # Extract unit-length segments from the ring. segs_ = [] size_.times do |i_| p0_ = ring_.point_n(i_) p1_ = ring_.point_n(i_+1) x_ = p1_.x - p0_.x y_ = p1_.y - p0_.y r_ = ::Math.sqrt(x_*x_ + y_*y_) if r_ > 0.0 segs_ << x_/r_ << y_/r_ else size_ -= 1 end end segs_ << segs_ << segs_ # Extract angles from the segments by subtracting the segments. # Note angles are represented as cos/sin pairs so we don't # have to calculate any trig functions. angs_ = [] size_.times do |i_| x0_, y0_, x1_, y1_ = segs_[i_*2,4] angs_ << x0_*x1_ + y0_*y1_ << x0_*y1_ - x1_*y0_ end # Now add the angles and count revolutions. # Again, our running sum is represented as a cos/sin pair. revolutions_ = 0 sin_ = 0.0 cos_ = 1.0 angs_.each_slice(2) do |(x_, y_)| ready_ = y_ > 0.0 && sin_ > 0.0 || y_ < 0.0 && sin_ < 0.0 if y_ != 0.0 s_ = sin_*x_ + cos_*y_ c_ = cos_*x_ - sin_*y_ r_ = ::Math.sqrt(s_*s_ + c_*c_) sin_ = s_ / r_ cos_ = c_ / r_ end if ready_ if y_ > 0.0 && sin_ <= 0.0 revolutions_ += 1 elsif y_ < 0.0 && sin_ >= 0.0 revolutions_ -= 1 end end end revolutions_ end```