﻿<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://wiki.blender.jp/index.php?action=history&amp;feed=atom&amp;title=%E5%88%A9%E7%94%A8%E8%80%85%3ATestscreenings%2FIvy_port%2FOriginalAlgo</id>
	<title>利用者:Testscreenings/Ivy port/OriginalAlgo - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.blender.jp/index.php?action=history&amp;feed=atom&amp;title=%E5%88%A9%E7%94%A8%E8%80%85%3ATestscreenings%2FIvy_port%2FOriginalAlgo"/>
	<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=%E5%88%A9%E7%94%A8%E8%80%85:Testscreenings/Ivy_port/OriginalAlgo&amp;action=history"/>
	<updated>2026-05-03T16:23:38Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>https://wiki.blender.jp/index.php?title=%E5%88%A9%E7%94%A8%E8%80%85:Testscreenings/Ivy_port/OriginalAlgo&amp;diff=98717&amp;oldid=prev</id>
		<title>Yamyam: 1版 をインポートしました</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=%E5%88%A9%E7%94%A8%E8%80%85:Testscreenings/Ivy_port/OriginalAlgo&amp;diff=98717&amp;oldid=prev"/>
		<updated>2018-06-28T19:38:11Z</updated>

		<summary type="html">&lt;p&gt;1版 をインポートしました&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ja&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← 古い版&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;2018年6月28日 (木) 19:38時点における版&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;ja&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(相違点なし)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Yamyam</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.blender.jp/index.php?title=%E5%88%A9%E7%94%A8%E8%80%85:Testscreenings/Ivy_port/OriginalAlgo&amp;diff=98716&amp;oldid=prev</id>
		<title>wiki&gt;Mindrones: moved User:Testscreenings/Ivy port/originalAlgo to User:Testscreenings/Ivy port/OriginalAlgo</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=%E5%88%A9%E7%94%A8%E8%80%85:Testscreenings/Ivy_port/OriginalAlgo&amp;diff=98716&amp;oldid=prev"/>
		<updated>2010-07-31T14:35:28Z</updated>

		<summary type="html">&lt;p&gt;moved &lt;a href=&quot;/%E5%88%A9%E7%94%A8%E8%80%85:Testscreenings/Ivy_port/originalAlgo&quot; class=&quot;mw-redirect&quot; title=&quot;利用者:Testscreenings/Ivy port/originalAlgo&quot;&gt;User:Testscreenings/Ivy port/originalAlgo&lt;/a&gt; to &lt;a href=&quot;/%E5%88%A9%E7%94%A8%E8%80%85:Testscreenings/Ivy_port/OriginalAlgo&quot; title=&quot;利用者:Testscreenings/Ivy port/OriginalAlgo&quot;&gt;User:Testscreenings/Ivy port/OriginalAlgo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;back [[User:Testscreenings/Ivy port|Ivy port]]&lt;br /&gt;
= original algorithm =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== defenitions and so forth ==&lt;br /&gt;
[[image:Ivy_Elements.jpg |right|thumb|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- Ivy&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- IvyNode&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- IvyRoot&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Data Structure ==&lt;br /&gt;
&lt;br /&gt;
All the data of the Ivy is stored in three Node-classes. Here are short descriptions as well as a first translation into Python.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- IvyNode&lt;br /&gt;
    This is the most basic Nodetype.&lt;br /&gt;
    It stores the position and other attributes of one point on one root of the Ivy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
class IvyNode():&lt;br /&gt;
    def __init__(self, climbing, length, floatingLength):&lt;br /&gt;
        self.climbing = False&lt;br /&gt;
        self.length = 0.0&lt;br /&gt;
        self.floatingLength = 0.0&lt;br /&gt;
    &lt;br /&gt;
    # node position&lt;br /&gt;
    position = (0,0,0)&lt;br /&gt;
    &lt;br /&gt;
    # primary grow direction, a weighted sum of the previous directions&lt;br /&gt;
    primaryVector = (0,0,0)&lt;br /&gt;
    &lt;br /&gt;
    #adhesion vector as a result from other scene objects&lt;br /&gt;
    adhesionVector = (0,0,0)&lt;br /&gt;
    &lt;br /&gt;
    # a smoothed adhesion vector computed and used during the birth phase,&lt;br /&gt;
	#  since the ivy leaves are align by the adhesion vector, this smoothed vector&lt;br /&gt;
	#  allows for smooth transitions of leaf alignment&lt;br /&gt;
    smootAdhesionVector = (0,0,0)&lt;br /&gt;
    &lt;br /&gt;
    # length of the associated ivy branch at this node&lt;br /&gt;
    length = 0.0&lt;br /&gt;
    &lt;br /&gt;
    # length at the last node that was climbing&lt;br /&gt;
    floatingLength = 0.0&lt;br /&gt;
    &lt;br /&gt;
    # climbing state&lt;br /&gt;
    climbing = False&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- IvyRoot&lt;br /&gt;
    This Node is basically a container for one Root of the Ivy&lt;br /&gt;
    and stores all the containing IvyNodes,&lt;br /&gt;
    as well as its living state&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
class IvyRoot():&lt;br /&gt;
    # List with containing IvyNodes&lt;br /&gt;
    ivyNodes = []&lt;br /&gt;
    &lt;br /&gt;
    # living state of this Root&lt;br /&gt;
    alive = True&lt;br /&gt;
    &lt;br /&gt;
    # number of parents, represents the level in the root hierarchy&lt;br /&gt;
    parents = 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- Ivy&lt;br /&gt;
    Ivy is the base Node.&lt;br /&gt;
    It stores the IvyRootNodes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
class Ivy():&lt;br /&gt;
    # list of containing Roots&lt;br /&gt;
    ivyRoots = []&lt;br /&gt;
    &lt;br /&gt;
    # the ivy size factor, influences the grow behaviour [0..0,1]&lt;br /&gt;
    ivySize = 1.0&lt;br /&gt;
    &lt;br /&gt;
    # leaf size factor [0..0,1]&lt;br /&gt;
    leafSize = 1.0&lt;br /&gt;
    &lt;br /&gt;
    # branch size factor [0..0,1]&lt;br /&gt;
    branchSize = 1.0&lt;br /&gt;
    &lt;br /&gt;
    # maximum length of an ivy branch segment that is freely floating [0..1]&lt;br /&gt;
    maxFloatingLength = 1.0&lt;br /&gt;
    &lt;br /&gt;
    # maximum distance for adhesion of scene object [0..1]&lt;br /&gt;
    maxAdhesionDistance = 1&lt;br /&gt;
    &lt;br /&gt;
    # weight for the primary grow vector [0..1]&lt;br /&gt;
    primaryWeight = 0.5&lt;br /&gt;
    &lt;br /&gt;
    # weight for the random influence vector [0..1]&lt;br /&gt;
    randomWeight = 0.5&lt;br /&gt;
    &lt;br /&gt;
    # weight for the gravity vector [0..1]&lt;br /&gt;
    gravityWeight = 0.5&lt;br /&gt;
    &lt;br /&gt;
    # weight for the adhesion vector [0..1]&lt;br /&gt;
    adhesionWeight = 0.5&lt;br /&gt;
    &lt;br /&gt;
    # the probability of producing a new ivy root per iteration [0..1]&lt;br /&gt;
    branchingProbability = 0.5&lt;br /&gt;
    &lt;br /&gt;
    # the probability of creating a new ivy leaf [0..1]&lt;br /&gt;
    leafingProbability = 0.5&lt;br /&gt;
    &lt;br /&gt;
    # in the C++ version the functions for seeding, growing, birthing, etc&lt;br /&gt;
    # are also placed inside this class.&lt;br /&gt;
    # I show them here, but it is probably better to place them somewhere else eventually&lt;br /&gt;
    # Or maybe I don't really understand how the C++ class is working and how these really fit in here.&lt;br /&gt;
    # I am deffing them here, but i really am not sure if that is what the C++ Code does.&lt;br /&gt;
    &lt;br /&gt;
    # resetting&lt;br /&gt;
    def resetSettings():&lt;br /&gt;
        pass&lt;br /&gt;
        &lt;br /&gt;
    # initialize a new ivy root&lt;br /&gt;
    def seed():&lt;br /&gt;
        pass&lt;br /&gt;
        &lt;br /&gt;
    # one single grow iteration&lt;br /&gt;
    def grow():&lt;br /&gt;
        pass&lt;br /&gt;
        &lt;br /&gt;
    # compute the adhesion of scene objects at a point pos&lt;br /&gt;
    def computeAdhesion():&lt;br /&gt;
        pass&lt;br /&gt;
        &lt;br /&gt;
    # computes the collision detection for an ivy segment&lt;br /&gt;
    # oldPos-&amp;gt;newPos, newPos will be modified if necessary&lt;br /&gt;
    def computeAdhesion():&lt;br /&gt;
        pass&lt;br /&gt;
        &lt;br /&gt;
    # creates the ivy triangle mesh&lt;br /&gt;
    def birth():&lt;br /&gt;
        pass&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== growing algorithm ==&lt;br /&gt;
&lt;br /&gt;
This is a short description of the original algorithm of the ivy generator.&lt;br /&gt;
&lt;br /&gt;
The main part of the algorithm lies in the grow function.&lt;br /&gt;
From the initial seed point new Ivynodes are spawned and placed.&lt;br /&gt;
&lt;br /&gt;
the position of the new Nodes is determined in three steps.&lt;br /&gt;
&lt;br /&gt;
- the first step is to generate a new position depending on several variables.&lt;br /&gt;
    - (A)a primary Vector&lt;br /&gt;
    - (B)a random Vector&lt;br /&gt;
    - (C)an adhesion vector&lt;br /&gt;
    &lt;br /&gt;
        -these variables are normalized in respect to each other and individually weighed&lt;br /&gt;
        according to user input&lt;br /&gt;
        - growVector = (A * Aweight) + (B * Bweight) + (C * Cweight)&lt;br /&gt;
    &lt;br /&gt;
    - (D)a gravity Vector&lt;br /&gt;
        - gravityVector = ((0,0,-1)) * localIvySize * gravityWeight&lt;br /&gt;
        - gravityVector *= pow((previousNode.floatingLength / local_maxFloatLength), 0.7f)&lt;br /&gt;
        - the gravityVector acts then on the new Node with userweighting&lt;br /&gt;
        and depending on the floatinglength of the current ivysegment&lt;br /&gt;
        &lt;br /&gt;
    -the above result then in the new position of the next node:&lt;br /&gt;
        new_pos = previousNode.position + growVector + gravityVector&lt;br /&gt;
&lt;br /&gt;
- now the new position is checked against the colliding Mesh&lt;br /&gt;
    &lt;br /&gt;
    - test if the root collides&lt;br /&gt;
        - test if the root should die&lt;br /&gt;
        - change the new_pos so it doesn't intersect with the mesh anymore&lt;br /&gt;
        - set it's climbingState according to collisionState&lt;br /&gt;
        &lt;br /&gt;
    - if the new_pos was changed: update the growVector according to the new_pos&lt;br /&gt;
        - growVector = newPos - previousNode.position - gravityVector&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- in the third step a new IvyNode is generated and its settings are set&lt;br /&gt;
&lt;br /&gt;
    - newNode.position = new_pos&lt;br /&gt;
    - newNode.primaryVector = ( 0.5 * previousNode.primaryVector +&lt;br /&gt;
                                0.5 * growVector.normalize() )&lt;br /&gt;
    - newNode.adhesionVector = adhesionVector&lt;br /&gt;
    - newNode.length = previousNode.length +&lt;br /&gt;
                       (new_pos - previousNode.position).length()&lt;br /&gt;
    - newNode.floatingLength = length of conected floating IvyNodes&lt;br /&gt;
    - newNode.climbing = climbing (from the collision detection)&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
- the last step here is now to put this newNode in the list of IvyNodes of the corresponding IvyRootNode&lt;br /&gt;
&lt;br /&gt;
== helper functions / algorithms ==&lt;br /&gt;
&lt;br /&gt;
=== compute adhesion ===&lt;br /&gt;
this are my preliminary notes on adhesion:&lt;br /&gt;
&lt;br /&gt;
    ok, first: what does he exactly want to do here?&lt;br /&gt;
    the function returns the adhesionVector. so my best guess would be that&lt;br /&gt;
    this is the force and direction towards the surface.&lt;br /&gt;
    combined with the adhesionWeight this then defines how strongly the Ivy wants to stick to the surface.&lt;br /&gt;
    &lt;br /&gt;
    so how does he do that?:&lt;br /&gt;
    -check for nearest face of the mesh&lt;br /&gt;
    -now this again i don't quiet get:&lt;br /&gt;
        -scalar product projection of old_pos to the center of the fface?:&lt;br /&gt;
            float nq = Vector3d::dotProduct(t-&amp;gt;norm, pos - t-&amp;gt;v0-&amp;gt;pos)&lt;br /&gt;
    -check if the projection nq(?) is on the outer side of the face&lt;br /&gt;
        if not: continue&lt;br /&gt;
    &lt;br /&gt;
   -...&lt;br /&gt;
   &lt;br /&gt;
   -compute barycentric coordinates of p0  &amp;lt;&amp;lt;&amp;lt;?&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
   -at last compute normalized direction of adhesion&lt;br /&gt;
   -and multiply it with the distance to the surface divided by the scale_factor of the local_maxAdhesion&lt;br /&gt;
   -return the adhesionVector&lt;br /&gt;
   &lt;br /&gt;
   ####### obviously the middle i haven't figured out yet #########&lt;br /&gt;
&lt;br /&gt;
=== compute collision ===&lt;br /&gt;
this are my notes so far on the collision detection.&lt;br /&gt;
they are neither complete nor are they correct to the point of certainty.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    basic steps:&lt;br /&gt;
        thought: maybe implement and octree for the faces&lt;br /&gt;
                 to efficiently discard the one too far away?&lt;br /&gt;
    &lt;br /&gt;
        ### http://www.flipcode.com/archives/Basic_Collision_Detection.shtml&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
    - test if old_pos --&amp;gt; new_pos is passing through the hyperplane of the polygon&lt;br /&gt;
                                                not sure about this one (below)&lt;br /&gt;
        direction = new_pos.dot(face.normal) + (old_pos - face.center).length&lt;br /&gt;
        if direction &amp;gt; 0:&lt;br /&gt;
            new_pos_placement = 'plane_front'&lt;br /&gt;
        else:&lt;br /&gt;
            new_pos_placement = 'plane_back'&lt;br /&gt;
        return new_pos_placement&lt;br /&gt;
        &lt;br /&gt;
    - test if the path old_pos --&amp;gt; new_pos passes through the boundaries of the polygon&lt;br /&gt;
        --&amp;gt; find the intersectionpoint():&lt;br /&gt;
        ray_vector = (old_pos - new_pos).normalize()&lt;br /&gt;
        t = -(face.normal.dot(old_pos) + (old_pos - face.center).length) /&lt;br /&gt;
            face.normal.dot(ray_vector)&lt;br /&gt;
            ### check if face.normal.dot(ray_vector) is zero: if yes: do something ###&lt;br /&gt;
        intersectPoint = old_pos + ray_vector * t&lt;br /&gt;
        return intersectPoint&lt;br /&gt;
        &lt;br /&gt;
        --&amp;gt; test if intersectPoint is on the polygon():&lt;br /&gt;
            ### An Efficient Ray-Polygon Intersection&lt;br /&gt;
            ### by Didier Badouel from Graphics Gems I :&lt;br /&gt;
            ### http://graphics.stanford.edu/courses/cs348b-98/gg/intersect.html&lt;br /&gt;
    &lt;br /&gt;
    ###################################################&lt;br /&gt;
    if you have read all of the above: nice&lt;br /&gt;
    actuall i remembered we have this whole rayintersection test&lt;br /&gt;
    as a function of objects. much simpler.&lt;br /&gt;
    obj.ray_cast(old_pos, new_pos)&lt;br /&gt;
    returns [hitlocation, hitnormal at face, faceindex]&lt;br /&gt;
    &lt;br /&gt;
    ####################################################&lt;br /&gt;
    now: what do i think does the original function do:&lt;br /&gt;
    it tests if the new_pos is intersecting some part of the mesh (doh)&lt;br /&gt;
    if yes it adjusts the new_pos as to move it out of the mesh again&lt;br /&gt;
    it also sets the climbingState of the RootNode:&lt;br /&gt;
        if it intersects the climbing is set to true&lt;br /&gt;
        if not climbing is set to false&lt;br /&gt;
        not sure about the following:&lt;br /&gt;
            the climbing is important for the adhesion i think&lt;br /&gt;
            the longer the chain of non climbing RootNodes&lt;br /&gt;
                --&amp;gt; something should be done i think (?)&lt;br /&gt;
                - suggestions? (maybe look elsewhere better :) )&lt;/div&gt;</summary>
		<author><name>wiki&gt;Mindrones</name></author>
		
	</entry>
</feed>