• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[WIP][Snippet]Bezier

Status
Not open for further replies.
So I saw this:
Curve ( Projectile ) system using the cubic Bézier curve, a wrapper for quadratic curves as they are more likely useful in map making
and the option to add n cubic curves with proper calculated continuity. It should not be restricted to missiles
as you could also draw special effects / images on the curve, but you could build a missile system based on it.

That would be awesome.

and realized that I misunderstood it. The idea was to have a Bezier struct where it has N points, so it has N-degrees.

It was a good idea, so I made this WIP:

JASS:
library Bezier/*v1.0 by Almia
*************************************************************************************
*
*   For creating n-degree Beziers
*   Beziers are created by making a linked list, where each node is a point. 
*
*************************************************************************************
*
*   API
*       struct Point
*           readonly static thistype sentinel
*   
*           static method create takes real tx, real ty, real tz returns thistype
*
*           method operator next= takes thistype pt returns nothing
*           method operator prev= takes thistype pt returns nothing
*           method operator next takes nothing returns thistype
*           method operator prev takes nothing returns thistype
*
*           method destroy takes nothing returns nothing
*
*       struct Bezier
*           readonly static thistype sentinel
*
*           static method create takes Point p returns thistype
*               - starting point for bezier
*
*           method insert takes Point p, Point pr, Point nx returns nothing
*           method remove takes Point p returns nothing
*
*           method pushHead takes Point p returns nothing
*           method pushTail takes Point p returns nothing
*
*           method popHead takes nothing returns Point
*           method popTail takes nothing returns Point
*
*           method get takes real t returns Point
*               - get's the current position at time t
*
*           method destroy takes nothing returns nothing
*
*************************************************************************************/

    private function Linear takes real a, real b, real t returns real
        return a + (b-a)*t
    endfunction
    
    private module Init
        private static method onInit takes nothing returns nothing
            call init()
        endmethod
    endmodule
    
    struct Point
        readonly static thistype sentinel
        real x
        real y
        real z
        
        private thistype n
        private thistype p
        
        static method create takes real tx, real ty, real tz returns thistype
            local thistype this = allocate()
            set x = tx
            set y = ty
            set z = tz
            set n = sentinel
            set p = sentinel
            return this
        endmethod
        
        method operator next= takes thistype pt returns nothing
            set n = pt
            set pt.p = this
        endmethod
        
        method operator next takes nothing returns thistype
            return n
        endmethod
        
        method operator prev= takes thistype pt returns nothing
            set p = pt
            set pt.n = this
        endmethod
        
        method operator prev takes nothing returns thistype
            return p
        endmethod
        
        method destroy takes nothing returns nothing
            set n = sentinel
            set p = sentinel
            call deallocate()
        endmethod
        
        private static method init takes nothing returns nothing
            set sentinel = create(0, 0, 0)
        endmethod
        
        implement Init
    endstruct
    
    struct Bezier
        readonly static Point sentinel
        
        private Point head
        private Point tail
        private integer size
        
        method destroy takes nothing returns nothing
            set head = sentinel
            set tail = sentinel
            set size = 0
            
            call deallocate()
        endmethod
        
        static method create takes Point p returns thistype
            local thistype this = allocate()
            set head = p
            set tail = p
            set size = 1
            return this
        endmethod
        
        method insert takes Point p, Point pr, Point nx returns nothing
            if pr == sentinel then
                set tail = p
            endif
            if nx == sentinel then
                set head = p
            endif
            set p.next = nx
            set p.prev = pr
            
            set size = size + 1
        endmethod
        
        method remove takes Point p returns nothing
            set p.prev.next = p.next
            set p.next.prev = p.prev
            if p == head then
                set head = p.prev
            elseif p == tail then
                set tail = p.next
            endif
            
            set size = size - 1
        endmethod
        
        method pushHead takes Point p returns nothing
            call insert(p, head, sentinel)
        endmethod
        
        method popHead takes nothing returns Point
            local Point t = head
            call remove(t)
            return t
        endmethod
        
        method pushTail takes Point p returns nothing
            call insert(p, sentinel, tail)
        endmethod
        
        method popTail takes nothing returns Point
            local Point t = tail
            call remove(t)
            return t
        endmethod
        
        method get takes real t returns Point
            local Bezier b = this
            local Bezier r
            local Point p
            local Point nextp
            loop
                exitwhen b.size <= 1
                set r = allocate()
                set p = b.tail
                loop
                    exitwhen p == b.head
                    set nextp = p.next
                    call r.pushHead(Point.create(Linear(p.x, nextp.x, t), Linear(p.y, nextp.y, t), Linear(p.z, nextp.z, t)))
                    set p = nextp
                endloop
                if b != this then
                    call b.destroy()
                endif
                set b = r
            endloop
            set p = b.head
            if b != this then
                call b.destroy()
            endif
            return p
        endmethod
        
        private static method init takes nothing returns nothing
            set sentinel = Point.sentinel
        endmethod
        
        implement Init
    endstruct
endlibrary


Planned improvements:
- Will use a much better LinkedList struct instead of using the Points as nodes.
- A much better, faster "get" method for N-degree curves, using this formula :
 

Attachments

  • yes.png
    yes.png
    122.5 KB · Views: 255
Status
Not open for further replies.
Top