Class: Topolys::Wire

Inherits:
Object show all
Defined in:
lib/topolys/model.rb

Overview

DirectedEdge

Instance Attribute Summary collapse

Attributes inherited from Object

#attributes, #children, #id, #parents

Instance Method Summary collapse

Methods inherited from Object

#debug, #hash, link, #link_child, #link_parent, #short_id, #short_name, #to_s, unlink, #unlink_child, #unlink_parent

Constructor Details

#initialize(directed_edges) ⇒ Wire

Initializes a Wire object

Throws if directed_edges is incorrect type or if not sequential, not planar, or not closed

Parameters:

  • edge (Edge)

    The underlying edge

  • inverted (Boolean)

    True if this is a forward DirectedEdge, false otherwise



1035
1036
1037
1038
1039
1040
# File 'lib/topolys/model.rb', line 1035

def initialize(directed_edges)
  super()
  @directed_edges = directed_edges

  recalculate
end

Instance Attribute Details

#directed_edgesArray (readonly)

Returns array of directed edges.

Returns:

  • (Array)

    array of directed edges



1020
1021
1022
# File 'lib/topolys/model.rb', line 1020

def directed_edges
  @directed_edges
end

#normalVector3D (readonly)

Returns outward normal of this wire’s plane.

Returns:

  • (Vector3D)

    outward normal of this wire’s plane



1026
1027
1028
# File 'lib/topolys/model.rb', line 1026

def normal
  @normal
end

#planePlane3D (readonly)

Returns plane of this wire.

Returns:



1023
1024
1025
# File 'lib/topolys/model.rb', line 1023

def plane
  @plane
end

Instance Method Details

#child_classObject



1090
1091
1092
# File 'lib/topolys/model.rb', line 1090

def child_class
  DirectedEdge
end

#circular_equal?(directed_edges) ⇒ Bool

Checks if this Wire’s directed edges are the same as another array of directed edges. The order of directed edges must be the same but the two arrays may start at different indices.

Parameters:

  • directed_edges (Array)

    Array of DirectedEdge

Returns:

  • (Bool)

    Returns true if the wires are circular_equal, false otherwise



1151
1152
1153
1154
1155
1156
1157
1158
# File 'lib/topolys/model.rb', line 1151

def circular_equal?(directed_edges)

  if !Topolys::find_offset(@directed_edges, directed_edges).nil?
    return true
  end

  return false
end

#closed?Bool

Validates if directed edges are closed

Returns:

  • (Bool)

    Returns true if closed



1138
1139
1140
1141
1142
# File 'lib/topolys/model.rb', line 1138

def closed?
  n = @directed_edges.size
  return false if n < 3
  return @directed_edges[n-1].v1.id == @directed_edges[0].v0.id
end

#edgesArray

Returns Array of Edge.

Returns:

  • (Array)

    Array of Edge



1100
1101
1102
# File 'lib/topolys/model.rb', line 1100

def edges
  @directed_edges.map {|de| de.edge}
end

#facesObject



1094
1095
1096
# File 'lib/topolys/model.rb', line 1094

def faces
  @parents
end

#parent_classObject



1086
1087
1088
# File 'lib/topolys/model.rb', line 1086

def parent_class
  Face
end

#perimeterFloat

Gets 3D wire perimeter length

Returns:

  • (Float)

    Returns perimeter of 3D wire



1178
1179
1180
# File 'lib/topolys/model.rb', line 1178

def perimeter
  @directed_edges.inject(0){|sum, de| sum + de.length }
end

#pointsArray

Returns Array of Point3D.

Returns:

  • (Array)

    Array of Point3D



1112
1113
1114
# File 'lib/topolys/model.rb', line 1112

def points
  vertices.map {|v| v.point}
end

#recalculateObject



1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
# File 'lib/topolys/model.rb', line 1048

def recalculate
  super()

  # unlink from any previous directed edges
  @children.reverse_each {|child| Object.unlink(self, child)}

  # link with current directed edges
  @directed_edges.each {|de| Object.link(self, de)}

  # recompute cached properties and check invariants

  raise "Empty edges" if @directed_edges.empty?
  raise "Not sequential" if !sequential?
  raise "Not closed" if !closed?

  @normal = nil
  largest = 0
  (0...@directed_edges.size-1).each do |i|
    temp = @directed_edges[i].vector.cross(@directed_edges[i+1].vector)
    if temp.magnitude > largest
      largest = temp.magnitude
      @normal = temp
    end
  end

  raise "Cannot compute normal" if @normal.nil?
  raise "Normal has 0 length" if largest == 0

  @normal.normalize!

  @plane = Topolys::Plane3D.new(@directed_edges[0].v0.point, @normal)

  @directed_edges.each do |de|
    raise "Point not on plane" if (de.v0.point - @plane.project(de.v0.point)).magnitude > Topolys.planar_tol
    raise "Point not on plane" if (de.v1.point - @plane.project(de.v1.point)).magnitude > Topolys.planar_tol
  end
end

#reverse_equal?(other) ⇒ Bool

Checks if this Wire is reverse equal to another Wire. The order of directed edges must be the same but the two arrays may start at different indices.

Parameters:

  • other (Wire)

    Other Wire

Returns:

  • (Bool)

    Returns true if the wires are reverse_equal, false otherwise



1167
1168
1169
1170
# File 'lib/topolys/model.rb', line 1167

def reverse_equal?(other)
  # TODO: implement
  return false
end

#sequential?Bool

Validates if directed edges are sequential

Returns:

  • (Bool)

    Returns true if sequential



1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
# File 'lib/topolys/model.rb', line 1120

def sequential?
  n = @directed_edges.size
  @directed_edges.each_index do |i|
    break if i == n-1

    # e.g. check if first edge v0 == last edge v
    #      check if each intermediate, nieghbouring v0 & v are equal
    #      e.g. by relying on 'inverted?'
    #      'answer = true' if all checks out
    return false if @directed_edges[i].v1.id != @directed_edges[i+1].v0.id
  end
  return true
end

#shared_edges(other) ⇒ Array

Gets shared edges with another wire

Returns:

  • (Array)

    Returns array of shared edges



1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
# File 'lib/topolys/model.rb', line 1186

def shared_edges(other)
  return nil unless other.is_a?(Wire)

  result = []
  @directed_edges.each do |de|
    other.directed_edges.each do |other_de|
      result << de.edge if de.edge.id == other_de.edge.id
    end
  end

  return result
end

#to_jsonObject



1042
1043
1044
1045
1046
# File 'lib/topolys/model.rb', line 1042

def to_json
  result = super
  result[:directed_edges] = @directed_edges.map { |de| de.id }
  return result
end

#verticesArray

Returns Array of Vertex.

Returns:

  • (Array)

    Array of Vertex



1106
1107
1108
# File 'lib/topolys/model.rb', line 1106

def vertices
  @directed_edges.map {|de| de.v0}
end