【SU Ruby教程】幾何與變換(1):向量與點線面

2021-02-24 Apiglio

從這一篇開始,教程進入第三個部分,開始對SU Ruby API中的各個模塊和類的方法和相關概念進行詳細的介紹。首先不可避免的要談及SU模型表示三維空間的方法。包括空間坐標、空間範圍、空間變換以及更廣域意義上的地理坐標表示等內容:這就需要使用到Geom模塊。

Geom模塊是幾何與變換的核心模塊,教程將分為四個部分介紹。以下是第一篇,有關如何表示一個點、一條直線或者一個平面。

幾何與變換(1):向量與點線面

【本期目錄】

(1)長度與角度單位

①長度單位

②角度單位

③自定義單位轉換

④模型單位格式

(4)直線

①點向式表示法

②與Sketchup::Edge的關係

(2)點

①用數組表示點

②Geom::Point

③與Sketchup::Vertex的區別

(5)平面

①點法式表示法

②原點距式表示法

③與Sketchup::Face的關係

(3)向量

①用數組表示向量

②Geom::Vector

③向量計算

(6)立體幾何

①交錯與投影

②位置關係

③距離計算

(1)長度與角度單位

①長度單位

Sketchup的默認長度尺寸為英寸,因此在使用數字坐標的時候,(1000,0,0)並不代表距離原點1000毫米的點,而是距離原點1000英寸的點。這時如果需要使用1000毫米的尺寸,就需要使用 1000.mm。

如上圖可以發現 1000.mm 返回的並不是一個數字類(::Numeric),而是::Length類。這個類繼承自::Numeric類,所有數值都繼承自這個ruby自帶的類,SU在其中追加了一些方法使之可以直接進行單位轉換。而轉換之後使用 .inspect 方法查看這個數值的存儲值可以發現依然是以英寸作為單位的。

相似地,還可以將英寸轉換為釐米(cm)、米(m)、千米(km)、英尺(feet)、英碼(yard)和英裡(mile),當然也可以是轉換成英寸本身。下圖是這些轉換方式的測試,由於當前模型的單位為毫米,所以顯示時為毫米單位:

1.feet1.yard1.inch1.mile1.km1.cm1.m

隨便打一個數字,查看數字以「to_」開頭的方法,可以看到ruby風格的轉換方法,其中除了 to_s、 to_f、 to_i、 to_c 這些ruby自帶的數據類型轉換以外,還有SU提供的單位轉換。

這些是與上文相對應的逆過程方法,將以英寸計的尺寸轉換成指定單位下的數值。例如:

1.m.to_mm1.mile.to_yard1.feet.to_inch1.km.to_m1.yard.to_feet1.mile.to_m1.inch.to_mm

②角度單位

SketchUp的角度單位默認是弧度制,因此如果需要使用角度制,需在角度數值之後添加 .degrees 。這裡需要與前文長度單位區別一下,不同於 .mm 返回的是Length類, .degrees 方法返回的並不是一個特定的Angle類實例,而是浮點數類型(::Float)。這意味著這個返回值與原數值一樣,都是不帶單位的數字。因此這個方法是純粹的數值轉化,可以直接理解成是如下的定義:

class Numeric  def degrees    return(self / 180 * Math::PI)  end  def radians    return(self / Math::PI * 180)  endend

同理,還有一個 .radians 方法,用於將弧度制轉換為角度制,同樣返回的是Float類型。因此,角度制弧度制的轉換不是像英寸和毫米的轉換那樣有主次關係,表現為一對 .mm 和 .to_mm ,而是 .degrees 和 .radians 對稱的轉換方法。

③自定義單位轉換

在理解了角度單位轉換的方式之後,也可以使用相同的手法追加其他自定義方法到Numeric類以實現其他單位轉換。由於Length繼承自Numeric類,因此在往Numeric中追加新方法的同時,Length類也會同步更新這些方法。以下以英制單位「弗隆」和市制單位「寸」「尺」「丈」「引」「裡」為例子:

class Numeric  def furlong    return (self*220*3*12).to_l  end  def to_furlong    return (self/220/3/12)  end  def cun    return (self*100/3).mm  end  def to_cun    return (self.to_mm*3/100)  end  def chi    return (self*10).cun  end  def to_chi    return (self.to_cun/10)  end  def zhang    return (self*100).cun  end  def to_zhang    return (self.to_cun/100)  end  def yin    return (self*1000).cun  end  def to_yin    return (self.to_cun/1000)  end  def li    return (self*15000).cun  end  def to_li    return (self.to_cun/15000)  endend

其中furlong的轉換方法中出現了 .to_l 方法,這是將Numeric類轉換成英寸單位的Length類的方法;而市制單位的換算中都是用 .mm 方法繞開了這一步驟。下圖為效果測試:

1.li.to_m1.zhang.to_cm1.cun.to_inch1.chi.to_feet1.zhang.to_yard1.yin.to_furlong1.li.to_mile1.m.to_cun1.mile.to_furlong

④模型單位格式

在Sketchup模塊下定義有這樣一系列的方法,它們通過給定的英寸單位的數據返回當前模型的單位數值。包括 .format_length、 .format_area、 .format_angle、 .format_degrees 和 .format_volume 。如下圖,如果是2019.2以前的版本,是沒有 .format_volume 這個方法的。

在當前模型以毫米為單位時,就會是以下的結果:

puts Sketchup.format_degrees(Math::PI.radians)puts Sketchup.format_angle(Math::PI)puts Sketchup.format_length(100.m)puts Sketchup.format_length(1.mile)puts Sketchup.format_area(1)puts Sketchup.format_area(3.mm*9.mm)puts Sketchup.format_volume(3.mm*4.mm*5.mm)

對於2019以前的版本,也可以通過追加的方法在Sketchup模塊中自己添加 .format_volume 方法,不過需要涉及到判斷當前模型的單位設置,這會在之後有關Sketchup:: OptionsManager的章節中涉及。

(2)點

①用數組表示空間點

Sketchup 中可以使用數組來表示空間坐標,例如坐標 (0,100,100) 在ruby中表示為 [0,100,100]。其中三個維度的順序是 [x,y,z],或說 [width, height, depth],同時也接受xy平面上的二維坐標 [x,y],或者說 [width, height]。

了解了這種最簡易的表示空間點坐標的方式,就已經可以利用Entities類中的添加圖元方法,向圖元容器中繪製新圖形了:

②用Geom::Point表示空間點

數組只是方便使用者快速地表示空間坐標,而模型中的圖元的存檔則有專門的定義,二維和三維的空間坐標有分別的類定義,即Geom:: Point2d 和 Geom:: Point3d。

這裡以Geom:: Point3d為例,同樣繪製上一部分中的那條線段,同時額外展示一些創建Point3d實例的方法:

point_O  = Geom::Point3d.new(0,0,0)point_P  = Geom::Point3d.new([100.mm,100.mm,0])point_P1 = Geom::Point3d.new(point_P)point_P2 = point_P.clone
Sketchup.active_model.entities.add_line(point_O,point_P)
puts point_O==point_P  puts point_P==point_P1 puts point_P==point_P2 

其中第一行和第二行是比較常見的創建點的方式,一種是使用三個參數表示xyz,另一種則是使用數組表示三維坐標。第三行是通過已有點的坐標創建新的點,其實它與第二行的表達只有一步之遙,可以寫成這樣: point_P1 = Geom:: Point3d. new( point_P. to_a) 。第四行則完全不需要使用類名,直接使用已有點創建副本,是比較方便的做法。8-10行對這些點進行比較,P1和P2是通過P創建的,因此相等;O與P則不相等。

如果需要訪問Point類實例的坐標,有兩種方式可以選擇:

p = Geom::Point3d.new(4.mm,8.mm,12.mm)puts p.x  puts p.y  puts p.z  puts p[0]  puts p[1]  puts p[2]  

如果需要修改Point類實例的坐標,有三種方式可以選擇:

p = Geom::Point3d.new(4.mm,8.mm,12.mm)p.x=1.mmp.y=2.mmp.z=4.mmputs p    p[0]=0.mmp[1]=1.mmp[2]=2.mmputs p    p.set!([3.mm,6.mm,12.mm])p.set!(3.mm,6.mm,12.mm)puts p    

訪問與修改共五種方法,其中除了 .set! 以外,其餘四種方法對於用數組形式的坐標也有效, .[] 和 .[]= 還是Array類固有的方法。

Geom:: Point2d 和 Geom:: Point3d 是專門的點類型,使用這種方式表示空間點坐標不如數組表示來得方便,但是具有兩個優勢:一是數組不僅可以用來表示空間坐標,還可以用來表示向量,混合使用數組可能會造成混淆,影響代碼的可讀性;二是這兩個類的實例有數組類沒有的方法,這些方法在點與向量的計算中能夠提供方便。

③與Sketchup::Vertex的關係

Vertex是Sketchup模塊下定義的端點類,是圖元的一種,是直接與Geom:: Point類對標的圖元類。Point類側重於空間計算,而Vertex類是具體模型中的數據類型,包括了模型中端點與其它圖元的關係,例如該端點參與了哪些邊線、面的組成。Vertex作為表示端點的圖元,包含空間點坐標的信息,所以每一個實例中包含一個Point類實例,通過Vertex類的 .position 方法可以訪問:

edge=Sketchup.active_model.entities[0]vertex=edge.vertice[1]puts vertex.position

其中, edge. vertice 返回邊線的兩個端點, edge. vertice[1] 表示的是其中的終點。這部分內容會在涉及Sketchup:: Edge類的章節中詳解。

(3)向量

①使用數組表示向量

向量的表達方式與點坐標的表達方式如出一轍,同樣是 [x,y,z] 或者 [x,y] 的順序。在SU Ruby中,向量經常用於表示平面的方向。例如繪製一個圓時, .add_circle 中的第二個參數就是向量,表示繪製圓所在平面的法向量。

Sketchup::Entities.add_circle(  centre,          normal,          radius           [,segnum=24]   ) => Array of Sketchup::Edge

以下為了便於展示,在畫圓的基礎上創建了相應的面域:

②使用Geom::Vector表示向量

向量類Geom::Vector類與Geom::Point類一樣,分為2d和3d兩種,即 Geom:: Vector2d 和 Geom:: Vector3d ,前者用來表示xy平面上的向量。

center   = Geom::Point3d.new(0,0,0)normal   = Geom::Vector3d.new([1,1,1])normal_1 = Geom::Vector3d.new(normal)normal_2 = normal.cloneradius   = 100.mm
es=Sketchup.active_model.entities.add_circle(center,normal,radius)Sketchup.active_model.entities.add_face es

Vector類與Point類有著相似的聲明方式,同樣支持多種創建實例的方式。向量的坐標訪問與修改也與點坐標一致,同樣包括 .[]、 .[]=、 .x、 .x= 和 .set! 五種。與Point類不同的是,向量有一些特殊的概念:

向量是有方向的,因此Vector類提供反向變換方法:

vector = Geom::Vector3d.new([1,1,1])puts vector.reverse puts vector         vector.reverse!     puts vector         

向量是有長度的,因此Vector類實例能對長度進行訪問和修改。還可以判斷向量是否為單位向量以及對向量進行標準化。

vector = Geom::Vector3d.new([1,1,1])puts vector.length         vector.length=500.mm       puts vector                puts vector.unitvector?    vector.normalize!          puts vector.length.to_inch vector.unitvector?         puts vector                

③向量計算

向量與點存在一系列的運算和轉換方法,Vector類提供了 .+、 .-、 .==、 .cross 和 .dot 等方法,分別用於表示向量加法、減法、比較、叉乘和點乘;其中前三個方法通過運算符重載使得向量計算和解析幾何上的表示非常相似。

以下通過在三角形OPQ中的PQ上作中點M的例子,展示向量與點之間的加減運算方法:

point_O = Geom::Point3d.new(0,0,0)point_P = Geom::Point3d.new(3,0,0)point_Q = Geom::Point3d.new(0,4,0)vector_OP = point_P - point_Ovector_OQ = point_Q - point_O      vector_PQ = vector_OQ - vector_OPvector_PM = vector_PQ.clonevector_PM.length= 0.5 * vector_PQ.length    point_M1 = point_P + vector_PM  point_M2 = point_P.offset(vector_PM)    vector_OM = vector_OP + vector_PM  point_M3 = Geom::Point3d.new(vector_OM.to_a)puts point_M.to_a            puts point_M1 == point_M2    puts point_M1 == point_M3    puts point_M1 == point_P     

在前一個例子的基礎上,展示向量間關係的判斷:

  puts vector_OP == vector_OQ          puts vector_PM == vector_PQ          puts vector_PM == vector_PM.clone    puts vector_OP.perpendicular?(vector_OQ)    puts vector_OP.perpendicular?(vector_PQ)    puts vector_PM.parallel?(vector_PQ)            puts vector_PM.parallel?(vector_PQ.reverse)    puts vector_PM.samedirection?(vector_PQ)            puts vector_PM.samedirection?(vector_PQ.reverse)    puts vector_OP.angle_between(vector_OQ).radians    puts vector_OP.angle_between(vector_PQ).radians    puts vector_OP.angle_between(vector_PQ.reverse).radians  

除此之外,向量計算還有叉乘和點乘,分別常用於構造正交和投影:

vector_OA=Geom::Vector3d.new(3,1,-4)vector_OB=Geom::Vector3d.new(-2,4,1)vector_OC=vector_OA.cross(vector_OB)puts vector_OCputs vector_OC.perpendicular?(vector_OA)puts vector_OC.perpendicular?(vector_OB)
vector_OA = Geom::Vector3d.new(1,6,3)vector_OB = Geom::Vector3d.new(-2,4,6)dot_OA_OB = vector_OA.dot(vector_OB)vector_OM = vector_OA.clonevector_OM.length = dot_OA_OB / vector_OA.lengthvector_MB = vector_OB - vector_OMputs vector_MB.perpendicular?(vector_OA)

以上代碼中的坐標如下圖所示:

使用叉乘構造所在平面法線
使用點乘獲得向量的投影

(4)直線

①表示直線的數組

SketchUp中的直線使用點向式表示,即直線上一點加方向向量的形式。具體在ruby中是一個有兩個元素的數組。第0個元素為直線上任意一點,第1個元素為直線的方向向量。

例如以下兩段代碼均定義了直線line: x=y=z-1:

point_1 = Geom::Point3d.new(0,0,1)vector_1 = Geom::Vector3d.new(1,1,1)line_1 = [point_1,vector_1]
point_2 = Geom::Point3d.new(-1,-1,0)vector_2 = Geom::Vector3d.new(-2,-2,-2)line_2 = [point_2,vector_2]

這種直線的表達存在一個問題,就是同一個直線有無數中表達方式,因此在判斷兩個表達是否是同一個直線時就會比較麻煩,需要比較兩個直線方程的方向向量是否相同,然後再判斷他們是否存在至少一個共同點。由於直線沒有專門的類定義,沒有專門的判斷是否相等的方法,也就不能通過運算符重載來實現相等的判斷,所以需要在Geom模塊中追加一個函數判斷:

module Geom  def Geom.line_line_equal?(la,lb)    la[1].parallel?(lb[1]) and la[0].on_line?(lb)  endend

②與Sketchup::Edge的關係

直線在空間中是無限延伸的,而Sketchup::Edge是邊線圖元,是有限的線段。儘管如此,Edge類圖元可以通過 .line 方法返回其所在的直線。使用 .line 方法得到的直線,其點坐標為邊線的起始點(第一個端點),而方向向量是與兩個端點坐標之差同向的單位向量。因此可以理解成如下的方法定義:

module Sketchup  class Edge    def line      res = [self.start.position]      vec = self.end.position - self.start.position      res << vec.normalize     end      end  end

其中, edge. start 返回邊線的起點,相當於 edge. vertice[0]; edge. end 返回邊線的終點,相當於 edge. vertice[1] 。這部分內容會在涉及Sketchup:: Edge類的章節中詳解。

(5)平面

①表示平面的數組

SketchUp中的平面有兩種表示方法,一種是「點法式」,另一個是「原點距式」。

點法式。與直線的表示形式完全相同,表現為由1個點坐標和1個向量組成的數組。第0元素為平面上任意一點,第1元素為平面法向量。所以有著相同形式的直線與平面一定相互垂直,並且相交於第0元素表示的點。

原點距式。和直線的點向式一樣,平面的點法式也存在同一個平面有多個表達方式這情況,這對於比較平面是否相等十分不方便。不過平面的情況比直線好一些,不同於直線要五個參數才能確定唯一性,平面只需要四個參數;並且這四個參數都有幾何意義。也就是說,在法向量確定的情況下,原點和交點在法向量方向上的位置對於每一個不同的平面是唯一的。所以如下圖,可以用四個數表示三維空間中的所有平面,記為 [x, y, z, d],前三位 x, y, z 為平面的單位法向量PQ, d 則表示交點到原點沿PQ方向的有向距離。

所以平面plane: x+y+z-1=0的「原點距式」就是:

plane = [0.5773502691896258,         0.5773502691896258,         0.5773502691896258,        -0.5773502691896258]

對於平面 plane 來說, plane[0..2] 表示該平面的法向量, plane[3] 表示該平面的「原點距」。將數組的四個元素分別取相反數,即 plane. map{|i| -i} 或 plane. map(&:-@),也是相同的平面,只不過法向量相反。

Geom模塊中提供了一個名為 .fit_plane_to_points 的方法,能夠通過已知點坐標列表最大程度地創建擬合平面,可以通過這個方法,用三個點坐標創建平面。其返回結果也是「原點距式」。

points=[]points<<[0,0,0]points<<[0,1,0]points<<[1,0,0]points<<[1,1,0]Geom.fit_plane_to_points(points)
points=[]points<<[1,0,0]points<<[0,1,0]points<<[0,0,1]Geom.fit_plane_to_points(points)

②與Sketchup::Face的關係

平面和直線一樣,在空間中無限延伸,與之相關的Sketchup:: Face則是有具體形狀的面域。Face類圖元可以通過 .plane 方法返回其所在的平面,返回格式為「原點距式」。

法向量相反的兩個表達方式對於平面來說是相同的,但對於 Face 圖元 .plane 方法的返回結果而言,卻有一點區別。如下圖代碼所展示,這一點區別能夠反映該平面圖元的材質正面是朝向原點還是背向原點,相關內容在涉及 Sketchup:: Face 的章節中詳解。

face=Sketchup.active_model.entities.grep(Sketchup::Face)[0]puts "#{face.plane.map{|i|i.round(3)}}"face.reverse!puts "#{face.plane.map{|i|i.round(3)}}"

(6)立體幾何

現在已經完整地介紹了點線面在SU Ruby中的表達方式,其中連帶地也涉及了一些有關同類圖形之間的立體幾何計算。在最後這一部分會補充不同圖形之間關係判斷和有關的計算方法。

本部分中灰色字體部分不是 SU Ruby API 目前提供的方法,系額外追加的方法,這部分段落之後代碼為個人實現方案,可選擇性閱讀。

①交錯與投影

Geom模塊中提供了三個交錯方法 : .intersect_line_line、.intersect_line_plane 和 .intersect_plane_plane 。分別用於返回線線交點、線面交點和面面交線。三個方法均只返回唯一的結果,如果是兩線重合、兩線異面、線在面上、線面平行或者面面重合的情況,則返回nil。

Geom:: Point類實例提供 .project_to_line 和 .project_to_plane 兩個方法,用於將點投影到線或面上。

point_1 = Geom::Point3d.new(0,0,0)point_2 = Geom::Point3d.new(500.mm,300.mm,1000.mm)line_1 = [point_1,Geom::Vector3d.new(0,0,1)]line_2 = [point_1,Geom::Vector3d.new(0,1,1)]plane_1 = [point_2,Geom::Vector3d.new(0,0,1)]plane_2 = [point_1,Geom::Vector3d.new(1,1,1)]
intersect_point_1 = Geom.intersect_line_line(line_1,line_2)intersect_point_2 = Geom.intersect_line_plane(line_1,plane_2)intersect_line = Geom.intersect_plane_plane(plane_1,plane_2)
proj_pt1=point_2.project_to_line(line_1)proj_pt2=point_2.project_to_line(line_2)

②位置關係

Geom:: Point類中提供了兩個方法用於判斷點是否在直線或者平面上,分別是: .on_line? 和 .on_plane? 。

point_1 = Geom::Point3d.new(0,0,0)point_2 = Geom::Point3d.new(0,0,1000.mm)line_1 = [point_1,Geom::Vector3d.new(0,0,1)]line_2 = [point_1,Geom::Vector3d.new(0,1,1)]plane_1 = [point_2,Geom::Vector3d.new(0,0,1)]plane_2 = [point_1,Geom::Vector3d.new(0,0,1)]puts point_1.on_line?(line_1)puts point_2.on_line?(line_2)puts point_1.on_plane?(plane_1)puts point_1.on_plane?(plane_2)

至於線線關係、線面關係和面面關係則可以在向量關係的基礎上進行補充。例如,判斷線與線、線與面和面與面之間是否垂直或平行,可以如此實現:

module Geom  def Geom.line_line_perpendicular?(la,lb)    return la[1].perpendicular?(lb[1])  end  def Geom.line_line_parallel?(la,lb)    return la[1].parallel?(lb[1])  end  def Geom.line_plane_perpendicular?(l,p)    case p.count      when 2 then       return l[1].parallel?(p[1])      when 4 then       return l[1].parallel?(p[0..2])    end  end  def Geom.line_plane_parallel?(l,p)    case p.count      when 2 then       return l[1].perpendicular?(p[1])      when 4 then       return l[1].perpendicular?(p[0..2])    end  end  def Geom.plane_plane_perpendicular?(p1,p2)    case p1.count      when 2 then n1 = p1[1]      when 4 then n1 = p1[0..2]    end    case p2.count      when 2 then n2 = p2[1]      when 4 then n2 = p2[0..2]    end    return Geom::Vector3d.new(n1).perpendicular?(n2)  end  def Geom.plane_plane_parallel?(p1,p2)    case p1.count      when 2 then n1 = p1[1]      when 4 then n1 = p1[0..2]    end    case p2.count      when 2 then n2 = p2[1]      when 4 then n2 = p2[0..2]    end    return Geom::Vector3d.new(n1).parallel?(n2)  endend

在這幾個方法的基礎上,結合上文三個計算交點交線的方法,就可以綜合判斷點線面之間的位置關係了。

③距離

Geom:: Point 類提供了點-點、點-線和點-面距離的計算方法。這些方法也追加到 Array 類中,因此直接使用數組表示點坐標也可以使用這些方法。

p1 = Geom::Point3d.new(0,0,0)p2 = Geom::Point3d.new(3000.mm,4000.mm,0)line = [p2,Geom::Vector3d.new(-1,1,-1)]plane1 = [p2,Geom::Vector3d.new(-1,1,-1)]plane2 = [0,0,1,1000.mm]
puts Sketchup.format_length p1.distance(p2)puts Sketchup.format_length p1.distance_to_line(line)puts Sketchup.format_length p1.distance_to_plane(plane1)puts Sketchup.format_length p1.distance_to_plane(plane2)

對於線-面距離,Geom 模塊中有一個 .closest_points 方法,可以獲取兩條直線中彼此距離最近的一對點坐標。如果兩條直線為異面直線,則返回唯一的最近距離點對。如果兩條直線相交或重合,則返回的兩點相等且為交點(相交)或第一條直線的定位點(重合)。如果兩條線平行而不重合,點對為第一條直線的定位點和另一直線上對應的最近點。

由於沒有直線與直線最近距離的方法,可以在 .closest_points 方法的基礎上在 Geom 模塊中追加一個自定義的方法:

module Geom  def Geom.distance_line_line(la,lb)    points = closest_points(la,lb)    return(points[0].distance(points[1]))  endend

對於面-面距離就只針對平行面了,因而適用範圍更小,在此處僅列出一小部分實現方法僅供參考:

module Geom  def Geom.distance_plane_plane(pa,pb)    if pa.count==4 and pb.count==4 then      unless Geom::Vector3d.new(pa[0..2]).parallel?(pb[0..2]) then        return 0      else        if Geom::Vector3d.new(pa[0..2]).samedirection?(pb[0..2]) then          return (pa[3]-pb[3]).abs        else          return (pa[3]+pb[3]).abs        end      end     else          end  endend

最後還是按照慣例放一些補充內容:

①文中例子的點或者向量的定義都採用的「point_」/「vector_」+大寫字母的規則來命名。這一方面是為了區分點和向量,更重要的是,ruby中大寫字母開頭的標識符為模塊、類或者常量名。例子中雖然沒有去編輯這幾個點和向量的坐標,但也視之為變量,因此還是應該使用小寫字母或者下劃線開頭。

②一個關於方法定義名稱的疑問。為什麼判斷向量是否為單位向量的方法 .unitvector? 不用構詞上更具有聯繫的 .normalized? 的表述,或至少將其列為別名呢?

③以下提供一個簡易的點法式轉原點距式的函數:

def plane2_to_plane4(p2)  vec=p2[1]  dist=p2[0].distance_to_plane(p2)  axis=[Geom::Point3d.new,vec]  intersect=Geom.intersect_line_plane(axis,p2)  vec_ori=intersect.vector_to([0,0,0])  res=vec.normalize.to_a  case vec_ori.dot(vec)<=>0    when 1 then res << vec_ori.length    when -1 then res << -vec_ori.length    when 0 then res << 0  end  return resend

這是一個圖省事的做法,用到了Geom中的種種構造。但實際上這是一個純粹的數學問題,可以僅使用數組坐標的計算就能很好地解決這個問題。

這是Apiglio SU Ruby教程的第三篇,編號為「SU-R06」,本系列的其他文章可以在公眾號後臺輸入「SU-R」+兩位數編號查看,或者直接點擊菜單中的「SU Ruby」選項獲得全部有關SketchUp文章的目錄。

相關焦點

  • 向量方法解決立體幾何問題
    立體幾何是高考數學每年必考的大題,牽涉的問題也有很多。比如:線面平行、線面垂直、面面平行、面面垂直、異面直線所成的角度、直線與平面所成的角度、平面與平面所成的角度等。線面平行:定義:一條直線與一個平面沒有公共點,則稱直線與平面平行;線面平行的判定定理1:平面外一條直線與平面平行,則稱此直線與平面平行;線面平行的判定定理2:平面外一條直線與該平面的垂線垂直
  • 空間向量在立體幾何中的應用(理)(下)
    空間線線、線面、面面平行關係問題是高考考查的重點內容,考查的形式靈活多樣,常與探索性問題、垂直問題、空間角問題結合,可以是小題,也可以是解答題.題目的難度一般不大,是高考中的得分點之一.       【評述】對於容易建立坐標系的線面平行問題的向量解法,求出平面的法向量,然後證明法向量與直線的方向向量垂直即可.對於探究性問題,通常先假設結論成立,設出相關點的坐標,利用相關知識,列出關於坐標的方程,若方程有解,則存在,否則不存在.設點的坐標時,利用點在某線段上,設出點分線段所成的比,用比表示坐標可以減少未知量
  • 【SU Ruby教程】了解基礎結構前:數據類型
    上一部分教程目的在於通過一個簡短的例子大概地窺探SketchUp Ruby的用法,因此很多涉及到的細枝末節被一筆帶過甚至隱藏。但從這一部分開始,教程將儘可能地展開內容。這一部分的核心是介紹SketchUp的基本結構,為了更好的理解這些結構,需要一些例子來展示它們的功能。而理解這些例子需要一些Ruby的語法知識,因此在展開介紹基本結構之前需要對Ruby的數據類型和基礎語法有所了解。
  • 幾何向量並舉·計算證明兼顧
    其實,幾何向量並舉,計算證明兼顧,才是空間幾何的教學數學素養,才是培訓學生數學文化的主陣地。在平時的空間幾何教學中,應該引起足夠的重視,不可使用單一的方法冒險解題。下面幾個典型例子,就是幾何向量並舉,計算證明兼顧的最好例證,希望同學們用心感悟體會靈感。
  • 2020高考全國1卷理科數學第18題解析,立體幾何,向量的坐標運算
    本題為立體幾何大題,每年考一題,為中等難度題型。思路,(1)求線面垂直,根據線面垂直的判定定理,要找到平面內的兩條相交直線與線垂直。從結果看,既然PA垂直於平面ABC,那麼PA應垂直於PB,PC,故只要證明PA垂直於PB,PC就行了。
  • 12分高考答題必刷題型,「空間向量分析點到線的距離問題」
    立體幾何的計算和證明常常涉及到二大問題:一是位置關係,它主要包括線線垂直,線面垂直,線線平行,線面平行;二是度量問題,它主要包括點到線、點到面的距離,線線、線面所成角,面面所成角等。這裡比較多的主要是用向量證明線線、線面垂直及計算線線角,而如何用向量證明線面平行,計算點到平面的距離、線面角及面面角的例題不多,起到一個拋磚引玉的作用。
  • 仿射變換(1)
    仿射變換,顧名思義,是一種幾何變換,適用範圍很廣尤其是對於圓錐曲線的問題,很牛13,沒有像其他幾何變換變化的單一.其包含平移旋轉伸縮等初等幾何的變換一、定義:在幾何上定義的兩個向量空間之間的一個仿射變換或映射,是由一個非奇異的線性變換加上一個平移變換組成,在有限維的情況下,每個仿射變換可由一個矩陣A和一個向量B組成。
  • 高中數學解題技巧:立體幾何中幾類經典問題的向量解法
    空間向量的引入為求立體幾何的空間角和距離問題、證線面平行與垂直以及解決立體幾何的探索性試題提供了簡便、快速的解法。向量解法也使空間立體幾何的題型難度係數減小,不在那麼抽象、立體,那麼解決立體幾何利用向量法都有哪些典型例題和方法呢?下面就給大家整理了高中數學解題技巧:立體幾何中幾類經典問題的向量解法,攻破解答題中立體幾何等問題。
  • 奇異值分解(SVD) --- 線性變換幾何意義
    線性變換的幾何意義(The geometry of linear transformations)讓我們來看一些簡單的線性變換例子,以 2 X 2 的線性變換矩陣為例,首先來看一個較為特殊的,對角矩陣:從幾何上講,M 是將二維平面上的點(x,y
  • Numpy和OpenCV中的圖像幾何變換
    x』 = Ax其中A是在齊次坐標系中的2x3矩陣或3x3,x是在齊次坐標系中的(x,y)或(x,y,1)形式的向量。這個公式表示A將任意向量x,映射到另一個向量x』。一般來說,仿射變換有6個自由度。根據參數的值,它將在矩陣乘法後扭曲任何圖像。
  • 高中數學:立體幾何、空間向量公式+知識點+推論大集合!看這一篇足夠了!
    空間向量與立體幾何複習總結來啦,主要分以下幾部分:基礎概念與知識點記憶;常見技巧加推論公式;立體幾何輔助線添加技巧
  • 高考數學平面向量和立體幾何學什麼?考什麼?
    ,1-12課是傳統方法,考查空間想像能力,13課以後是空間向量及外接球、截面等壓軸問題。第04課立體幾何平面與平面的位置關係二面角傳統法.第05課立體幾何傳統法相關證明公式線線線面面面平行垂直三垂線定理求高的方法.第06課斜二測畫法空間幾何體弧長面積體積公式.第07題2013年天津高考數學立體幾何解答題線面平行線面垂直面面垂直線面角.第08題2014年天津高考數學立體幾何解答題線面平行線面垂直面面垂直二面角線面角.
  • 點到面距離分析《空間向量分析空間位置問題》
    平面法向量的具體步驟:(待定係數法)1、建立恰當的直角坐標系2、設平面法向量n=(x,y,z)3、在平面內找出兩個不共線的向量,記為a=(a1,a2, a3) b=(b1,b2,b3法向量方法是高考數學可以採用的方法之一,它的優點在於思路簡單,容易操作。只要能夠建立出直角坐標系,都可以寫出最後答案。缺點在於同一般立體幾何方法相比,其計算量巨大,特別是在計算二面角的時候。點到面的距離
  • 空間向量在立體幾何中的運用,每一種題型都能解!(第105期)
    空間向量在立體幾何中的運用到底有多廣?每一種類型題都能解!!!1.共線證明平面向量共線定理:對於非零向量a和向量b,如果存在唯一實數λ,使得b=λa,則向量a和向量b共線。1.線線垂直已知直線p,q,且這兩條直線的方向向量分別為a,b,要證明p⊥q,即證明a∙b=0即可。2.線面垂直已知直線p,平面ɑ,且直線p的方向向量為a,平面ɑ的法向量為n,要證明p⊥ɑ,即證明a=λn即可。
  • 立體幾何重難點突破(二)
    平行關係的轉化:平行關係包括線線平行、線面平行和面面平行.三種平行關係既是相互依存,又可以依據性質定理和判定定理在一定條件下相互轉化.線線平行是線面平行和面面平行的基礎,常常通過平行的傳遞性,以及中位線、平行四邊形、相似形等判斷線線平行,進而證明線面平行和面面平行.
  • 小波變換教程(三):多尺度分析和連續小波變換
    本文講解ROBI POLIKAR編寫的小波變換教程《THE WAVELET TUTORIAL》的第三部分:多尺度分析和連續小波變換。
  • 高考數學「法向量」專題
    為了得到確定法向量,可採用固定z=1(也可以固定x=1或y=1)或者模等於1的方法(單位法向量),但是這步並不是必須的。因為確定法向量和不確定法向量的作用是一樣的。法向量的主要應用如下:1、求斜線與平面所成的角(一般只求出正弦值即可):求出平面法向量和斜線的一邊,然後聯立方程組,可以得到角度的餘弦值,根據公式Sinα=|Cosα|。利用這個原理也可以證明線面平行;
  • Ruby 語言教程
    學習本教程,您將對 Ruby 有一個全面的了解。現在開始學習 Ruby!Ruby 在線工具誰適合閱讀本教程?本教程有助於初學者理解 Ruby 語言基礎知識及基本概念。閱讀本教程前,您需要了解的知識:在您開始練習本教程中提供的各種實例之前,最好已經對電腦程式和電腦程式設計語言有一個基本的認識,這將有助於您對本教程的學習。編譯/執行 Ruby 程序對於大多數程式語言,第一個入門實例便是 "Hello World!",下面的實例使用 Ruby 輸出 "Hello World!":實例#!
  • 空間向量在立體幾何中的應用
    立體幾何的夾角與距離問題求解方法多變,而利用空間向量來求解,不但方法統一,而且過程簡單,本文介紹空間向量在這兩方面應用。二.應用1.線與面的夾角正弦值:方法:直線的方向向量與平面的法向量夾角的餘弦的絕對值3.二面角的平面角餘弦值方法:兩平面的「順次」法向量夾角的餘弦值,兩平面的「對頂」法向量夾角的餘弦值的相反數
  • 向量代數與空間解析幾何終結篇:結束代數與幾何
    向量代數與空間解析幾何算是比較費腦的一章,因為圖形要動腦來想。所以對於空間想像力弱的同學,學習這一章就很痛苦。但是這也沒有辦法,這也是為了後來的多元積分做鋪墊,扛過去就好了。最後來對這一章的內容總結一下:本章知識點總結:1.向量代數(1)在利用空間解析幾何知識去解決問題時,若已知條件中沒有給定坐標系,應根據所求問題選取合適的坐標系,使解題過程更為簡潔。